typescript-sdk/examples/json-response/client.ts

49 lines
1.9 KiB
TypeScript

/**
* Asserts the `responseMode: 'json'` server answers a `tools/call` with a
* `Content-Type: application/json` body (not `text/event-stream`) AND that the
* regular `Client` works against it unchanged.
*
* HTTP-only, modern-only — `responseMode` shapes the 2026-07-28 per-request
* HTTP path; there is no stdio equivalent and 2025-era traffic goes through
* the stateless legacy fallback unaffected.
*/
import { check, parseExampleArgs } from '@mcp-examples/shared';
import { Client, isJsonContentType, StreamableHTTPClientTransport } from '@modelcontextprotocol/client';
const { url } = parseExampleArgs();
const client = new Client({ name: 'json-response-example-client', version: '1.0.0' }, { versionNegotiation: { mode: 'auto' } });
await client.connect(new StreamableHTTPClientTransport(new URL(url)));
// Low-level: a 2026-07-28 (envelope) request should come back as plain JSON —
// the JSON content-type assertion is the point of the story.
const probe = await fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
accept: 'application/json, text/event-stream',
'mcp-protocol-version': '2026-07-28',
'mcp-method': 'tools/list'
},
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'tools/list',
params: {
_meta: {
'io.modelcontextprotocol/protocolVersion': '2026-07-28',
'io.modelcontextprotocol/clientInfo': { name: 'probe', version: '1.0.0' },
'io.modelcontextprotocol/clientCapabilities': {}
}
}
})
});
check.equal(isJsonContentType(probe.headers.get('content-type')), true);
check.equal(probe.status, 200);
// High-level: the regular Client works unchanged.
const result = await client.callTool({ name: 'greet', arguments: { name: 'json' } });
check.equal(result.content?.[0]?.type === 'text' ? result.content[0].text : '', 'Hello, json!');
await client.close();