Skip to content

Commit 2f420c4

Browse files
committed
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.
1 parent 1896f20 commit 2f420c4

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

server/src/index.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,31 @@ const getHttpHeaders = (req: express.Request): Record<string, string> => {
9393
return headers;
9494
};
9595

96+
/**
97+
* Updates a headers object in-place, preserving the original Accept header.
98+
* This is necessary to ensure that transports holding a reference to the headers
99+
* object see the updates.
100+
* @param currentHeaders The headers object to update.
101+
* @param newHeaders The new headers to apply.
102+
*/
103+
const updateHeadersInPlace = (
104+
currentHeaders: Record<string, string>,
105+
newHeaders: Record<string, string>,
106+
) => {
107+
// Preserve the Accept header, which is set at transport creation and
108+
// is not present in subsequent client requests.
109+
const accept = currentHeaders["Accept"];
110+
111+
// Clear the old headers and apply the new ones.
112+
Object.keys(currentHeaders).forEach((key) => delete currentHeaders[key]);
113+
Object.assign(currentHeaders, newHeaders);
114+
115+
// Restore the Accept header.
116+
if (accept) {
117+
currentHeaders["Accept"] = accept;
118+
}
119+
};
120+
96121
const app = express();
97122
app.use(cors());
98123
app.use((req, res, next) => {
@@ -292,7 +317,10 @@ app.get(
292317

293318
const headerHolder = sessionHeaderHolders.get(sessionId);
294319
if (headerHolder) {
295-
headerHolder.headers = getHttpHeaders(req);
320+
updateHeadersInPlace(
321+
headerHolder.headers as Record<string, string>,
322+
getHttpHeaders(req),
323+
);
296324
}
297325

298326
try {
@@ -323,7 +351,10 @@ app.post(
323351
console.log(`Received POST message for sessionId ${sessionId}`);
324352
const headerHolder = sessionHeaderHolders.get(sessionId);
325353
if (headerHolder) {
326-
headerHolder.headers = getHttpHeaders(req);
354+
updateHeadersInPlace(
355+
headerHolder.headers as Record<string, string>,
356+
getHttpHeaders(req),
357+
);
327358
}
328359

329360
try {
@@ -598,7 +629,10 @@ app.post(
598629

599630
const headerHolder = sessionHeaderHolders.get(sessionId);
600631
if (headerHolder) {
601-
headerHolder.headers = getHttpHeaders(req);
632+
updateHeadersInPlace(
633+
headerHolder.headers as Record<string, string>,
634+
getHttpHeaders(req),
635+
);
602636
}
603637

604638
const transport = webAppTransports.get(sessionId) as SSEServerTransport;

0 commit comments

Comments
 (0)