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 65daa4383443f32d1046103c9284119bd01484a3 Mon Sep 17 00:00:00 2001 From: lanxevo3 Date: Sat, 28 Mar 2026 11:14:43 -0500 Subject: [PATCH 2/2] fix(server): add relatedRequestId option to sendToolListChanged/sendResourceListChanged/sendPromptListChanged Enables stateless MCP servers to deliver list-change notifications inline via the POST SSE response stream, instead of silently dropping them when no GET SSE channel is open. Fixes #1771. --- packages/server/src/server/mcp.ts | 13 +++++++------ packages/server/src/server/server.ts | 12 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/server/src/server/mcp.ts b/packages/server/src/server/mcp.ts index 4d9f81c50..db0fb73d5 100644 --- a/packages/server/src/server/mcp.ts +++ b/packages/server/src/server/mcp.ts @@ -13,6 +13,7 @@ import type { ListResourcesResult, ListToolsResult, LoggingMessageNotification, + NotificationOptions, Prompt, PromptReference, ReadResourceResult, @@ -973,27 +974,27 @@ export class McpServer { /** * Sends a resource list changed event to the client, if connected. */ - sendResourceListChanged() { + sendResourceListChanged(options?: NotificationOptions) { if (this.isConnected()) { - this.server.sendResourceListChanged(); + this.server.sendResourceListChanged(options); } } /** * Sends a tool list changed event to the client, if connected. */ - sendToolListChanged() { + sendToolListChanged(options?: NotificationOptions) { if (this.isConnected()) { - this.server.sendToolListChanged(); + this.server.sendToolListChanged(options); } } /** * Sends a prompt list changed event to the client, if connected. */ - sendPromptListChanged() { + sendPromptListChanged(options?: NotificationOptions) { if (this.isConnected()) { - this.server.sendPromptListChanged(); + this.server.sendPromptListChanged(options); } } } diff --git a/packages/server/src/server/server.ts b/packages/server/src/server/server.ts index f1a1851f4..102894c3a 100644 --- a/packages/server/src/server/server.ts +++ b/packages/server/src/server/server.ts @@ -660,17 +660,17 @@ export class Server extends Protocol { }); } - async sendResourceListChanged() { + async sendResourceListChanged(options?: NotificationOptions) { return this.notification({ method: 'notifications/resources/list_changed' - }); + }, options); } - async sendToolListChanged() { - return this.notification({ method: 'notifications/tools/list_changed' }); + async sendToolListChanged(options?: NotificationOptions) { + return this.notification({ method: 'notifications/tools/list_changed' }, options); } - async sendPromptListChanged() { - return this.notification({ method: 'notifications/prompts/list_changed' }); + async sendPromptListChanged(options?: NotificationOptions) { + return this.notification({ method: 'notifications/prompts/list_changed' }, options); } }