diff --git a/.changeset/add-url-to-request-info.md b/.changeset/add-url-to-request-info.md new file mode 100644 index 000000000..b3851fdce --- /dev/null +++ b/.changeset/add-url-to-request-info.md @@ -0,0 +1,5 @@ +--- +'@modelcontextprotocol/sdk': minor +--- + +Add `url` property to `RequestInfo` interface, exposing the request URL to server handlers diff --git a/src/server/sse.ts b/src/server/sse.ts index b7450a09e..c7048a020 100644 --- a/src/server/sse.ts +++ b/src/server/sse.ts @@ -149,7 +149,10 @@ export class SSEServerTransport implements Transport { } const authInfo: AuthInfo | undefined = req.auth; - const requestInfo: RequestInfo = { headers: req.headers }; + const requestInfo: RequestInfo = { + headers: req.headers, + url: req.url + }; let body: string | unknown; try { diff --git a/src/server/webStandardStreamableHttp.ts b/src/server/webStandardStreamableHttp.ts index 3ae9846c2..08793b7a3 100644 --- a/src/server/webStandardStreamableHttp.ts +++ b/src/server/webStandardStreamableHttp.ts @@ -597,9 +597,10 @@ export class WebStandardStreamableHTTPServerTransport implements Transport { return this.createJsonErrorResponse(415, -32000, 'Unsupported Media Type: Content-Type must be application/json'); } - // Build request info from headers + // Build request info from headers and URL const requestInfo: RequestInfo = { - headers: Object.fromEntries(req.headers.entries()) + headers: Object.fromEntries(req.headers.entries()), + url: req.url }; let rawMessage; diff --git a/src/types.ts b/src/types.ts index 6bec5190c..3c034d0ca 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2361,6 +2361,10 @@ export interface RequestInfo { * The headers of the request. */ headers: IsomorphicHeaders; + /** + * The URL of the request. + */ + url?: string; } /** diff --git a/test/server/sse.test.ts b/test/server/sse.test.ts index 4686f2ba9..00ce242e1 100644 --- a/test/server/sse.test.ts +++ b/test/server/sse.test.ts @@ -19,10 +19,15 @@ const createMockResponse = () => { return res as unknown as Mocked; }; -const createMockRequest = ({ headers = {}, body }: { headers?: Record; body?: string } = {}) => { +const createMockRequest = ({ + headers = {}, + body, + url = '/messages' +}: { headers?: Record; body?: string; url?: string } = {}) => { const mockReq = { headers, body: body ? body : undefined, + url, auth: { token: 'test-token' }, @@ -312,7 +317,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => { 'user-agent': 'node', 'accept-encoding': 'gzip, deflate', 'content-length': '124' - } + }, + url: `/?sessionId=${sessionId}` }) } ] @@ -417,7 +423,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => { requestInfo: { headers: { 'content-type': 'application/json' - } + }, + url: '/messages' } } ); diff --git a/test/server/streamableHttp.test.ts b/test/server/streamableHttp.test.ts index 36a12ca9c..38da8e8af 100644 --- a/test/server/streamableHttp.test.ts +++ b/test/server/streamableHttp.test.ts @@ -443,7 +443,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => { 'user-agent': expect.any(String), 'accept-encoding': expect.any(String), 'content-length': expect.any(String) - } + }, + url: baseUrl.toString() }); });