@@ -217,7 +217,6 @@ export class StreamableHTTPServerTransport implements Transport {
217
217
218
218
// Assign the response to the standalone SSE stream
219
219
this . _streamMapping . set ( this . _standaloneSseStreamId , res ) ;
220
-
221
220
// Set up close handler for client disconnects
222
221
res . on ( "close" , ( ) => {
223
222
this . _streamMapping . delete ( this . _standaloneSseStreamId ) ;
@@ -345,8 +344,10 @@ export class StreamableHTTPServerTransport implements Transport {
345
344
const isInitializationRequest = messages . some (
346
345
msg => 'method' in msg && msg . method === 'initialize'
347
346
) ;
347
+ const mcpSessionId = req . headers [ "mcp-session-id" ] as string | undefined ;
348
348
if ( isInitializationRequest ) {
349
- if ( this . _initialized ) {
349
+ // if generateSessionId is not set, the server does not support session management
350
+ if ( this . _initialized && this . sessionId !== undefined && mcpSessionId !== this . sessionId ) {
350
351
res . writeHead ( 400 ) . end ( JSON . stringify ( {
351
352
jsonrpc : "2.0" ,
352
353
error : {
@@ -368,7 +369,7 @@ export class StreamableHTTPServerTransport implements Transport {
368
369
} ) ) ;
369
370
return ;
370
371
}
371
- this . sessionId = this . sessionIdGenerator ( ) ;
372
+ this . sessionId = mcpSessionId ?? this . sessionIdGenerator ( ) ;
372
373
this . _initialized = true ;
373
374
374
375
}
@@ -419,17 +420,8 @@ export class StreamableHTTPServerTransport implements Transport {
419
420
this . _requestToStreamMapping . set ( message . id , streamId ) ;
420
421
}
421
422
}
422
-
423
423
// Set up close handler for client disconnects
424
424
res . on ( "close" , ( ) => {
425
- // find a stream ID for this response
426
- // Remove all entries that reference this response
427
- for ( const [ id , stream ] of this . _requestToStreamMapping . entries ( ) ) {
428
- if ( streamId === stream ) {
429
- this . _requestToStreamMapping . delete ( id ) ;
430
- this . _requestResponseMap . delete ( id ) ;
431
- }
432
- }
433
425
this . _streamMapping . delete ( streamId ) ;
434
426
} ) ;
435
427
@@ -577,7 +569,7 @@ export class StreamableHTTPServerTransport implements Transport {
577
569
// Get the response for this request
578
570
const streamId = this . _requestToStreamMapping . get ( requestId ) ;
579
571
const response = this . _streamMapping . get ( streamId ! ) ;
580
- if ( ! streamId || ! response ) {
572
+ if ( ! streamId ) {
581
573
throw new Error ( `No connection established for request ID: ${ String ( requestId ) } ` ) ;
582
574
}
583
575
@@ -588,9 +580,10 @@ export class StreamableHTTPServerTransport implements Transport {
588
580
if ( this . _eventStore ) {
589
581
eventId = await this . _eventStore . storeEvent ( streamId , message ) ;
590
582
}
591
-
592
- // Write the event to the response stream
593
- this . writeSSEEvent ( response , message , eventId ) ;
583
+ if ( response ) {
584
+ // Write the event to the response stream
585
+ this . writeSSEEvent ( response , message , eventId ) ;
586
+ }
594
587
}
595
588
596
589
if ( isJSONRPCResponse ( message ) ) {
@@ -603,6 +596,9 @@ export class StreamableHTTPServerTransport implements Transport {
603
596
const allResponsesReady = relatedIds . every ( id => this . _requestResponseMap . has ( id ) ) ;
604
597
605
598
if ( allResponsesReady ) {
599
+ if ( ! response ) {
600
+ throw new Error ( `No connection established for request ID: ${ String ( requestId ) } ` ) ;
601
+ }
606
602
if ( this . _enableJsonResponse ) {
607
603
// All responses ready, send as JSON
608
604
const headers : Record < string , string > = {
0 commit comments