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.

Assessment

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

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.

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.

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

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.

More from modelcontextprotocol/conformance

All issues in modelcontextprotocol/conformance

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.