From fa780fa85be93718f16a5f710a64bfb2ce7ec89b Mon Sep 17 00:00:00 2001 From: lanxevo3 Date: Thu, 26 Mar 2026 16:55:19 -0500 Subject: [PATCH 1/2] fix(auth): enforce form-urlencoded Content-Type for token endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- packages/client/src/client/auth.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/client/src/client/auth.ts b/packages/client/src/client/auth.ts index 1a021be18..0391e35e9 100644 --- a/packages/client/src/client/auth.ts +++ b/packages/client/src/client/auth.ts @@ -1439,6 +1439,10 @@ export async function executeTokenRequest( applyClientAuthentication(authMethod, clientInformation as OAuthClientInformation, headers, tokenRequestParams); } + // Ensure Content-Type is always form-urlencoded for the token endpoint (OAuth 2.1 §3.2). + // Some addClientAuthentication implementations may have inadvertently set a different value. + headers.set('Content-Type', 'application/x-www-form-urlencoded'); + const response = await (fetchFn ?? fetch)(tokenUrl, { method: 'POST', headers, From 735b634c2bc41f264d2b6f061f0b7029b879c2d0 Mon Sep 17 00:00:00 2001 From: lanxevo3 Date: Sat, 28 Mar 2026 14:35:45 -0500 Subject: [PATCH 2/2] fix(core): validate RequestId integers against Number.MAX_SAFE_INTEGER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 #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 #1765. --- packages/core/src/types/schemas.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/core/src/types/schemas.ts b/packages/core/src/types/schemas.ts index c8f0c9978..a8cf1d77a 100644 --- a/packages/core/src/types/schemas.ts +++ b/packages/core/src/types/schemas.ts @@ -119,8 +119,18 @@ export const ResultSchema = z.looseObject({ /** * A uniquely identifying ID for a request in JSON-RPC. - */ -export const RequestIdSchema = z.union([z.string(), z.number().int()]); + * Rejects integers outside Number.MAX_SAFE_INTEGER to prevent JavaScript + * Map/Object key precision loss that causes server hangs (Issue #1765). + */ +export const RequestIdSchema = z.union([ + z.string(), + 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})` + }) +]); /** * A request that expects a response.