From fdae89ecbfec8fda5d166277ab77398e6d3c06c9 Mon Sep 17 00:00:00 2001 From: Jerome Date: Sat, 14 Jun 2025 13:07:02 +0100 Subject: [PATCH] fix: use X-MCP-Proxy-Auth header for proxy authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed proxy authentication to use a custom header (X-MCP-Proxy-Auth) instead of the standard Authorization header. This prevents conflicts when the proxy needs to forward the client's Authorization header to upstream MCP servers. - Updated client to send proxy auth token in X-MCP-Proxy-Auth header - Updated server auth middleware to check X-MCP-Proxy-Auth header - Applies to all transport types (SSE, stdio, streamable-http) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- client/src/lib/hooks/useConnection.ts | 4 ++-- server/src/index.ts | 14 ++++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/client/src/lib/hooks/useConnection.ts b/client/src/lib/hooks/useConnection.ts index 472b391f..9c578fba 100644 --- a/client/src/lib/hooks/useConnection.ts +++ b/client/src/lib/hooks/useConnection.ts @@ -246,7 +246,7 @@ export function useConnection({ const proxyAuthToken = getMCPProxyAuthToken(config); const headers: HeadersInit = {}; if (proxyAuthToken) { - headers["Authorization"] = `Bearer ${proxyAuthToken}`; + headers["X-MCP-Proxy-Auth"] = `Bearer ${proxyAuthToken}`; } const proxyHealthResponse = await fetch(proxyHealthUrl, { headers }); const proxyHealth = await proxyHealthResponse.json(); @@ -335,7 +335,7 @@ export function useConnection({ const proxyAuthToken = getMCPProxyAuthToken(config); const proxyHeaders: HeadersInit = {}; if (proxyAuthToken) { - proxyHeaders["Authorization"] = `Bearer ${proxyAuthToken}`; + proxyHeaders["X-MCP-Proxy-Auth"] = `Bearer ${proxyAuthToken}`; } // Create appropriate transport diff --git a/server/src/index.ts b/server/src/index.ts index 9afdb1c6..38d62b71 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -138,13 +138,17 @@ const authMiddleware = ( }); }; - const authHeader = req.headers.authorization; - if (!authHeader || !authHeader.startsWith("Bearer ")) { + const authHeader = req.headers["x-mcp-proxy-auth"]; + const authHeaderValue = Array.isArray(authHeader) + ? authHeader[0] + : authHeader; + + if (!authHeaderValue || !authHeaderValue.startsWith("Bearer ")) { sendUnauthorized(); return; } - const providedToken = authHeader.substring(7); // Remove 'Bearer ' prefix + const providedToken = authHeaderValue.substring(7); // Remove 'Bearer ' prefix const expectedToken = sessionToken; // Convert to buffers for timing-safe comparison @@ -196,7 +200,9 @@ const createTransport = async (req: express.Request): Promise => { const headers = getHttpHeaders(req, transportType); - console.log(`SSE transport: url=${url}, headers=${Object.keys(headers)}`); + console.log( + `SSE transport: url=${url}, headers=${JSON.stringify(headers)}`, + ); const transport = new SSEClientTransport(new URL(url), { eventSourceInit: {