Include requestInit options in GET SSE stream request (#1592)

Co-authored-by: De Wildt van Reenen <dewildt@labs.epiuse.com>
Co-authored-by: Matt <77928207+mattzcarey@users.noreply.github.com>
Co-authored-by: Felix Weinberger <3823880+felixweinberger@users.noreply.github.com>
This commit is contained in:
bhosmer-ant 2026-03-09 14:05:30 -04:00 • committed by GitHub
commit ad4b2f9cac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 0 deletions

View file

@ -222,6 +222,7 @@ export class StreamableHTTPClientTransport implements Transport {
}
const response = await (this._fetch ?? fetch)(this._url, {
...this._requestInit,
method: 'GET',
headers,
signal: this._abortController?.signal

View file

@ -425,6 +425,34 @@ describe('StreamableHTTPClientTransport', () => {
expect(headers.get('last-event-id')).toBe('test-event-id');
});
it('should include requestInit options (credentials, mode, etc.) in GET SSE request', async () => {
// Regression test for #895: POST and DELETE requests spread _requestInit but the
// GET SSE request did not, so non-header options like credentials were dropped.
vi.clearAllMocks();
transport = new StreamableHTTPClientTransport(new URL('http://localhost:1234/mcp'), {
requestInit: { credentials: 'include', mode: 'cors' }
});
const fetchSpy = globalThis.fetch as Mock;
fetchSpy.mockReset();
fetchSpy.mockResolvedValue({
ok: true,
status: 200,
headers: new Headers({ 'content-type': 'text/event-stream' }),
body: new ReadableStream()
});
await transport.start();
await (transport as unknown as { _startOrAuthSse: (opts: StartSSEOptions) => Promise<void> })._startOrAuthSse({});
expect(fetchSpy).toHaveBeenCalled();
const init = fetchSpy.mock.calls[0]![1];
expect(init.method).toBe('GET');
expect(init.credentials).toBe('include');
expect(init.mode).toBe('cors');
});
it('should throw error when invalid content-type is received', async () => {
// Clear any previous state from other tests
vi.clearAllMocks();