diff --git a/docs/mcp-dep-bug-need-verify.md b/docs/mcp-dep-bug-need-verify.md deleted file mode 100644 index 12c4edf..0000000 --- a/docs/mcp-dep-bug-need-verify.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -summary: "Pending upstream bug: SDK 1.22.0 crashes on tools/list when tools are registered with JSON Schema (not Zod)" -read_when: - - "Investigating SDK version bumps or mcporter generate-cli failures" - - "Seeing 'Cannot read properties of undefined (reading "typeName")' from tools/list" ---- - -# @modelcontextprotocol/sdk 1.22.0 regression (tools/list crashes) - -## What happens -`tools/list` throws `Cannot read properties of undefined (reading 'typeName')` when a server registers tools with **JSON Schema** `inputSchema`/`outputSchema` (spec‑compliant). This breaks `mcporter generate-cli --compile` against inline STDIO servers and any server that provides JSON Schema instead of Zod. - -## Repro (in this repo) -- File: `tests/cli-generate-cli.integration.test.ts` writes `mock-stdio.mjs` that calls `registerTool('echo', { inputSchema: {type:'object',...}, outputSchema:{...} }, cb)`. -- With `@modelcontextprotocol/sdk@1.22.0`, running `pnpm test` or `mcporter generate-cli "node mock-stdio.mjs" --compile ...` fails with the error above when `tools/list` runs. - -## Why (code path in SDK 1.22.0) -- `McpServer.setRequestHandler(ListToolsRequestSchema)` unconditionally passes `tool.inputSchema` / `tool.outputSchema` to `zodToJsonSchema(...)`. -- For JSON objects (no `_def`), `zod-to-json-schema` tries to read `schema._def.typeName` and throws. -- `call_tool` also assumes Zod (`safeParseAsync`) and would fail later for JSON Schema tools. - -## Minimal upstream fix (suggested) -- Guard with the existing `isZodTypeLike` helper: - - If schema is Zod → keep current conversion/validation. - - Else → treat it as already-JSON-Schema: pass through in `tools/list`; skip Zod validation in `call_tool`. - -## Current mitigation here -- Pinned `@modelcontextprotocol/sdk` to `~1.21.2` and kept `zod@3.x` to match. -- Runtime `listTools` now paginates and matches 1.22+ signature; tests green on the pinned SDK. - -## Upstream status -- As of 2025-11-22: no public issue found that matches this exact regression. Consider filing against `modelcontextprotocol/typescript-sdk` with the inline repro above. - -## Action items when unpinning -1) Check if a newer SDK release adds guards around `zodToJsonSchema` / `safeParseAsync` for JSON Schema. -2) If fixed, drop the pin and re-run `pnpm check && pnpm test`. -3) If not fixed, keep the pin or patch upstream and send a PR. diff --git a/package.json b/package.json index eed3515..85a3a86 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ }, "dependencies": { "@iarna/toml": "^2.2.5", - "@modelcontextprotocol/sdk": "~1.21.2", + "@modelcontextprotocol/sdk": "^1.22.0", "acorn": "^8.15.0", "commander": "^14.0.2", "es-toolkit": "^1.42.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4aa66e9..ca111b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^2.2.5 version: 2.2.5 '@modelcontextprotocol/sdk': - specifier: ~1.21.2 - version: 1.21.2 + specifier: ^1.22.0 + version: 1.22.0 acorn: specifier: ^8.15.0 version: 8.15.0 @@ -51,9 +51,6 @@ importers: '@typescript/native-preview': specifier: 7.0.0-dev.20251121.1 version: 7.0.0-dev.20251121.1 - bun: - specifier: runtime:^1.3.2 - version: runtime:1.3.2 bun-types: specifier: ^1.3.3 version: 1.3.3 @@ -63,9 +60,6 @@ importers: express: specifier: ^5.1.0 version: 5.1.0 - node: - specifier: runtime:^24.10.0 - version: runtime:24.11.1 oxlint: specifier: ^1.29.0 version: 1.29.0(oxlint-tsgolint@0.8.0) @@ -322,8 +316,8 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@modelcontextprotocol/sdk@1.21.2': - resolution: {integrity: sha512-HXR5NeVbaL45KuPRqfBQL/hcdc8Y197ALj5G75M5qUMcOk2at0bj2Nns4ZnjU2mTw52360TK63oDqvRjc1iPRQ==} + '@modelcontextprotocol/sdk@1.22.0': + resolution: {integrity: sha512-VUpl106XVTCpDmTBil2ehgJZjhyLY2QZikzF8NvTXtLRF1CvO5iEE2UNZdVIUer35vFOwMKYeUGbjJtvPWan3g==} engines: {node: '>=18'} peerDependencies: '@cfworker/json-schema': ^4.1.1 @@ -757,85 +751,6 @@ packages: bun-types@1.3.3: resolution: {integrity: sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ==} - bun@runtime:1.3.2: - resolution: - type: variations - variants: - - resolution: - archive: zip - bin: bun - integrity: sha256-2FhHmC21dFGBMKRVgrzxTY4r6WELZstQRsIDSFeLD+I= - prefix: bun-darwin-aarch64 - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-darwin-aarch64.zip - targets: - - cpu: arm64 - os: darwin - - resolution: - archive: zip - bin: bun - integrity: sha256-eNTwyGN0J6wL5VY5ppf/agJejrlAppIMpQhgPEGlp7A= - prefix: bun-darwin-x64 - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-darwin-x64.zip - targets: - - cpu: x64 - os: darwin - - resolution: - archive: zip - bin: bun - integrity: sha256-urqUctj+AoPHuZP9Z/2RBUD3YIyGDtMo+jMcTQwNvlQ= - prefix: bun-linux-aarch64-musl - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-linux-aarch64-musl.zip - targets: - - cpu: arm64 - os: linux - libc: musl - - resolution: - archive: zip - bin: bun - integrity: sha256-/jjBO2trRQr05PD7jgSyLspT+c1xBo0dHuv09KRPAvs= - prefix: bun-linux-aarch64 - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-linux-aarch64.zip - targets: - - cpu: arm64 - os: linux - - resolution: - archive: zip - bin: bun - integrity: sha256-bndzZQmHVatRadGmCStq4Ydh9KbkoyNlJSrZieSUiFo= - prefix: bun-linux-x64-musl - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-linux-x64-musl.zip - targets: - - cpu: x64 - os: linux - libc: musl - - resolution: - archive: zip - bin: bun - integrity: sha256-DLVqRIS9d2Sj7vm55nq0V4QJgSh7RnlJdNHmYSy/Zwk= - prefix: bun-linux-x64 - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-linux-x64.zip - targets: - - cpu: x64 - os: linux - - resolution: - archive: zip - bin: bun.exe - integrity: sha256-XnO066DMCQhd8UHhFnYJsQBXDxoNU42H+bnA2lSvWNY= - prefix: bun-windows-x64 - type: binary - url: https://github.com/oven-sh/bun/releases/download/bun-v1.3.2/bun-windows-x64.zip - targets: - - cpu: x64 - os: win32 - version: 1.3.2 - hasBin: true - bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} @@ -1136,96 +1051,6 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} - node@runtime:24.11.1: - resolution: - type: variations - variants: - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-mLqRmgOQ2MQi1LsxBexbd3I89UFDtMHkudd2kPoHUgY= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-aix-ppc64.tar.gz - targets: - - cpu: ppc64 - os: aix - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-sFqjpm7+aAAj+TC9WvP9u9VCeU2lZEyirXEdaMvU3DU= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-darwin-arm64.tar.gz - targets: - - cpu: arm64 - os: darwin - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-CWCBttb83T9boPXx1EpH6DA3rS546tomZxwlL+ZN0RE= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-darwin-x64.tar.gz - targets: - - cpu: x64 - os: darwin - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-Dck+xceYsNNH8GjbbSBdA96ppxdl5qU5IraCuRJl1x8= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-linux-arm64.tar.gz - targets: - - cpu: arm64 - os: linux - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-zUFAfzNS3i8GbqJsXF0OqbY2I3TWthg4Wp8una0iBhY= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-linux-ppc64le.tar.gz - targets: - - cpu: ppc64le - os: linux - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-XUyLyl+PJZP5CB3uOYNHYOhaFvphyVDz6G7IWZbwBVA= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-linux-s390x.tar.gz - targets: - - cpu: s390x - os: linux - - resolution: - archive: tarball - bin: bin/node - integrity: sha256-WKX/XMjyIA5Fi+oi4ynVwZlKobER1JnKRuwkEdWCOco= - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-linux-x64.tar.gz - targets: - - cpu: x64 - os: linux - - resolution: - archive: zip - bin: node.exe - integrity: sha256-zp7k5Ufr3/NVvrSOMJsWbCTfa+ApHJ6vEDzhXz3p5bQ= - prefix: node-v24.11.1-win-arm64 - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-win-arm64.zip - targets: - - cpu: arm64 - os: win32 - - resolution: - archive: zip - bin: node.exe - integrity: sha256-U1WubXxJ7dz959NKw0hoIGAKgxv4HcO9ylyNtqm7DnY= - prefix: node-v24.11.1-win-x64 - type: binary - url: https://nodejs.org/download/release/v24.11.1/node-v24.11.1-win-x64.zip - targets: - - cpu: x64 - os: win32 - version: 24.11.1 - hasBin: true - object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1707,7 +1532,7 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.5': {} - '@modelcontextprotocol/sdk@1.21.2': + '@modelcontextprotocol/sdk@1.22.0': dependencies: ajv: 8.17.1 ajv-formats: 3.0.1(ajv@8.17.1) @@ -2063,8 +1888,6 @@ snapshots: dependencies: '@types/node': 24.10.1 - bun@runtime:1.3.2: {} - bytes@3.1.2: {} call-bind-apply-helpers@1.0.2: @@ -2357,8 +2180,6 @@ snapshots: negotiator@1.0.0: {} - node@runtime:24.11.1: {} - object-assign@4.1.1: {} object-inspect@1.13.4: {} diff --git a/tests/cli-generate-cli.integration.test.ts b/tests/cli-generate-cli.integration.test.ts index 974688c..ef8d5eb 100644 --- a/tests/cli-generate-cli.integration.test.ts +++ b/tests/cli-generate-cli.integration.test.ts @@ -16,6 +16,7 @@ const CLI_ENTRY = fileURLToPath(new URL('../dist/cli.js', import.meta.url)); const testRequire = createRequire(import.meta.url); const MCP_SERVER_MODULE = pathToFileURL(testRequire.resolve('@modelcontextprotocol/sdk/server/mcp.js')).href; const STDIO_SERVER_MODULE = pathToFileURL(testRequire.resolve('@modelcontextprotocol/sdk/server/stdio.js')).href; +const ZOD_MODULE = pathToFileURL(path.join(process.cwd(), 'node_modules', 'zod', 'index.js')).href; async function ensureDistBuilt(): Promise { try { @@ -313,20 +314,15 @@ describe('mcporter CLI integration', () => { const scriptPath = path.join(tempDir, 'mock-stdio.mjs'); const scriptSource = `import { McpServer } from '${MCP_SERVER_MODULE}'; import { StdioServerTransport } from '${STDIO_SERVER_MODULE}'; +import { z } from '${ZOD_MODULE}'; const server = new McpServer({ name: 'inline-cli', version: '1.0.0' }); server.registerTool('echo', { title: 'Echo', description: 'Return the provided text', - inputSchema: { - type: 'object', - properties: { text: { type: 'string' } }, - required: ['text'], - }, - outputSchema: { - type: 'object', - properties: { text: { type: 'string' } }, - }, + // Use Zod schemas to keep SDK 1.22.x happy when converting to JSON Schema. + inputSchema: z.object({ text: z.string() }), + outputSchema: z.object({ text: z.string() }), }, async ({ text }) => ({ content: [{ type: 'text', text }], structuredContent: { text },