@@ -59,15 +59,11 @@ const TEST_MESSAGES ={
5959/**
6060 * Creates a POST request for the transport
6161 */
62- function createPostRequest (
63- message : JSONRPCMessage | JSONRPCMessage [ ] ,
64- sessionId ?: string ,
65- extraHeaders ?: Record < string , string >
66- ) : Request {
62+ function createPostRequest ( message : JSONRPCMessage | JSONRPCMessage [ ] , sessionId ?: string , extraHeaders ?: Record < string , string > ) : Request {
6763const headers : Record < string , string > = {
6864'Content-Type' : 'application/json' ,
69- ' Accept' : 'application/json, text/event-stream' ,
70- ' Host' : 'localhost:3000'
65+ Accept : 'application/json, text/event-stream' ,
66+ Host : 'localhost:3000'
7167} ;
7268
7369if ( sessionId ) {
@@ -92,8 +88,8 @@ function createPostRequest(
9288 */
9389function createGetRequest ( sessionId : string , extraHeaders ?: Record < string , string > ) : Request {
9490const headers : Record < string , string > = {
95- ' Accept' : 'text/event-stream' ,
96- ' Host' : 'localhost:3000' ,
91+ Accept : 'text/event-stream' ,
92+ Host : 'localhost:3000' ,
9793'mcp-session-id' : sessionId ,
9894 ...extraHeaders
9995} ;
@@ -109,7 +105,7 @@ function createGetRequest(sessionId: string, extraHeaders?: Record<string, strin
109105 */
110106function createDeleteRequest ( sessionId : string , extraHeaders ?: Record < string , string > ) : Request {
111107const headers : Record < string , string > = {
112- ' Host' : 'localhost:3000' ,
108+ Host : 'localhost:3000' ,
113109'mcp-session-id' : sessionId ,
114110 ...extraHeaders
115111} ;
@@ -303,7 +299,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
303299
304300it ( 'should pass request info to tool callback' , async ( ) => {
305301// Create a new transport with a tool that captures request info
306- let capturedHeaders : Record < string , string > | undefined ;
302+ let capturedHeaders : Record < string , string | string [ ] | undefined > | undefined ;
307303
308304const customMcpServer = new McpServer ( { name : 'test-server' , version : '1.0.0' } , { capabilities : { logging : { } } } ) ;
309305customMcpServer . tool (
@@ -416,9 +412,9 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
416412const request = new Request ( 'http://localhost:3000/mcp' , {
417413method : 'GET' ,
418414headers : {
419- ' Host' : 'localhost:3000' ,
415+ Host : 'localhost:3000' ,
420416'mcp-session-id' : sessionId ,
421- ' Accept' : 'application/json'
417+ Accept : 'application/json'
422418}
423419} ) ;
424420
@@ -431,8 +427,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
431427method : 'POST' ,
432428headers : {
433429'Content-Type' : 'application/json' ,
434- ' Host' : 'localhost:3000' ,
435- ' Accept' : 'application/json' // Missing text/event-stream
430+ Host : 'localhost:3000' ,
431+ Accept : 'application/json' // Missing text/event-stream
436432} ,
437433body : JSON . stringify ( TEST_MESSAGES . initialize )
438434} ) ;
@@ -446,8 +442,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
446442method : 'POST' ,
447443headers : {
448444'Content-Type' : 'text/plain' ,
449- ' Host' : 'localhost:3000' ,
450- ' Accept' : 'application/json, text/event-stream'
445+ Host : 'localhost:3000' ,
446+ Accept : 'application/json, text/event-stream'
451447} ,
452448body : 'not json'
453449} ) ;
@@ -490,8 +486,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
490486method : 'POST' ,
491487headers : {
492488'Content-Type' : 'application/json' ,
493- ' Host' : 'localhost:3000' ,
494- ' Accept' : 'application/json, text/event-stream'
489+ Host : 'localhost:3000' ,
490+ Accept : 'application/json, text/event-stream'
495491} ,
496492body : 'not valid json'
497493} ) ;
@@ -508,8 +504,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
508504method : 'POST' ,
509505headers : {
510506'Content-Type' : 'application/json' ,
511- ' Host' : 'localhost:3000' ,
512- ' Accept' : 'application/json, text/event-stream'
507+ Host : 'localhost:3000' ,
508+ Accept : 'application/json, text/event-stream'
513509} ,
514510body : JSON . stringify ( { invalid : 'message' } )
515511} ) ;
@@ -597,8 +593,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
597593method : 'POST' ,
598594headers : {
599595'Content-Type' : 'application/json' ,
600- ' Accept' : 'application/json, text/event-stream' ,
601- ' Host' : 'localhost:3000' ,
596+ Accept : 'application/json, text/event-stream' ,
597+ Host : 'localhost:3000' ,
602598'mcp-session-id' : sessionId
603599} ,
604600body : JSON . stringify ( TEST_MESSAGES . toolsList )
@@ -639,8 +635,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
639635const request = new Request ( 'http://localhost:3000/mcp' , {
640636method : 'GET' ,
641637headers : {
642- ' Accept' : 'text/event-stream' ,
643- ' Host' : 'localhost:3000' ,
638+ Accept : 'text/event-stream' ,
639+ Host : 'localhost:3000' ,
644640'mcp-session-id' : sessionId ,
645641'mcp-protocol-version' : '9999-99-99'
646642}
@@ -656,7 +652,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
656652const request = new Request ( 'http://localhost:3000/mcp' , {
657653method : 'DELETE' ,
658654headers : {
659- ' Host' : 'localhost:3000' ,
655+ Host : 'localhost:3000' ,
660656'mcp-session-id' : sessionId ,
661657'mcp-protocol-version' : '9999-99-99'
662658}
@@ -799,18 +795,23 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
799795storedEvents . set ( streamId , events ) ;
800796return eventId ;
801797} ,
802- replayEventsAfter : async ( streamId : StreamId , lastEventId : EventId | null , callback ) => {
803- const events = storedEvents . get ( streamId ) || [ ] ;
804- let replay = lastEventId === null ;
805-
806- for ( const event of events ) {
807- if ( replay ) {
808- await callback ( event . id , event . message ) ;
798+ replayEventsAfter : async ( lastEventId : EventId , { send } ) : Promise < StreamId > => {
799+ // Find the stream that has this eventId
800+ for ( const [ streamId , events ] of storedEvents ) {
801+ let replay = false ;
802+ for ( const event of events ) {
803+ if ( replay ) {
804+ await send ( event . id , event . message ) ;
805+ }
806+ if ( event . id === lastEventId ) {
807+ replay = true ;
808+ }
809809}
810- if ( event . id === lastEventId ) {
811- replay = true ;
810+ if ( replay ) {
811+ return streamId ;
812812}
813813}
814+ return 'unknown-stream' as StreamId ;
814815}
815816} ;
816817
@@ -915,26 +916,18 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
915916// Create a simple event store to enable closeSSEStream
916917const eventStore : EventStore = {
917918storeEvent : async ( ) => 'event-1' as EventId ,
918- replayEventsAfter : async ( ) => { }
919+ replayEventsAfter : async ( ) => 'stream-1' as StreamId
919920} ;
920921
921922const mcpServer = new McpServer ( { name : 'test-server' , version : '1.0.0' } , { capabilities : { logging : { } } } ) ;
922923
923- let closeSSEStreamFn : ( ( ) => void ) | undefined ;
924-
925- mcpServer . tool (
926- 'close-stream' ,
927- 'Closes the SSE stream' ,
928- { } ,
929- async ( _args , extra ) : Promise < CallToolResult > => {
930- closeSSEStreamFn = extra . closeSSEStream ;
931- // Call closeSSEStream after a short delay
932- setTimeout ( ( ) => {
933- extra . closeSSEStream ?.( ) ;
934- } , 50 ) ;
935- return { content : [ { type : 'text' , text : 'closing' } ] } ;
936- }
937- ) ;
924+ mcpServer . tool ( 'close-stream' , 'Closes the SSE stream' , { } , async ( _args , extra ) : Promise < CallToolResult > => {
925+ // Call closeSSEStream after a short delay
926+ setTimeout ( ( ) => {
927+ extra . closeSSEStream ?.( ) ;
928+ } , 50 ) ;
929+ return { content : [ { type : 'text' , text : 'closing' } ] } ;
930+ } ) ;
938931
939932const transport = new FetchStreamableHTTPServerTransport ( {
940933sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
@@ -976,15 +969,10 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
976969
977970let hasCloseSSEStream = false ;
978971
979- mcpServer . tool (
980- 'check-callback' ,
981- 'Checks for closeSSEStream callback' ,
982- { } ,
983- async ( _args , extra ) : Promise < CallToolResult > => {
984- hasCloseSSEStream = typeof extra . closeSSEStream === 'function' ;
985- return { content : [ { type : 'text' , text : 'checked' } ] } ;
986- }
987- ) ;
972+ mcpServer . tool ( 'check-callback' , 'Checks for closeSSEStream callback' , { } , async ( _args , extra ) : Promise < CallToolResult > => {
973+ hasCloseSSEStream = typeof extra . closeSSEStream === 'function' ;
974+ return { content : [ { type : 'text' , text : 'checked' } ] } ;
975+ } ) ;
988976
989977const transport = new FetchStreamableHTTPServerTransport ( {
990978sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
@@ -1020,15 +1008,10 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
10201008
10211009let hasCloseSSEStream = false ;
10221010
1023- mcpServer . tool (
1024- 'check-callback' ,
1025- 'Checks for closeSSEStream callback' ,
1026- { } ,
1027- async ( _args , extra ) : Promise < CallToolResult > => {
1028- hasCloseSSEStream = typeof extra . closeSSEStream === 'function' ;
1029- return { content : [ { type : 'text' , text : 'checked' } ] } ;
1030- }
1031- ) ;
1011+ mcpServer . tool ( 'check-callback' , 'Checks for closeSSEStream callback' , { } , async ( _args , extra ) : Promise < CallToolResult > => {
1012+ hasCloseSSEStream = typeof extra . closeSSEStream === 'function' ;
1013+ return { content : [ { type : 'text' , text : 'checked' } ] } ;
1014+ } ) ;
10321015
10331016const transport = new FetchStreamableHTTPServerTransport ( {
10341017sessionIdGenerator : ( ) => crypto . randomUUID ( )
@@ -1063,7 +1046,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
10631046
10641047const { transport } = await createTestTransport ( {
10651048sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
1066- onsessionclosed : ( id ) => {
1049+ onsessionclosed : id => {
10671050closedSessionId = id ;
10681051}
10691052} ) ;
@@ -1126,7 +1109,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
11261109
11271110const { transport } = await createTestTransport ( {
11281111sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
1129- onsessioninitialized : async ( id ) => {
1112+ onsessioninitialized : async id => {
11301113await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
11311114initializedSessionId = id ;
11321115}
@@ -1146,7 +1129,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
11461129
11471130const { transport } = await createTestTransport ( {
11481131sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
1149- onsessioninitialized : ( id ) => {
1132+ onsessioninitialized : id => {
11501133initializedSessionId = id ;
11511134}
11521135} ) ;
@@ -1165,7 +1148,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
11651148
11661149const { transport } = await createTestTransport ( {
11671150sessionIdGenerator : ( ) => crypto . randomUUID ( ) ,
1168- onsessionclosed : async ( id ) => {
1151+ onsessionclosed : async id => {
11691152await new Promise ( resolve => setTimeout ( resolve , 50 ) ) ;
11701153closedSessionId = id ;
11711154}
@@ -1198,8 +1181,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
11981181method : 'POST' ,
11991182headers : {
12001183'Content-Type' : 'application/json' ,
1201- ' Accept' : 'application/json, text/event-stream' ,
1202- ' Host' : 'localhost:3000'
1184+ Accept : 'application/json, text/event-stream' ,
1185+ Host : 'localhost:3000'
12031186} ,
12041187body : JSON . stringify ( TEST_MESSAGES . initialize )
12051188} ) ;
@@ -1221,8 +1204,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
12211204method : 'POST' ,
12221205headers : {
12231206'Content-Type' : 'application/json' ,
1224- ' Accept' : 'application/json, text/event-stream' ,
1225- ' Host' : 'evil.com'
1207+ Accept : 'application/json, text/event-stream' ,
1208+ Host : 'evil.com'
12261209} ,
12271210body : JSON . stringify ( TEST_MESSAGES . initialize )
12281211} ) ;
@@ -1248,8 +1231,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
12481231method : 'POST' ,
12491232headers : {
12501233'Content-Type' : 'application/json' ,
1251- ' Accept' : 'application/json, text/event-stream' ,
1252- ' Host' : 'localhost:3000'
1234+ Accept : 'application/json, text/event-stream' ,
1235+ Host : 'localhost:3000'
12531236} ,
12541237body : JSON . stringify ( TEST_MESSAGES . initialize )
12551238} ) ;
@@ -1259,8 +1242,8 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
12591242const request = new Request ( 'http://evil.com/mcp' , {
12601243method : 'GET' ,
12611244headers : {
1262- ' Accept' : 'text/event-stream' ,
1263- ' Host' : 'evil.com'
1245+ Accept : 'text/event-stream' ,
1246+ Host : 'evil.com'
12641247}
12651248} ) ;
12661249
@@ -1283,9 +1266,9 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
12831266method : 'POST' ,
12841267headers : {
12851268'Content-Type' : 'application/json' ,
1286- ' Accept' : 'application/json, text/event-stream' ,
1287- ' Host' : 'localhost:3000' ,
1288- ' Origin' : 'http://localhost:3000'
1269+ Accept : 'application/json, text/event-stream' ,
1270+ Host : 'localhost:3000' ,
1271+ Origin : 'http://localhost:3000'
12891272} ,
12901273body : JSON . stringify ( TEST_MESSAGES . initialize )
12911274} ) ;
@@ -1307,9 +1290,9 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
13071290method : 'POST' ,
13081291headers : {
13091292'Content-Type' : 'application/json' ,
1310- ' Accept' : 'application/json, text/event-stream' ,
1311- ' Host' : 'localhost:3000' ,
1312- ' Origin' : 'http://evil.com'
1293+ Accept : 'application/json, text/event-stream' ,
1294+ Host : 'localhost:3000' ,
1295+ Origin : 'http://evil.com'
13131296} ,
13141297body : JSON . stringify ( TEST_MESSAGES . initialize )
13151298} ) ;
@@ -1337,9 +1320,9 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
13371320method : 'POST' ,
13381321headers : {
13391322'Content-Type' : 'application/json' ,
1340- ' Accept' : 'application/json, text/event-stream' ,
1341- ' Host' : 'evil.com' ,
1342- ' Origin' : 'http://evil.com'
1323+ Accept : 'application/json, text/event-stream' ,
1324+ Host : 'evil.com' ,
1325+ Origin : 'http://evil.com'
13431326} ,
13441327body : JSON . stringify ( TEST_MESSAGES . initialize )
13451328} ) ;
@@ -1365,9 +1348,9 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
13651348method : 'POST' ,
13661349headers : {
13671350'Content-Type' : 'application/json' ,
1368- ' Accept' : 'application/json, text/event-stream' ,
1369- ' Host' : 'localhost:3000' ,
1370- ' Origin' : 'http://evil.com'
1351+ Accept : 'application/json, text/event-stream' ,
1352+ Host : 'localhost:3000' ,
1353+ Origin : 'http://evil.com'
13711354} ,
13721355body : JSON . stringify ( TEST_MESSAGES . initialize )
13731356} ) ;
@@ -1382,9 +1365,9 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
13821365method : 'POST' ,
13831366headers : {
13841367'Content-Type' : 'application/json' ,
1385- ' Accept' : 'application/json, text/event-stream' ,
1386- ' Host' : 'localhost:3000' ,
1387- ' Origin' : 'http://localhost:3000'
1368+ Accept : 'application/json, text/event-stream' ,
1369+ Host : 'localhost:3000' ,
1370+ Origin : 'http://localhost:3000'
13881371} ,
13891372body : JSON . stringify ( TEST_MESSAGES . initialize )
13901373} ) ;
@@ -1517,7 +1500,7 @@ describe.each(zodTestMatrix)('$zodVersionLabel', (entry: ZodMatrixEntry) =>{
15171500const sessionStore = createInMemorySessionStore ( ) ;
15181501
15191502// First, initialize using one transport instance
1520- const { transport : transport1 , mcpServer : mcpServer1 } = await createTestTransport ( {
1503+ const { transport : transport1 } = await createTestTransport ( {
15211504sessionIdGenerator : ( ) => 'serverless-session-123' ,
15221505 sessionStore
15231506} ) ;
0 commit comments