Skip to content

fix(deps): patch vulnerable dependencies and keep JSON Schema tools working on MCP SDK 1.31+ - #25

Merged
imbenrabi merged 1 commit into
mainfrom
claude/project-thread-0itqrt
Oct 10, 2026
Merged

imbenrabi merged 1 commit into
mainfrom
claude/project-thread-0itqrt

Conversation

@imbenrabi

Copy link
Copy Markdown
Contributor

Requested by Ben · project thread

Before: npm audit reported 28 vulnerabilities (4 critical, 18 high), 12 of them in runtime dependencies that ship to consumers (MCP SDK OAuth credential leak, several fastify validation/auth bypasses, proxy-addr IP spoofing, hono, path-to-regexp, qs, ...). Also, any consumer installing toolception today resolves @modelcontextprotocol/sdk 1.32.x, where tools with a plain JSON Schema inputSchema (the form the README documents) fail to register and tools/list returns "Method not found".

After: the runtime audit (npm audit --omit=dev) is clean and the full audit is down to 5 moderate findings, all from sprintf-js under vite-plugin-dts at build time. JSON Schema tools register again and receive their arguments.

SDK 1.31 started throwing when server.tool() gets a non-Zod object. Before that, 1.27 silently treated the JSON Schema as annotations and called the handler without arguments, so these tools were already quietly broken.

How

  • @modelcontextprotocol/sdk ^1.27.1 → ^1.32.1 (GHSA-6qxp-vccf-f47h), fastify ^5.0.0 → ^5.12.5; the higher minimums make sure consumers pick up the patched versions.
  • Refreshed the lockfile for transitive fixes; vitest and @vitest/coverage-v8 moved to v5 to clear the critical tinypool RCE advisories (no API changes were needed).
  • DynamicToolManager.registerSingleTool: Zod raw shapes still go through server.tool() exactly as before. Anything else goes through registerTool with z.object({}).passthrough(), so args reach the handler. Clients still see an open object schema rather than the declared JSON Schema (the same as before); advertising the real schema would need a JSON Schema → Zod conversion and is left for a follow-up.
  • Added an e2e test with a real SDK server and client that calls a JSON Schema tool with arguments. Updated the fakes and src/core/AGENTS.md.

Not fixed here: sprintf-js (moderate, no patched release) comes in through vite-plugin-dts → @microsoft/api-extractor. Clearing it means moving to vite-plugin-dts 5 (unplugin-dts), which changes the build. It's build-time only.

Checks run locally: typecheck, test:run (326/326), test:coverage, build, and npm audit --audit-level=critical (passes). Note that vitest 5 declares engines.node ^22.12 || ^24 || >=26, while CI uses 25.3.0. npm only warns about this, and CI will confirm it works.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rw9KfvgjjyMscEQdRXbQaS


Generated by Claude Code

…orking on MCP SDK 1.31+

Bump @modelcontextprotocol/sdk to ^1.32.1 (GHSA-6qxp-vccf-f47h) and
fastify to ^5.12.5 (several validation/auth bypass advisories), refresh
the lockfile for transitive fixes (proxy-addr, hono, path-to-regexp, qs,
fast-uri, ip-address, ...), and move vitest/@vitest/coverage-v8 to v5
to clear the critical tinypool advisories.

SDK 1.31 throws when server.tool() receives a plain JSON Schema object,
which broke every tool defined with a JSON Schema inputSchema (the form
the README documents). Register those via registerTool with a
passthrough Zod object so they load and receive their arguments.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rw9KfvgjjyMscEQdRXbQaS
@imbenrabi imbenrabi self-assigned this Oct 10, 2026
@imbenrabi
imbenrabi marked this pull request as ready for review October 10, 2026 07:46

@imbenrabi imbenrabi left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compatibility review against the FMP MCP Server: GO

I reviewed head 08c00b6 against imbenrabi/Financial-Modeling-Prep-MCP-Server, which depends on toolception ^0.6.3. I packed this branch and installed it into the server, then ran the server's own checks and a live client against it.

Dependency resolution. Installing this branch moves the server's own @modelcontextprotocol/sdk to 1.32.1 and fastify to 5.12.5, and npm still shares a single copy of each between the server and toolception. The server's existing ranges (^1.27.1, ^5.7.2) already allow these versions, so nothing in the server's package.json has to change.

Server checks with this branch installed

Server branch typecheck build tests
main pass pass 850/850
prompts fix (server #108) pass pass 852/852

Live check. I started the server in ALL_TOOLS, DYNAMIC and STATIC (search,quotes) modes and connected a real SDK client to each:

  • tools/list still shows the full Zod-derived input schemas (for example searchSymbol has query and required: ["query"]).
  • Calls with invalid arguments are rejected with -32602.
  • Valid arguments reach the handlers.

Call-site review. All 253 server tools pass Zod raw shapes through ToolCollector, so isZodRawShape() returns true for every one of them. They keep using the unchanged server.tool() path, and the new registerTool + passthrough branch never runs for the server. Every branch passes only args to the handler, which matches what createModuleAdapter expects. registerPrompts (server.prompt with {}) also works on SDK 1.32.1.

Stacking. I merged this branch with #27 (STATIC per-client servers) locally. They merge cleanly, and typecheck plus 329/329 tests pass. With both installed, the server in ALL_TOOLS mode keeps two clients connected at once, and each client's ?config= token is used.

Non-blocking notes

  • JSON Schema tools now advertise an open object schema to clients. The FMP server isn't affected.
  • vitest 5 declares engines.node ^22.12 || ^24 || >=26 while CI runs Node 25. CI is green, so it's only a warning.

No changes needed for the server.


Generated by Claude Code

imbenrabi pushed a commit that referenced this pull request Oct 10, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pqcus1BTWLVAJaPavwdkGX
@imbenrabi
imbenrabi merged commit 2f15dfe into main Oct 10, 2026
1 check passed
@imbenrabi imbenrabi mentioned this pull request Oct 10, 2026
imbenrabi pushed a commit that referenced this pull request Oct 10, 2026
The next release carries #25, #26 and #27. #27 changes STATIC mode to a
server per client, so it ships as a minor version: consumers pinned to
^0.6.x keep 0.6.3 until they opt in.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pqcus1BTWLVAJaPavwdkGX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants