Skip to content

Commit b8cb152

Browse files
committed
feat: add url property to RequestInfo interface
1 parent b392f02 commit b8cb152

6 files changed

Lines changed: 36 additions & 8 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@modelcontextprotocol/sdk': minor
3+
---
4+
5+
Add `url` property to `RequestInfo` interface as a `URL` type, exposing the full request URL to server handlers. The URL is unified across all HTTP transports (SSE and Streamable HTTP) to always provide the complete URL including protocol, host, and path.

src/server/sse.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { randomUUID } from 'node:crypto';
22
import { IncomingMessage, ServerResponse } from 'node:http';
3+
import { TLSSocket } from 'node:tls';
34
import { Transport } from '../shared/transport.js';
45
import { JSONRPCMessage, JSONRPCMessageSchema, MessageExtraInfo, RequestInfo } from '../types.js';
56
import getRawBody from 'raw-body';
@@ -149,7 +150,15 @@ export class SSEServerTransport implements Transport {
149150
}
150151

151152
const authInfo: AuthInfo | undefined = req.auth;
152-
const requestInfo: RequestInfo = { headers: req.headers };
153+
154+
const host = req.headers.host;
155+
const protocol = req.socket instanceof TLSSocket ? 'https' : 'http';
156+
const fullUrl = host && req.url ? new URL(req.url, `${protocol}://${host}`) : undefined;
157+
158+
const requestInfo: RequestInfo = {
159+
headers: req.headers,
160+
url: fullUrl
161+
};
153162

154163
let body: string | unknown;
155164
try {

src/server/webStandardStreamableHttp.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,10 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
597597
return this.createJsonErrorResponse(415, -32000, 'Unsupported Media Type: Content-Type must be application/json');
598598
}
599599

600-
// Build request info from headers
600+
// Build request info from headers and URL
601601
const requestInfo: RequestInfo = {
602-
headers: Object.fromEntries(req.headers.entries())
602+
headers: Object.fromEntries(req.headers.entries()),
603+
url: new URL(req.url)
603604
};
604605

605606
let rawMessage;

src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,10 @@ export interface RequestInfo {
23612361
* The headers of the request.
23622362
*/
23632363
headers: IsomorphicHeaders;
2364+
/**
2365+
* The full URL of the request.
2366+
*/
2367+
url?: URL;
23642368
}
23652369

23662370
/**

test/server/sse.test.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@ const createMockResponse = () => {
1919
return res as unknown as Mocked<http.ServerResponse>;
2020
};
2121

22-
const createMockRequest = ({ headers = {}, body }: { headers?: Record<string, string>; body?: string } = {}) => {
22+
const createMockRequest = ({
23+
headers = {},
24+
body,
25+
url = '/messages'
26+
}: { headers?: Record<string, string>; body?: string; url?: string } = {}) => {
2327
const mockReq = {
2428
headers,
2529
body: body ? body : undefined,
30+
url,
2631
auth: {
2732
token: 'test-token'
2833
},
@@ -312,7 +317,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
312317
'user-agent': 'node',
313318
'accept-encoding': 'gzip, deflate',
314319
'content-length': '124'
315-
}
320+
},
321+
url: `http://127.0.0.1:${serverPort}/?sessionId=${sessionId}`
316322
})
317323
}
318324
]
@@ -387,7 +393,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
387393
id: 1
388394
});
389395
const mockReq = createMockRequest({
390-
headers: { 'content-type': 'application/json' },
396+
headers: { host: 'localhost', 'content-type': 'application/json' },
391397
body: validMessage
392398
});
393399
const mockRes = createMockResponse();
@@ -416,8 +422,10 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
416422
},
417423
requestInfo: {
418424
headers: {
425+
host: 'localhost',
419426
'content-type': 'application/json'
420-
}
427+
},
428+
url: new URL('http://localhost/messages')
421429
}
422430
}
423431
);

test/server/streamableHttp.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
443443
'user-agent': expect.any(String),
444444
'accept-encoding': expect.any(String),
445445
'content-length': expect.any(String)
446-
}
446+
},
447+
url: baseUrl.toString()
447448
});
448449
});
449450

0 commit comments

Comments
 (0)