Skip to content
105 changes: 105 additions & 0 deletions examples/servers/typescript/everything-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {
} from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import {
ElicitResultSchema,
McpError,
ErrorCode,
ListToolsRequestSchema,
type ListToolsResult,
type Tool
Expand Down Expand Up @@ -465,6 +467,7 @@ function createMcpServer() {
{
method: 'elicitation/create',
params: {
mode: 'form',
message: args.message,
requestedSchema: {
type: 'object',
Expand Down Expand Up @@ -517,6 +520,7 @@ function createMcpServer() {
{
method: 'elicitation/create',
params: {
mode: 'form',
message: 'Please review and update the form fields with defaults',
requestedSchema: {
type: 'object',
Expand Down Expand Up @@ -592,6 +596,7 @@ function createMcpServer() {
{
method: 'elicitation/create',
params: {
mode: 'form',
message: 'Please select options from the enum fields',
requestedSchema: {
type: 'object',
Expand Down Expand Up @@ -674,6 +679,106 @@ function createMcpServer() {
}
);

// SEP-1036: URL mode elicitation
mcpServer.registerTool(
'test_elicitation_sep1036_url',
{
description: 'Tests URL mode elicitation per SEP-1036',
inputSchema: {}
},
async () => {
try {
const elicitationId = `sep1036-test-${randomUUID()}`;
const result = await mcpServer.server.elicitInput({
mode: 'url',
message: 'Please complete authorization to continue',
url: 'https://mcp.example.com/authorize',
elicitationId
});

return {
content: [
{
type: 'text',
text: `URL elicitation completed: action=${result.action}`
}
]
};
} catch (error: any) {
return {
content: [
{
type: 'text',
text: `URL elicitation not supported or error: ${error.message}`
}
]
};
}
}
);

// SEP-1036: URL mode elicitation error flow
mcpServer.registerTool(
'test_elicitation_sep1036_error',
{
description:
'Tests URLElicitationRequiredError flow per SEP-1036 (throws error)',
inputSchema: {}
},
async () => {
const elicitationId = `sep1036-error-${randomUUID()}`;
throw new McpError(
ErrorCode.UrlElicitationRequired,
'Authorization required to access this resource',
{
elicitations: [
{
mode: 'url',
message: 'Please authorize access to continue',
url: 'https://mcp.example.com/authorize-error-test',
elicitationId
}
]
}
);
}
);

// SEP-1036: URL mode elicitation with completion notification
mcpServer.registerTool(
'test_elicitation_sep1036_complete',
{
description:
'Tests URL mode elicitation with completion notification per SEP-1036',
inputSchema: {}
},
async () => {
const elicitationId = `sep1036-complete-${randomUUID()}`;
const result = await mcpServer.server.elicitInput({
mode: 'url',
message: 'Please complete the authorization flow',
url: 'https://mcp.example.com/authorize-with-completion',
elicitationId
});

// Send completion notification after client accepts
if (result.action === 'accept') {
// Create a notifier for this elicitationId and send the notification
const notifier =
mcpServer.server.createElicitationCompletionNotifier(elicitationId);
await notifier();
}
return {
content: [
{
type: 'text',
text: `URL elicitation with completion: action=${result.action}, notification sent`
}
]
};
}
);

// SEP-1613: JSON Schema 2020-12 conformance test tool
// This tool is registered with a Zod schema for tools/call validation,
// but the tools/list handler (below) returns the raw JSON Schema 2020-12
Expand Down
9 changes: 6 additions & 3 deletions src/scenarios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { JsonSchema2020_12Scenario } from './server/json-schema-2020-12';

import { ElicitationDefaultsScenario } from './server/elicitation-defaults';
import { ElicitationEnumsScenario } from './server/elicitation-enums';
import { ElicitationUrlModeScenario } from './server/elicitation-url.js';
import { ServerSSEPollingScenario } from './server/sse-polling';
import { ServerSSEMultipleStreamsScenario } from './server/sse-multiple-streams';

Expand Down Expand Up @@ -58,6 +59,8 @@ import { listMetadataScenarios } from './client/auth/discovery-metadata';
const pendingClientScenariosList: ClientScenario[] = [
// Elicitation scenarios (SEP-1330)
new ElicitationEnumsScenario(),
// Elicitation scenarios (SEP-1036) - URL mode (pending SDK release)
new ElicitationUrlModeScenario(),

// JSON Schema 2020-12 (SEP-1613)
// This test is pending until the SDK includes PR #1135 which preserves
Expand Down Expand Up @@ -103,13 +106,13 @@ const allClientScenariosList: ClientScenario[] = [
// Elicitation scenarios (SEP-1034)
new ElicitationDefaultsScenario(),

// Elicitation scenarios (SEP-1330, SEP-1036) - pending
...pendingClientScenariosList,

// SSE Polling scenarios (SEP-1699)
new ServerSSEPollingScenario(),
new ServerSSEMultipleStreamsScenario(),

// Elicitation scenarios (SEP-1330) - pending
new ElicitationEnumsScenario(),

// Resources scenarios
new ResourcesListScenario(),
new ResourcesReadTextScenario(),
Expand Down
34 changes: 34 additions & 0 deletions src/scenarios/server/client-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,40 @@ export async function connectToServer(
};
}

/**
* Create and connect an MCP client with URL elicitation capability (SEP-1036)
*/
export async function connectToServerWithUrlElicitation(
serverUrl: string
): Promise<MCPClientConnection> {
const client = new Client(
{
name: 'conformance-test-client',
version: '1.0.0'
},
{
capabilities: {
// Client capabilities
sampling: {},
elicitation: {
url: {}
}
}
}
);

const transport = new StreamableHTTPClientTransport(new URL(serverUrl));

await client.connect(transport);

return {
client,
close: async () => {
await client.close();
}
};
}

/**
* Helper to collect notifications (logging and progress)
*/
Expand Down
Loading
Loading