From d55f966562ee861ed4eaa703b257111ea3b95386 Mon Sep 17 00:00:00 2001 From: Chris Dickinson Date: Mon, 30 Dec 2024 18:55:57 -0800 Subject: [PATCH] feat(client/sse): add {EventSource,Request}Init options param This enables users of the SSE client to optionally send cookie-based credentials to the event source MCP server using `EventSourceInit` [1] parameters and set the outgoing request headers for the POST call. [1]: https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource#options --- src/client/sse.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/client/sse.ts b/src/client/sse.ts index e7f0dc6..0e6e7eb 100644 --- a/src/client/sse.ts +++ b/src/client/sse.ts @@ -12,13 +12,17 @@ export class SSEClientTransport implements Transport { private _endpoint?: URL; private _abortController?: AbortController; private _url: URL; + private _eventSourceInit?: EventSourceInit; + private _requestInit?: RequestInit; onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: JSONRPCMessage) => void; - constructor(url: URL) { + constructor(url: URL, opts?: { eventSourceInit?: EventSourceInit, requestInit?: RequestInit }) { this._url = url; + this._eventSourceInit = opts?.eventSourceInit; + this._requestInit = opts?.requestInit; } start(): Promise { @@ -29,7 +33,7 @@ export class SSEClientTransport implements Transport { } return new Promise((resolve, reject) => { - this._eventSource = new EventSource(this._url.href); + this._eventSource = new EventSource(this._url.href, this._eventSourceInit); this._abortController = new AbortController(); this._eventSource.onerror = (event) => { @@ -90,14 +94,17 @@ export class SSEClientTransport implements Transport { } try { - const response = await fetch(this._endpoint, { + const headers = new Headers(this._requestInit?.headers); + headers.set("content-type", "application/json"); + const init = { + ...this._requestInit, method: "POST", - headers: { - "Content-Type": "application/json", - }, + headers, body: JSON.stringify(message), - signal: this._abortController?.signal, - }); + signal: this._abortController?.signal + }; + + const response = await fetch(this._endpoint, init); if (!response.ok) { const text = await response.text().catch(() => null);