Skip to content

fix(core): validate RequestId integers against Number.MAX_SAFE_INTEGER#1806

Open
lanxevo3 wants to merge 3 commits intomodelcontextprotocol:mainfrom
lanxevo3:fix/request-id-safe-integer
Open

fix(core): validate RequestId integers against Number.MAX_SAFE_INTEGER#1806
lanxevo3 wants to merge 3 commits intomodelcontextprotocol:mainfrom
lanxevo3:fix/request-id-safe-integer

Conversation

@lanxevo3
Copy link
Copy Markdown

Per JSON-RPC spec and JavaScript Map semantics, integer request IDs must be safe integers. When a request id exceeds Number.MAX_SAFE_INTEGER, JavaScript Map lookups silently lose precision, causing the server to never find the matching response and hang permanently.

Bug

Send any JSON-RPC request with id: 9007199254740992 (MAX_SAFE_INTEGER + 1):

{"jsonrpc":"2.0","id":9007199254740992,"method":"tools/list"}

Before: Server becomes permanently unresponsive — no crash, no error, requires manual restart.
After: Returns JSON-RPC InvalidRequest error immediately, server stays responsive.

Root Cause

RequestIdSchema = z.union([z.string(), z.number().int()]) accepts any integer. When such an ID is used as a JavaScript Map key (in _requestResponseMap and _requestToStreamMapping), precision is lost:

const m = new Map();
m.set(9007199254740992, "value");
m.get(9007199254740992); // → undefined (precision lost!)

The server waits indefinitely for a response it can never route.

Fix

Added .refine() to RequestIdSchema to validate integer IDs against Number.MAX_SAFE_INTEGER:

z.number().int().refine((n) => Math.abs(n) <= Number.MAX_SAFE_INTEGER, {
  message: `Request ID must be a safe integer (|id| ≤ ${Number.MAX_SAFE_INTEGER})`
})

The JSON-RPC error response is returned at parse time — the server remains fully functional.

Fixes #1765.

OAuth 2.1 §3.2 requires token endpoint requests to use
application/x-www-form-urlencoded regardless of grant type.

Add an explicit header.set() call immediately before the fetch in
executeTokenRequest() to prevent any addClientAuthentication
implementation from accidentally overriding the Content-Type.

Fixes modelcontextprotocol/inspector#1160
Per JSON-RPC spec and JavaScript Map semantics, integer request IDs
must be safe integers. When a request id exceeds Number.MAX_SAFE_INTEGER,
JavaScript Map lookups silently lose precision, causing the server to
never find the matching response and hang permanently (Issue modelcontextprotocol#1765).

The fix adds a zod .refine() to RequestIdSchema that rejects any integer
with absolute value > Number.MAX_SAFE_INTEGER. The JSON-RPC error response
is returned immediately at parse time, keeping the server responsive.

Reproduction: send any JSON-RPC request with id: 9007199254740992
(MAX_SAFE_INTEGER + 1) — previously froze the server permanently.
Now: returns JSON-RPC InvalidRequest error immediately.

Fixes modelcontextprotocol#1765.
@lanxevo3 lanxevo3 requested a review from a team as a code owner March 28, 2026 19:36
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 28, 2026

⚠️ No Changeset found

Latest commit: 735b634

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 28, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1806

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1806

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1806

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1806

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1806

commit: 735b634

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.

Server hangs indefinitely when JSON-RPC request ID exceeds

1 participant