Skip to content

fix(server): keep the Mcp-Param check on a tool with a number-typed header - #2960

Merged
felixweinberger merged 4 commits into
mainfrom
fix/mcp-param-check-number-declaration
Oct 12, 2026
Merged

felixweinberger merged 4 commits into
mainfrom
fix/mcp-param-check-number-declaration

Conversation

@claude

@claude claude Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Requested by Felix Weinberger · Slack thread

Follow-up to #2762.

Before: #2762 makes the declaration scan report a tool as invalid when it puts x-mcp-header on a number-typed parameter. createMcpHandler compared the Mcp-Param-* headers with the body only when the scan was valid, so for such a tool the whole check went away, valid string, integer and boolean parameters included: a tools/call whose header disagrees with the body got 200 where released 2.3.0 answers 400 with -32020.

After: The scan keeps walking after a number fault. When those are the tool's only faults it returns the declarations next to the reason, and the handler checks whatever declarations the scan returns. The result is still invalid, so clients still drop the tool from tools/list and the server still warns; registerTool does not throw. Between an upgraded client and an upgraded server, a call by name of such a tool is answered 400 again, as against a 2.3.0 server; with #2762 alone it was 200. A tool with another fault as well was not checked in 2.3.0 and is not checked now.

How it was verified: Against released 2.3.0 over 13 tool shapes and 68 request cases (status, error code, the header named in the error, whether the handler ran), main today differs in 20 cases and this change in 0. The new server test fails without either source change (expected [200, …] to deeply equal [400, -32020, 'Mcp-Param-Region']); the new client test fails as soon as number is permitted again. core-internal, client and server suites pass; typecheck, ESLint, Prettier, sync-snippets --check and docs:check are clean. Changeset: @modelcontextprotocol/server patch.

🤖 Generated with Claude Code

https://claude.ai/code/session_012VRbFCp41otcScXE1YY3es


Generated by Claude Code

…eader

#2762 makes the declaration scan report a tool as invalid when it puts
`x-mcp-header` on a `number`-typed parameter, as the 2026-07-28 spec
requires of clients. `createMcpHandler` compared the `Mcp-Param-*`
headers of a `tools/call` with the body only when the scan was valid.
So for such a tool the whole check went away, its valid string, integer
and boolean parameters included: a call whose header disagrees with the
body was answered 200 where 2.3.0 answers 400 with -32020.

The scan now keeps walking after a `number` fault. When those are the
only faults it returns the declarations next to the reason, and the
handler checks whatever declarations the scan returns. The result is
still invalid, so a client still drops the tool from `tools/list` and
the server still warns when tools are listed.

The server then checks exactly the calls 2.3.0 checks. The header of
the number-typed parameter itself is still required and compared as a
number. A tool with another fault as well was not checked in 2.3.0 and
is not checked now. `registerTool` does not throw for such a tool,
because that would stop a server at startup after an upgrade.

Also here: one sentence in the 2026-07-28 migration page on the tool no
longer being listed, a server test for the check, a client test that
`listTools()` drops the tool (only a unit test of the scan covered
#2762), and three comments in mcpParamHeaders.ts that no longer matched
the code.
@claude
claude Bot requested a review from a team as a code owner October 5, 2026 15:12
@changeset-bot

changeset-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fbdfbec

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@2960

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@2960

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@2960

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@2960

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@2960

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@2960

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@2960

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@2960

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@2960

commit: fbdfbec

@claude claude Bot 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.

Findings marked 🟡 are optional suggestions and need no follow-up push.

Comment thread packages/server/src/server/createMcpHandler.ts
Comment thread docs/migration/support-2026-07-28.md Outdated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012VRbFCp41otcScXE1YY3es

@claude claude Bot 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.

Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.

Comment thread .changeset/mcp-param-check-number-declaration.md Outdated
@claude claude Bot added the v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes label Oct 6, 2026

@claude claude Bot 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.

I re-reviewed the latest push and found no bugs; the two docs follow-ups address the points I raised earlier, and the remaining question is a design call rather than a defect, so a maintainer look to confirm the intended client/server contract is still worthwhile.

What was reviewed:

  • The reworded changeset against the code: the stdio carve-out matches the early return in client.ts:2557, and "a call that carries a value for a declared parameter" matches validateMcpParamHeaders skipping absent/null body values (mcpParamHeaders.ts:355).
  • The scanner's early-return paths once more: a non-number fault still returns without declarations, so the handler gate at createMcpHandler.ts:833 only widens the check for number-only-invalid tools, as the changeset says.
  • The remaining design point (server validates a spec-invalid declaration that an upgraded client will never mirror) is now stated in both the changeset and the migration guide, so it is a deliberate, documented choice for the owners to confirm.
Extended reasoning...

The change touches the shared x-mcp-header scanner in core-internal, the tools/call header gate in createMcpHandler, two tests, a changeset and a migration paragraph; the only new commit since my last review is a one-line changeset rewording. It touches request validation (400 / -32020 on Mcp-Param-* mismatch) but no auth, crypto or data-exposure surface. All paths are covered by the repository-wide CODEOWNERS team, and the PR embeds a cross-package behaviour decision (client excludes the tool, server keeps validating it) that a maintainer should confirm, so I deferred rather than approved despite finding no bugs.

@felixweinberger
felixweinberger merged commit 43c45f4 into main Oct 12, 2026
20 checks passed
@felixweinberger
felixweinberger deleted the fix/mcp-param-check-number-declaration branch October 12, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants