modelcontextprotocol / modelcontextprotocol/conformance

SEP-2243: safe-integer-range MUST is untested, and SDKs disagree on what it requires

Open
#445 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
127
Forks
101
Avg merge
6d 1h
Merged PRs (30d)
7

Description

The requirement

Released 2026-07-28 server/tools.mdx, in the x-mcp-header constraint list:

Integer values MUST be within the safe range for integers represented using IEEE754 double-precision floating point numbers (−253+1 to 253−1)

Nothing in the harness covers it: no row in src/seps/sep-2243.yaml (the primitive-only text stops at "not permitted"), no check ID emitted, and grep -iE 'safe range|MAX_SAFE_INTEGER|9007199254740991|2\*\*53' over src/ returns zero matches. An SDK that mirrors 9007199254740993 into a header passes the suite today.

It binds at call time, on argument values

Settled by the discussion on PR #2772, which introduced the sentence (@mikekistler, merged 2026-05-29):

As discussed in the Transports WG, I think we aligned on something like: only integer arguments from -2^53 to 2^53 (inclusive) can be mirrored to a header. Any other numeric values produce an error.
— @pja-ant

and the WG meeting notes @mikekistler pasted into the review:

Consensus: Custom numeric headers are strictly restricted to integers. Clients must reject tool inputs containing non-integer numbers in custom headers.

So this is a runtime constraint on arguments, not a schema-shape constraint.

The actual gap: SDKs disagree on the consequence

The spec states the constraint but never says what the client does when an argument violates it. Two SDKs read it two ways:

SDK Behavior on an out-of-range integer
csharp-sdk throws McpException — the call fails (McpHeaderExtractor.cs#L116-L121)
typescript-sdk mcpParamPrimitiveToString returns undefined, and buildMcpParamHeaders does continue — the header is silently omitted and the call proceeds (mcpParamHeaders.ts#L211, L311)

typescript-sdk is internally consistent — its server-side validateMcpParamHeaders skips the comparison for exactly the same values — so nothing errors end to end. But that silence is the failure mode the WG was trying to prevent: an intermediary routing on Mcp-Param-UserId simply doesn't receive the header, with no signal to anyone. Against the consensus quoted above, the C# behavior looks like the intended one.

Worth confirming which is normative before writing a check, since whichever we assert will make the other SDK fail.

Shape of the check

Belongs in the existing http-custom-headers positive scenario rather than a new one, per the fewer-scenarios-more-checks rule:

  • add an integer param carrying x-mcp-header to a tool the scenario already exercises
  • have the scenario ask the client to call it with an out-of-range value (e.g. 2**53)
  • emit sep-2243-x-mcp-header-integer-safe-range asserting the agreed behavior
  • add the matching sep-2243.yaml row and a negative fixture proving the check can fail

Note for whoever writes it: C# accepts 42.0 and 4.2e1 as canonical 42, and TS compares integer-typed declarations numerically, so the fixture should use a genuinely out-of-range value rather than a differently-spelled in-range one.

Aside: the released spec contradicts itself here

Same bound, two different justifications, both shipped in 2026-07-28:

  • server/tools.mdx — "safe range for integers represented using IEEE754 double-precision floating point numbers"
  • basic/transports/streamable-http.mdx (line 386) — "safe range for JavaScript"

@pja-ant flagged the JavaScript phrasing as imprecise ("Even in languages that have native integers, sometimes JSON parsing libraries will parse to double by default"), @mikekistler replied "Fair point. I will revise." — but the revision only landed in tools.mdx. Probably a one-line upstream fix.

Filed while verifying spec wording for #344 / #444; unrelated to those changes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the existing http-custom-headers positive scenario and src/seps/sep-2243.yaml, then review PR #2772 and the cited C# and TypeScript SDK behavior before deciding the normative outcome. Add the out-of-range integer case, emit sep-2243-x-mcp-header-integer-safe-range, and provide the matching negative fixture. Done means the check and YAML row cover the agreed behavior, with the relevant wording contradiction addressed in server/tools.mdx and streamable-http.mdx.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, typescript, yaml
Domain
api, documentation, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.