Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f29cbe7

Browse files
committed
reject session as an array
1 parent c275a0d commit f29cbe7

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

src/server/streamableHttp.ts

+32-7
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,15 @@ export class StreamableHTTPServerTransport implements Transport {
8989
} else if (req.method === "DELETE") {
9090
await this.handleDeleteRequest(req, res);
9191
} else {
92-
await this.handleUnsupportedRequest(req, res);
92+
await this.handleUnsupportedRequest(res);
9393
}
9494
}
9595

9696
/**
9797
* Handles unsupported requests (GET, PUT, PATCH, etc.)
9898
* For now we support only POST and DELETE requests. Support for GET for SSE connections will be added later.
9999
*/
100-
private async handleUnsupportedRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {
101-
100+
private async handleUnsupportedRequest(res: ServerResponse): Promise<void> {
102101
res.writeHead(405, {
103102
"Allow": "POST, DELETE"
104103
}).end(JSON.stringify({
@@ -119,8 +118,7 @@ export class StreamableHTTPServerTransport implements Transport {
119118
// Validate the Accept header
120119
const acceptHeader = req.headers.accept;
121120
// The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.
122-
if (!acceptHeader ||
123-
!acceptHeader.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
121+
if (!acceptHeader?.includes("application/json") || !acceptHeader.includes("text/event-stream")) {
124122
res.writeHead(406).end(JSON.stringify({
125123
jsonrpc: "2.0",
126124
error: {
@@ -172,6 +170,17 @@ export class StreamableHTTPServerTransport implements Transport {
172170
msg => 'method' in msg && msg.method === 'initialize'
173171
);
174172
if (isInitializationRequest) {
173+
if (messages.length > 1) {
174+
res.writeHead(400).end(JSON.stringify({
175+
jsonrpc: "2.0",
176+
error: {
177+
code: -32600,
178+
message: "Invalid Request: Only one initialization request is allowed"
179+
},
180+
id: null
181+
}));
182+
return;
183+
}
175184
const headers: Record<string, string> = {};
176185

177186
if (this._sessionId !== undefined) {
@@ -280,7 +289,18 @@ export class StreamableHTTPServerTransport implements Transport {
280289
id: null
281290
}));
282291
return false;
283-
} else if ((Array.isArray(sessionId) ? sessionId[0] : sessionId) !== this._sessionId) {
292+
} else if (Array.isArray(sessionId)) {
293+
res.writeHead(400).end(JSON.stringify({
294+
jsonrpc: "2.0",
295+
error: {
296+
code: -32000,
297+
message: "Bad Request: Mcp-Session-Id header must be a single value"
298+
},
299+
id: null
300+
}));
301+
return false;
302+
}
303+
else if (sessionId !== this._sessionId) {
284304
// Reject requests with invalid session ID with 404 Not Found
285305
res.writeHead(404).end(JSON.stringify({
286306
jsonrpc: "2.0",
@@ -331,7 +351,12 @@ export class StreamableHTTPServerTransport implements Transport {
331351
// This is a response to the original request, we can close the stream
332352
// after sending all related responses
333353
this._sseResponseMapping.delete(relatedRequestId);
334-
sseResponse.end();
354+
355+
// Only close the connection if it's not needed by other requests
356+
const canCloseConnection = ![...this._sseResponseMapping.entries()].some(([id, res]) => res === sseResponse && id !== relatedRequestId);
357+
if (canCloseConnection) {
358+
sseResponse.end();
359+
}
335360
}
336361
}
337362
}

src/shared/protocol.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ export type RequestHandlerExtra<SendRequestT extends Request,
111111
sessionId?: string;
112112

113113
/**
114-
* Sends a notification that relates to the current request being handled.
115-
*
116-
* This is used by certain transports to correctly associate related messages.
117-
*/
114+
* Sends a notification that relates to the current request being handled.
115+
*
116+
* This is used by certain transports to correctly associate related messages.
117+
*/
118118
sendNotification: (notification: SendNotificationT) => Promise<void>;
119119

120120
/**

0 commit comments

Comments
 (0)