Skip to content

Commit 64a60c4

Browse files
authored
Merge pull request #571 from garciasdos/main
fix: extra headers when they are a Headers object
2 parents 99c7528 + 28e2efa commit 64a60c4

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

src/client/streamableHttp.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,37 @@ describe("StreamableHTTPClientTransport", () => {
476476
expect(global.fetch).toHaveBeenCalledTimes(2);
477477
});
478478

479+
it("should always send specified custom headers (Headers class)", async () => {
480+
const requestInit = {
481+
headers: new Headers({
482+
"X-Custom-Header": "CustomValue"
483+
})
484+
};
485+
transport = new StreamableHTTPClientTransport(new URL("http://localhost:1234/mcp"), {
486+
requestInit: requestInit
487+
});
488+
489+
let actualReqInit: RequestInit = {};
490+
491+
((global.fetch as jest.Mock)).mockImplementation(
492+
async (_url, reqInit) => {
493+
actualReqInit = reqInit;
494+
return new Response(null, { status: 200, headers: { "content-type": "text/event-stream" } });
495+
}
496+
);
497+
498+
await transport.start();
499+
500+
await transport["_startOrAuthSse"]({});
501+
expect((actualReqInit.headers as Headers).get("x-custom-header")).toBe("CustomValue");
502+
503+
(requestInit.headers as Headers).set("X-Custom-Header","SecondCustomValue");
504+
505+
await transport.send({ jsonrpc: "2.0", method: "test", params: {} } as JSONRPCMessage);
506+
expect((actualReqInit.headers as Headers).get("x-custom-header")).toBe("SecondCustomValue");
507+
508+
expect(global.fetch).toHaveBeenCalledTimes(2);
509+
});
479510

480511
it("should have exponential backoff with configurable maxRetries", () => {
481512
// This test verifies the maxRetries and backoff calculation directly

src/client/streamableHttp.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,12 @@ export class StreamableHTTPClientTransport implements Transport {
178178
headers["mcp-protocol-version"] = this._protocolVersion;
179179
}
180180

181-
return new Headers(
182-
{ ...headers, ...this._requestInit?.headers }
183-
);
181+
const extraHeaders = this._normalizeHeaders(this._requestInit?.headers);
182+
183+
return new Headers({
184+
...headers,
185+
...extraHeaders,
186+
});
184187
}
185188

186189

@@ -246,6 +249,20 @@ export class StreamableHTTPClientTransport implements Transport {
246249

247250
}
248251

252+
private _normalizeHeaders(headers: HeadersInit | undefined): Record<string, string> {
253+
if (!headers) return {};
254+
255+
if (headers instanceof Headers) {
256+
return Object.fromEntries(headers.entries());
257+
}
258+
259+
if (Array.isArray(headers)) {
260+
return Object.fromEntries(headers);
261+
}
262+
263+
return { ...headers as Record<string, string> };
264+
}
265+
249266
/**
250267
* Schedule a reconnection attempt with exponential backoff
251268
*

0 commit comments

Comments
 (0)