-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Describe the bug
new McpServer() throws during construction with:
Error: Schema method literal must be a string
This happens before any user code registers tools/resources/prompts (during SDK initialization when it installs default request handlers like ping). It appears the SDK’s Server.setRequestHandler() only reads method literals from _def.value / .value, but in some Zod runtimes the literal is stored under _def.values[0].
Related theme / potentially overlapping work:
- Migrate to Zod 4 #1251 (Migrate to Zod 4)
- Decouple from Zod, allow any validator (bring your own) #1252 (Decouple from Zod, allow any validator)
- Type-first as opposed to Zod schema-first approach #1253 (Type-first as opposed to Zod schema-first approach)
- Bug:
server.tool()silently ignores ZodObject schemas and strips all arguments #1291 (Bug: server.tool() silently ignores ZodObject schemas and strips all arguments) — schema handling bug, though this issue occurs even before tool registration - [TypeScript] Zod's .toJSONSchema() output type incompatible with elicitInput's requestedSchema parameter #1362 ([TypeScript] Zod's .toJSONSchema() output type incompatible...) — not the same failure mode, but same Zod/schema compatibility surface area
To Reproduce
Steps to reproduce the behavior:
- Install deps (any package manager):
@modelcontextprotocol/sdk@1.25.2zod@3.25.1
- Run:
// repro.js
const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
new McpServer({ name: "repro", version: "1.0.0" });
console.log("constructed");node repro.js
Expected behavior
new McpServer() constructs successfully (default handlers like ping should register without error).
Logs
Example stack:
Error: Schema method literal must be a string
at Server.setRequestHandler (.../node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js:117:19)
at new Protocol (.../node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js:37:14)
at new Server (.../node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js:41:9)
at new McpServer (.../node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js:28:23)
Additional observed detail:
- For the SDK’s internal request schemas (e.g.
PingRequestSchema),method’s schema_defcontains{ type, values }and the literal is at_def.values[0], while_def.valueand.valueareundefined. dist/cjs/server/index.jscurrently does:methodValue = legacyDef?.value ?? v3Schema.value;- then throws if
typeof methodValue !== 'string'
Additional context
Workaround (ugly): monkey-patch Server.prototype.setRequestHandler before new McpServer() to fallback to _def.values[0] when _def.value/.value are missing, then retry registration. This suggests the SDK should either:
- use the existing compat helper (it already has logic to read
values[0]in some places), or - extend
Server.setRequestHandlermethod-literal extraction to check_def.values[0]as a fallback.