Bug
Calling display_pdf or interact in examples/pdf-server fails client-side, before the tool call ever reaches the server, on clients with a strict JSON Schema 2020-12-only output-schema validator (observed on Claude Desktop / Claude Code):
Tool 'display_pdf' has an invalid outputSchema: JSON Schema declares an unsupported dialect
("$schema": "http://json-schema.org/draft-07/schema#"). The default validator supports
JSON Schema 2020-12 only, pass a pre-configured Ajv instance to AjvJs
interact has no outputSchema of its own, but it fails too — the client rejects the entire tools/list response over the one bad tool (display_pdf), so every tool in the list breaks together.
Root cause
@modelcontextprotocol/sdk (pinned ^1.29.0 here, confirmed still present in latest 1.30.0) always emits "$schema": "http://json-schema.org/draft-07/schema#" on Zod-derived inputSchema/outputSchema, with no way to configure it via registerTool/registerAppTool:
node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js:9-17 — mapMiniTarget() falls back to 'draft-7' whenever no target is passed.
node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:88-96 — the tools/list handler never passes a target.
This is a known, already-filed, still-open upstream bug: modelcontextprotocol/typescript-sdk#2721. There is no released SDK version that fixes it.
display_pdf, read_pdf_bytes, and save_pdf in examples/pdf-server/server.ts all declare outputSchema: z.object({...}) via registerAppTool and trigger this.
Fix
Opening a PR that adds fixOutputSchemaDialect(server) to src/server/index.ts — a workaround that wraps Server.setRequestHandler to intercept the tools/list handler and rewrite the draft-07 $schema to https://json-schema.org/draft/2020-12/schema before the response goes out. Wired into examples/pdf-server/server.ts, called immediately after new McpServer(...).
Follow-up (not in the linked PR, scoped out to keep it focused)
The same unpatched bug affects other examples that declare outputSchema without calling the new helper:
examples/budget-allocator-server/server.ts
examples/cohort-heatmap-server/server.ts
examples/basic-server-vanillajs/server.ts
examples/integration-server/server.ts
examples/customer-segmentation-server/server.ts
examples/system-monitor-server/server.ts
examples/debug-server/server.ts
examples/wiki-explorer-server/server.ts
examples/scenario-modeler-server/server.ts
examples/video-resource-server/server.ts
examples/threejs-server/server.ts
Happy to send a follow-up PR applying fixOutputSchemaDialect to these too, or maintainers may prefer to fold it into registerAppTool itself once there's agreement on the right call-site contract (it must run before any tool registration, since McpServer only installs its real tools/list handler once, lazily, on first registration).
Bug
Calling
display_pdforinteractinexamples/pdf-serverfails client-side, before the tool call ever reaches the server, on clients with a strict JSON Schema 2020-12-only output-schema validator (observed on Claude Desktop / Claude Code):interacthas nooutputSchemaof its own, but it fails too — the client rejects the entiretools/listresponse over the one bad tool (display_pdf), so every tool in the list breaks together.Root cause
@modelcontextprotocol/sdk(pinned^1.29.0here, confirmed still present in latest1.30.0) always emits"$schema": "http://json-schema.org/draft-07/schema#"on Zod-derivedinputSchema/outputSchema, with no way to configure it viaregisterTool/registerAppTool:node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js:9-17—mapMiniTarget()falls back to'draft-7'whenever notargetis passed.node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js:88-96— thetools/listhandler never passes atarget.This is a known, already-filed, still-open upstream bug: modelcontextprotocol/typescript-sdk#2721. There is no released SDK version that fixes it.
display_pdf,read_pdf_bytes, andsave_pdfinexamples/pdf-server/server.tsall declareoutputSchema: z.object({...})viaregisterAppTooland trigger this.Fix
Opening a PR that adds
fixOutputSchemaDialect(server)tosrc/server/index.ts— a workaround that wrapsServer.setRequestHandlerto intercept thetools/listhandler and rewrite the draft-07$schematohttps://json-schema.org/draft/2020-12/schemabefore the response goes out. Wired intoexamples/pdf-server/server.ts, called immediately afternew McpServer(...).Follow-up (not in the linked PR, scoped out to keep it focused)
The same unpatched bug affects other examples that declare
outputSchemawithout calling the new helper:examples/budget-allocator-server/server.tsexamples/cohort-heatmap-server/server.tsexamples/basic-server-vanillajs/server.tsexamples/integration-server/server.tsexamples/customer-segmentation-server/server.tsexamples/system-monitor-server/server.tsexamples/debug-server/server.tsexamples/wiki-explorer-server/server.tsexamples/scenario-modeler-server/server.tsexamples/video-resource-server/server.tsexamples/threejs-server/server.tsHappy to send a follow-up PR applying
fixOutputSchemaDialectto these too, or maintainers may prefer to fold it intoregisterAppToolitself once there's agreement on the right call-site contract (it must run before any tool registration, sinceMcpServeronly installs its realtools/listhandler once, lazily, on first registration).