From 2f420c4edf8edd43b9fecae82be24fae72162545 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Sat, 6 Sep 2025 15:51:43 -0400 Subject: [PATCH] A new `updateHeadersInPlace` function *mutates* the original header object instead of replacing it. This ensures that transports holding a static reference, like `SSEClientTransport`, always see the latest headers. * In `src/server/index.ts`, - Added `updateHeadersInPlace` helper function to solve the stale header reference issue in `SSEClientTransport`. It mutates the header object in-place, ensuring the transport sees all updates, while carefully preserving the original `Accept` header required by the transport. - in `/mcp GET`, `/mcp POST`, and `/message POST`, use `updateHeadersInPlace` to replace current headers with new headers, retaining the Accept header. --- server/src/index.ts | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/server/src/index.ts b/server/src/index.ts index 5d28acca..3f739f39 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -93,6 +93,31 @@ const getHttpHeaders = (req: express.Request): Record => { return headers; }; +/** + * Updates a headers object in-place, preserving the original Accept header. + * This is necessary to ensure that transports holding a reference to the headers + * object see the updates. + * @param currentHeaders The headers object to update. + * @param newHeaders The new headers to apply. + */ +const updateHeadersInPlace = ( + currentHeaders: Record, + newHeaders: Record, +) => { + // Preserve the Accept header, which is set at transport creation and + // is not present in subsequent client requests. + const accept = currentHeaders["Accept"]; + + // Clear the old headers and apply the new ones. + Object.keys(currentHeaders).forEach((key) => delete currentHeaders[key]); + Object.assign(currentHeaders, newHeaders); + + // Restore the Accept header. + if (accept) { + currentHeaders["Accept"] = accept; + } +}; + const app = express(); app.use(cors()); app.use((req, res, next) => { @@ -292,7 +317,10 @@ app.get( const headerHolder = sessionHeaderHolders.get(sessionId); if (headerHolder) { - headerHolder.headers = getHttpHeaders(req); + updateHeadersInPlace( + headerHolder.headers as Record, + getHttpHeaders(req), + ); } try { @@ -323,7 +351,10 @@ app.post( console.log(`Received POST message for sessionId ${sessionId}`); const headerHolder = sessionHeaderHolders.get(sessionId); if (headerHolder) { - headerHolder.headers = getHttpHeaders(req); + updateHeadersInPlace( + headerHolder.headers as Record, + getHttpHeaders(req), + ); } try { @@ -598,7 +629,10 @@ app.post( const headerHolder = sessionHeaderHolders.get(sessionId); if (headerHolder) { - headerHolder.headers = getHttpHeaders(req); + updateHeadersInPlace( + headerHolder.headers as Record, + getHttpHeaders(req), + ); } const transport = webAppTransports.get(sessionId) as SSEServerTransport;