Skip to content

Commit 46ea7f6

Browse files
feat: add client-side SEP-1034 conformance test for elicitation defaults
Adds a conformance test that validates client SDKs properly apply default values for omitted fields in elicitation responses per SEP-1034. The test spins up a server that sends elicitation requests with defaults, and validates that the client returns content with those defaults applied.
1 parent fa7a0bc commit 46ea7f6

File tree

3 files changed

+504
-1
lines changed

3 files changed

+504
-1
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Test client for SEP-1034 client-side elicitation defaults
5+
* This client intentionally returns empty/partial content in elicitation responses
6+
* to verify that the SDK applies defaults for omitted fields.
7+
*/
8+
9+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10+
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
11+
import { ElicitRequestSchema } from '@modelcontextprotocol/sdk/types.js';
12+
13+
async function main(): Promise<void> {
14+
const serverUrl = process.argv[2];
15+
16+
if (!serverUrl) {
17+
console.error('Usage: elicitation-defaults-test <server-url>');
18+
process.exit(1);
19+
}
20+
21+
console.log(`Connecting to MCP server at: ${serverUrl}`);
22+
23+
try {
24+
const client = new Client(
25+
{
26+
name: 'elicitation-defaults-test-client',
27+
version: '1.0.0'
28+
},
29+
{
30+
capabilities: {}
31+
}
32+
);
33+
34+
// Register elicitation handler that returns empty content
35+
// The SDK should fill in defaults for all omitted fields
36+
client.setRequestHandler(ElicitRequestSchema, async (request) => {
37+
console.log(
38+
'📋 Received elicitation request:',
39+
JSON.stringify(request.params, null, 2)
40+
);
41+
console.log(
42+
'✅ Accepting with empty content - SDK should apply defaults'
43+
);
44+
45+
// Return empty content - SDK should merge in defaults
46+
return {
47+
action: 'accept' as const,
48+
content: {}
49+
};
50+
});
51+
52+
const transport = new StreamableHTTPClientTransport(new URL(serverUrl));
53+
54+
await client.connect(transport);
55+
console.log('✅ Successfully connected to MCP server');
56+
57+
// List available tools
58+
const tools = await client.listTools();
59+
console.log(
60+
'📦 Available tools:',
61+
tools.tools.map((t) => t.name)
62+
);
63+
64+
// Call the test tool which will trigger elicitation
65+
const testTool = tools.tools.find(
66+
(t) => t.name === 'test_client_elicitation_defaults'
67+
);
68+
if (!testTool) {
69+
console.error('❌ Test tool not found: test_client_elicitation_defaults');
70+
process.exit(1);
71+
}
72+
73+
console.log('🔧 Calling test_client_elicitation_defaults tool...');
74+
const result = await client.callTool({
75+
name: 'test_client_elicitation_defaults',
76+
arguments: {}
77+
});
78+
79+
console.log('📄 Tool result:', JSON.stringify(result, null, 2));
80+
81+
await transport.close();
82+
console.log('✅ Connection closed successfully');
83+
84+
process.exit(0);
85+
} catch (error) {
86+
console.error('❌ Error:', error);
87+
process.exit(1);
88+
}
89+
}
90+
91+
main().catch((error) => {
92+
console.error('Unhandled error:', error);
93+
process.exit(1);
94+
});

0 commit comments

Comments
 (0)