Skip to content

Commit 51707c4

Browse files
committed
fix: return 404 for invalid MCP session IDs in examples
1 parent f82c997 commit 51707c4

File tree

7 files changed

+164
-42
lines changed

7 files changed

+164
-42
lines changed

examples/server/src/elicitationFormExample.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,21 @@ async function main() {
332332

333333
try {
334334
let transport: StreamableHTTPServerTransport;
335-
if (sessionId && transports[sessionId]) {
336-
// Reuse existing transport for this session
337-
transport = transports[sessionId];
335+
if (sessionId) {
336+
if (transports[sessionId]) {
337+
// Reuse existing transport for this session
338+
transport = transports[sessionId];
339+
} else {
340+
res.status(404).json({
341+
jsonrpc: '2.0',
342+
error: {
343+
code: -32000,
344+
message: 'Not Found: Invalid session ID'
345+
},
346+
id: null
347+
});
348+
return;
349+
}
338350
} else if (!sessionId && isInitializeRequest(req.body)) {
339351
// New initialization request - create new transport
340352
transport = new StreamableHTTPServerTransport({
@@ -366,7 +378,7 @@ async function main() {
366378
jsonrpc: '2.0',
367379
error: {
368380
code: -32000,
369-
message: 'Bad Request: No valid session ID provided'
381+
message: 'Bad Request: No session ID provided'
370382
},
371383
id: null
372384
});
@@ -395,8 +407,13 @@ async function main() {
395407
// Handle GET requests for SSE streams
396408
const mcpGetHandler = async (req: Request, res: Response) => {
397409
const sessionId = req.headers['mcp-session-id'] as string | undefined;
398-
if (!sessionId || !transports[sessionId]) {
399-
res.status(400).send('Invalid or missing session ID');
410+
if (!sessionId) {
411+
res.status(400).send('Missing session ID');
412+
return;
413+
}
414+
415+
if (!transports[sessionId]) {
416+
res.status(404).send('Invalid session ID');
400417
return;
401418
}
402419

@@ -410,8 +427,13 @@ async function main() {
410427
// Handle DELETE requests for session termination
411428
const mcpDeleteHandler = async (req: Request, res: Response) => {
412429
const sessionId = req.headers['mcp-session-id'] as string | undefined;
413-
if (!sessionId || !transports[sessionId]) {
414-
res.status(400).send('Invalid or missing session ID');
430+
if (!sessionId) {
431+
res.status(400).send('Missing session ID');
432+
return;
433+
}
434+
435+
if (!transports[sessionId]) {
436+
res.status(404).send('Invalid session ID');
415437
return;
416438
}
417439

examples/server/src/elicitationUrlExample.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,21 @@ const mcpPostHandler = async (req: Request, res: Response) => {
614614

615615
try {
616616
let transport: StreamableHTTPServerTransport;
617-
if (sessionId && transports[sessionId]) {
618-
// Reuse existing transport
619-
transport = transports[sessionId];
617+
if (sessionId) {
618+
if (transports[sessionId]) {
619+
// Reuse existing transport
620+
transport = transports[sessionId];
621+
} else {
622+
res.status(404).json({
623+
jsonrpc: '2.0',
624+
error: {
625+
code: -32000,
626+
message: 'Not Found: Invalid session ID'
627+
},
628+
id: null
629+
});
630+
return;
631+
}
620632
} else if (!sessionId && isInitializeRequest(req.body)) {
621633
const server = getServer();
622634
// New initialization request
@@ -658,7 +670,7 @@ const mcpPostHandler = async (req: Request, res: Response) => {
658670
jsonrpc: '2.0',
659671
error: {
660672
code: -32000,
661-
message: 'Bad Request: No valid session ID provided'
673+
message: 'Bad Request: No session ID provided'
662674
},
663675
id: null
664676
});
@@ -689,8 +701,13 @@ app.post('/mcp', authMiddleware, mcpPostHandler);
689701
// Handle GET requests for SSE streams (using built-in support from StreamableHTTP)
690702
const mcpGetHandler = async (req: Request, res: Response) => {
691703
const sessionId = req.headers['mcp-session-id'] as string | undefined;
692-
if (!sessionId || !transports[sessionId]) {
693-
res.status(400).send('Invalid or missing session ID');
704+
if (!sessionId) {
705+
res.status(400).send('Missing session ID');
706+
return;
707+
}
708+
709+
if (!transports[sessionId]) {
710+
res.status(404).send('Invalid session ID');
694711
return;
695712
}
696713

@@ -728,8 +745,13 @@ app.get('/mcp', authMiddleware, mcpGetHandler);
728745
// Handle DELETE requests for session termination (according to MCP spec)
729746
const mcpDeleteHandler = async (req: Request, res: Response) => {
730747
const sessionId = req.headers['mcp-session-id'] as string | undefined;
731-
if (!sessionId || !transports[sessionId]) {
732-
res.status(400).send('Invalid or missing session ID');
748+
if (!sessionId) {
749+
res.status(400).send('Missing session ID');
750+
return;
751+
}
752+
753+
if (!transports[sessionId]) {
754+
res.status(404).send('Invalid session ID');
733755
return;
734756
}
735757

examples/server/src/jsonResponseStreamableHttp.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,21 @@ app.post('/mcp', async (req: Request, res: Response) => {
105105
const sessionId = req.headers['mcp-session-id'] as string | undefined;
106106
let transport: StreamableHTTPServerTransport;
107107

108-
if (sessionId && transports[sessionId]) {
109-
// Reuse existing transport
110-
transport = transports[sessionId];
108+
if (sessionId) {
109+
if (transports[sessionId]) {
110+
// Reuse existing transport
111+
transport = transports[sessionId];
112+
} else {
113+
res.status(404).json({
114+
jsonrpc: '2.0',
115+
error: {
116+
code: -32000,
117+
message: 'Not Found: Invalid session ID'
118+
},
119+
id: null
120+
});
121+
return;
122+
}
111123
} else if (!sessionId && isInitializeRequest(req.body)) {
112124
// New initialization request - use JSON response mode
113125
transport = new StreamableHTTPServerTransport({
@@ -132,7 +144,7 @@ app.post('/mcp', async (req: Request, res: Response) => {
132144
jsonrpc: '2.0',
133145
error: {
134146
code: -32000,
135-
message: 'Bad Request: No valid session ID provided'
147+
message: 'Bad Request: No session ID provided'
136148
},
137149
id: null
138150
});

examples/server/src/simpleStreamableHttp.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,9 +606,21 @@ const mcpPostHandler = async (req: Request, res: Response) => {
606606
}
607607
try {
608608
let transport: StreamableHTTPServerTransport;
609-
if (sessionId && transports[sessionId]) {
610-
// Reuse existing transport
611-
transport = transports[sessionId];
609+
if (sessionId) {
610+
if (transports[sessionId]) {
611+
// Reuse existing transport
612+
transport = transports[sessionId];
613+
} else {
614+
res.status(404).json({
615+
jsonrpc: '2.0',
616+
error: {
617+
code: -32000,
618+
message: 'Not Found: Invalid session ID'
619+
},
620+
id: null
621+
});
622+
return;
623+
}
612624
} else if (!sessionId && isInitializeRequest(req.body)) {
613625
// New initialization request
614626
const eventStore = new InMemoryEventStore();
@@ -645,7 +657,7 @@ const mcpPostHandler = async (req: Request, res: Response) => {
645657
jsonrpc: '2.0',
646658
error: {
647659
code: -32000,
648-
message: 'Bad Request: No valid session ID provided'
660+
message: 'Bad Request: No session ID provided'
649661
},
650662
id: null
651663
});
@@ -680,8 +692,13 @@ if (useOAuth && authMiddleware) {
680692
// Handle GET requests for SSE streams (using built-in support from StreamableHTTP)
681693
const mcpGetHandler = async (req: Request, res: Response) => {
682694
const sessionId = req.headers['mcp-session-id'] as string | undefined;
683-
if (!sessionId || !transports[sessionId]) {
684-
res.status(400).send('Invalid or missing session ID');
695+
if (!sessionId) {
696+
res.status(400).send('Missing session ID');
697+
return;
698+
}
699+
700+
if (!transports[sessionId]) {
701+
res.status(404).send('Invalid session ID');
685702
return;
686703
}
687704

@@ -711,8 +728,13 @@ if (useOAuth && authMiddleware) {
711728
// Handle DELETE requests for session termination (according to MCP spec)
712729
const mcpDeleteHandler = async (req: Request, res: Response) => {
713730
const sessionId = req.headers['mcp-session-id'] as string | undefined;
714-
if (!sessionId || !transports[sessionId]) {
715-
res.status(400).send('Invalid or missing session ID');
731+
if (!sessionId) {
732+
res.status(400).send('Missing session ID');
733+
return;
734+
}
735+
736+
if (!transports[sessionId]) {
737+
res.status(404).send('Invalid session ID');
716738
return;
717739
}
718740

examples/server/src/simpleTaskInteractive.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,17 @@ app.post('/mcp', async (req: Request, res: Response) => {
679679
await server.connect(transport);
680680
await transport.handleRequest(req, res, req.body);
681681
return;
682+
} else if (sessionId) {
683+
res.status(404).json({
684+
jsonrpc: '2.0',
685+
error: { code: -32000, message: 'Not Found: Invalid session ID' },
686+
id: null
687+
});
688+
return;
682689
} else {
683690
res.status(400).json({
684691
jsonrpc: '2.0',
685-
error: { code: -32000, message: 'Bad Request: No valid session ID' },
692+
error: { code: -32000, message: 'Bad Request: No session ID' },
686693
id: null
687694
});
688695
return;
@@ -704,8 +711,13 @@ app.post('/mcp', async (req: Request, res: Response) => {
704711
// Handle GET requests for SSE streams
705712
app.get('/mcp', async (req: Request, res: Response) => {
706713
const sessionId = req.headers['mcp-session-id'] as string | undefined;
707-
if (!sessionId || !transports[sessionId]) {
708-
res.status(400).send('Invalid or missing session ID');
714+
if (!sessionId) {
715+
res.status(400).send('Missing session ID');
716+
return;
717+
}
718+
719+
if (!transports[sessionId]) {
720+
res.status(404).send('Invalid session ID');
709721
return;
710722
}
711723

@@ -716,8 +728,13 @@ app.get('/mcp', async (req: Request, res: Response) => {
716728
// Handle DELETE requests for session termination
717729
app.delete('/mcp', async (req: Request, res: Response) => {
718730
const sessionId = req.headers['mcp-session-id'] as string | undefined;
719-
if (!sessionId || !transports[sessionId]) {
720-
res.status(400).send('Invalid or missing session ID');
731+
if (!sessionId) {
732+
res.status(400).send('Missing session ID');
733+
return;
734+
}
735+
736+
if (!transports[sessionId]) {
737+
res.status(404).send('Invalid session ID');
721738
return;
722739
}
723740

examples/server/src/sseAndStreamableHttpCompatibleServer.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,13 @@ app.all('/mcp', async (req: Request, res: Response) => {
9696
const sessionId = req.headers['mcp-session-id'] as string | undefined;
9797
let transport: StreamableHTTPServerTransport;
9898

99-
if (sessionId && transports[sessionId]) {
99+
if (sessionId) {
100100
// Check if the transport is of the correct type
101101
const existingTransport = transports[sessionId];
102102
if (existingTransport instanceof StreamableHTTPServerTransport) {
103103
// Reuse existing transport
104104
transport = existingTransport;
105-
} else {
105+
} else if (existingTransport) {
106106
// Transport exists but is not a StreamableHTTPServerTransport (could be SSEServerTransport)
107107
res.status(400).json({
108108
jsonrpc: '2.0',
@@ -113,6 +113,16 @@ app.all('/mcp', async (req: Request, res: Response) => {
113113
id: null
114114
});
115115
return;
116+
} else {
117+
res.status(404).json({
118+
jsonrpc: '2.0',
119+
error: {
120+
code: -32000,
121+
message: 'Not Found: Invalid session ID'
122+
},
123+
id: null
124+
});
125+
return;
116126
}
117127
} else if (!sessionId && req.method === 'POST' && isInitializeRequest(req.body)) {
118128
const eventStore = new InMemoryEventStore();
@@ -144,7 +154,7 @@ app.all('/mcp', async (req: Request, res: Response) => {
144154
jsonrpc: '2.0',
145155
error: {
146156
code: -32000,
147-
message: 'Bad Request: No valid session ID provided'
157+
message: 'Bad Request: No session ID provided'
148158
},
149159
id: null
150160
});

examples/server/src/standaloneSseWithGetStreamableHttp.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,21 @@ app.post('/mcp', async (req: Request, res: Response) => {
4343
const sessionId = req.headers['mcp-session-id'] as string | undefined;
4444
let transport: StreamableHTTPServerTransport;
4545

46-
if (sessionId && transports[sessionId]) {
47-
// Reuse existing transport
48-
transport = transports[sessionId];
46+
if (sessionId) {
47+
if (transports[sessionId]) {
48+
// Reuse existing transport
49+
transport = transports[sessionId];
50+
} else {
51+
res.status(404).json({
52+
jsonrpc: '2.0',
53+
error: {
54+
code: -32000,
55+
message: 'Not Found: Invalid session ID'
56+
},
57+
id: null
58+
});
59+
return;
60+
}
4961
} else if (!sessionId && isInitializeRequest(req.body)) {
5062
// New initialization request
5163
transport = new StreamableHTTPServerTransport({
@@ -70,7 +82,7 @@ app.post('/mcp', async (req: Request, res: Response) => {
7082
jsonrpc: '2.0',
7183
error: {
7284
code: -32000,
73-
message: 'Bad Request: No valid session ID provided'
85+
message: 'Bad Request: No session ID provided'
7486
},
7587
id: null
7688
});
@@ -97,8 +109,13 @@ app.post('/mcp', async (req: Request, res: Response) => {
97109
// Handle GET requests for SSE streams (now using built-in support from StreamableHTTP)
98110
app.get('/mcp', async (req: Request, res: Response) => {
99111
const sessionId = req.headers['mcp-session-id'] as string | undefined;
100-
if (!sessionId || !transports[sessionId]) {
101-
res.status(400).send('Invalid or missing session ID');
112+
if (!sessionId) {
113+
res.status(400).send('Missing session ID');
114+
return;
115+
}
116+
117+
if (!transports[sessionId]) {
118+
res.status(404).send('Invalid session ID');
102119
return;
103120
}
104121

0 commit comments

Comments
 (0)