Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/add-url-to-request-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@modelcontextprotocol/sdk': minor
---

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.
11 changes: 10 additions & 1 deletion src/server/sse.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { randomUUID } from 'node:crypto';
import { IncomingMessage, ServerResponse } from 'node:http';
import { TLSSocket } from 'node:tls';
import { Transport } from '../shared/transport.js';
import { JSONRPCMessage, JSONRPCMessageSchema, MessageExtraInfo, RequestInfo } from '../types.js';
import getRawBody from 'raw-body';
Expand Down Expand Up @@ -149,7 +150,15 @@ export class SSEServerTransport implements Transport {
}

const authInfo: AuthInfo | undefined = req.auth;
const requestInfo: RequestInfo = { headers: req.headers };

const host = req.headers.host;
const protocol = req.socket instanceof TLSSocket ? 'https' : 'http';
const fullUrl = host && req.url ? new URL(req.url, `${protocol}://${host}`) : undefined;

const requestInfo: RequestInfo = {
headers: req.headers,
url: fullUrl
};

let body: string | unknown;
try {
Expand Down
5 changes: 3 additions & 2 deletions src/server/webStandardStreamableHttp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: new URL(req.url)
};

let rawMessage;
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2361,6 +2361,10 @@ export interface RequestInfo {
* The headers of the request.
*/
headers: IsomorphicHeaders;
/**
* The full URL of the request.
*/
url?: URL;
}

/**
Expand Down
16 changes: 12 additions & 4 deletions test/server/sse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ const createMockResponse = () => {
return res as unknown as Mocked<http.ServerResponse>;
};

const createMockRequest = ({ headers = {}, body }: { headers?: Record<string, string>; body?: string } = {}) => {
const createMockRequest = ({
headers = {},
body,
url = '/messages'
}: { headers?: Record<string, string>; body?: string; url?: string } = {}) => {
const mockReq = {
headers,
body: body ? body : undefined,
url,
auth: {
token: 'test-token'
},
Expand Down Expand Up @@ -312,7 +317,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
'user-agent': 'node',
'accept-encoding': 'gzip, deflate',
'content-length': '124'
}
},
url: `http://127.0.0.1:${serverPort}/?sessionId=${sessionId}`
})
}
]
Expand Down Expand Up @@ -387,7 +393,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
id: 1
});
const mockReq = createMockRequest({
headers: { 'content-type': 'application/json' },
headers: { host: 'localhost', 'content-type': 'application/json' },
body: validMessage
});
const mockRes = createMockResponse();
Expand Down Expand Up @@ -416,8 +422,10 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) => {
},
requestInfo: {
headers: {
host: 'localhost',
'content-type': 'application/json'
}
},
url: new URL('http://localhost/messages')
}
}
);
Expand Down
3 changes: 2 additions & 1 deletion test/server/streamableHttp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
});
});

Expand Down
Loading