From c6d2d8aeb3b49bb26b9de36c2e61b7ef1f9bbea7 Mon Sep 17 00:00:00 2001 From: De Wildt van Reenen Date: Thu, 21 Aug 2025 22:12:05 -0400 Subject: [PATCH] fix: client initial GET sse include requestInit (modelcontextprotocol#895) --- src/client/streamableHttp.test.ts | 24 ++++++++++++++++++++++++ src/client/streamableHttp.ts | 7 ++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/client/streamableHttp.test.ts b/src/client/streamableHttp.test.ts index fdd35ed3f..bc8d5fd42 100644 --- a/src/client/streamableHttp.test.ts +++ b/src/client/streamableHttp.test.ts @@ -502,6 +502,30 @@ describe("StreamableHTTPClientTransport", () => { expect(global.fetch).toHaveBeenCalledTimes(2); }); + it("should always include requestInit options for initial connection in SSE", async () => { + const requestInit: RequestInit = { + credentials: 'include' + }; + + transport = new StreamableHTTPClientTransport(new URL("http://localhost:1234/mcp"), { + requestInit: requestInit + }); + + let actualReqInit: RequestInit = {}; + + ((global.fetch as jest.Mock)).mockImplementation( + async (_url, reqInit) => { + actualReqInit = reqInit; + return new Response(null, { status: 200, headers: { "content-type": "text/event-stream" } }); + } + ); + + await transport.start(); + + await transport["_startOrAuthSse"]({}); + expect(actualReqInit.credentials).toBe("include"); + }); + it("should always send specified custom headers (Headers class)", async () => { const requestInit = { headers: new Headers({ diff --git a/src/client/streamableHttp.ts b/src/client/streamableHttp.ts index 12714ea44..7872f2443 100644 --- a/src/client/streamableHttp.ts +++ b/src/client/streamableHttp.ts @@ -208,6 +208,7 @@ export class StreamableHTTPClientTransport implements Transport { } const response = await (this._fetch ?? fetch)(this._url, { + ...this._requestInit, method: "GET", headers, signal: this._abortController?.signal, @@ -301,7 +302,7 @@ export class StreamableHTTPClientTransport implements Transport { } private _handleSseStream( - stream: ReadableStream | null, + stream: ReadableStream | null, options: StartSSEOptions, isReconnectable: boolean, ): void { @@ -352,8 +353,8 @@ export class StreamableHTTPClientTransport implements Transport { // Attempt to reconnect if the stream disconnects unexpectedly and we aren't closing if ( - isReconnectable && - this._abortController && + isReconnectable && + this._abortController && !this._abortController.signal.aborted ) { // Use the exponential backoff reconnection strategy