modelcontextprotocol / modelcontextprotocol/conformance
SEP-2243: safe-integer-range MUST is untested, and SDKs disagree on what it requires
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-headerto 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-rangeasserting the agreed behavior - add the matching
sep-2243.yamlrow 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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