You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor: Modify /mcp endpoint for concurrent session handling
The /mcp endpoint in src/sse.ts has been updated to dynamically create and manage StreamableHTTPServerTransport instances for each client session. This allows the /mcp endpoint to handle concurrent connections with independent session IDs, similar to the /sse endpoint. Each new transport instance now uses its own sessionId generated via crypto.randomUUID() and updates an internal map accordingly. Error and close handlers are also set up for each dynamic transport.
Copy file name to clipboardExpand all lines: config.yaml
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,5 @@
1
1
name: "MCP Proxy Server"
2
-
version: "0.3.1"
2
+
version: "0.3.2"
3
3
slug: "mcp_proxy_server"
4
4
description: "A central hub for Model Context Protocol (MCP) servers. Manages multiple backend MCP servers (Stdio/SSE), exposing their combined tools and resources via a unified SSE interface or as a Stdio server. Features Web UI for server/tool management, real-time installation monitoring, and optional web terminal."
console.warn(`[${clientId}] /mcp: Discrepancy! sdkGeneratedSessionId (${sdkGeneratedSessionId}) vs transport.sessionId (${capturedHttpTransportInstance.sessionId}). Using sdkGeneratedSessionId.`);
699
+
}
700
+
constfinalSessionId=sdkGeneratedSessionId;// Use the ID from the callback
console.log(`[${clientId}] /mcp: Transport map updated. Temp ID '${tempGeneratedIdForEarlyMap}' replaced with final '${finalSessionId}'. Active: ${streamableHttpTransports.size}`);
711
+
}else{
712
+
console.error(`[${clientId}] /mcp: Mismatch during onsessioninitialized! Temp ID ${tempGeneratedIdForEarlyMap} found but instance differs.`);
console.log(`[${clientId}] /mcp: Transport (re)added to map with final ID '${finalSessionId}' (temp not found or instance check). Active: ${streamableHttpTransports.size}`);
725
+
}
726
+
}
727
+
}else{
728
+
console.error(`[${clientId}] /mcp: onsessioninitialized called but capturedHttpTransportInstance is null. SDK SessionId: ${sdkGeneratedSessionId}`);
console.log(`[${clientId}] /mcp: New transport created. Stored with temp ID: ${tempGeneratedIdForEarlyMap}. Active transports: ${streamableHttpTransports.size}`);
740
+
741
+
constcurrentTransportForHandlers=httpTransport;// Use this specific instance in handlers
console.log(`[${clientId}] /mcp: Transport for session related to ${idToClean} removed on close. Active: ${streamableHttpTransports.size}`);
767
+
};
768
+
769
+
try{
770
+
awaitserver.connect(currentTransportForHandlers);
771
+
console.log(`[${clientId}] /mcp: New transport (temp ID: ${transportSessionIdToUse}, awaiting final SDK sessionId) connected to server.`);
772
+
}catch(connectError: any){
773
+
console.error(`[${clientId}] /mcp: Failed to connect new transport to server:`,connectError);
774
+
streamableHttpTransports.delete(tempGeneratedIdForEarlyMap);// Clean up temp entry
775
+
if(!res.headersSent){
776
+
res.status(500).json({
777
+
jsonrpc: "2.0",
778
+
error: {code: -32001,message: `Failed to connect new MCP transport: ${connectError.message}`},
779
+
id: (req.bodyasany)?.id??null
780
+
});
781
+
}
782
+
return;
783
+
}
784
+
}
702
785
703
786
if(!httpTransport){
704
-
console.error(`[${clientId}] FATAL: Main StreamableHTTPServerTransport for /mcp not found during request! This should have been initialized at startup.`);
787
+
// This case should ideally be caught earlier if clientProvidedSessionId was present but not found.
788
+
// If it's a new session and httpTransport somehow didn't get created.
789
+
console.error(`[${clientId}] /mcp: Transport is unexpectedly undefined before handling request.`);
705
790
if(!res.headersSent){
706
-
res.status(500).send("MCP transport not available");
791
+
res.status(500).json({
792
+
jsonrpc: "2.0",
793
+
error: {code: -32002,message: "MCP transport not available for session."},
794
+
id: (req.bodyasany)?.id??null
795
+
});
707
796
}
708
797
return;
709
798
}
710
-
711
-
// The mainHttpTransport's onmessage, onerror, onclose are already set up during startup
712
-
// and connected to the main 'server' instance.
713
-
// We don't need to (and shouldn't) override them here.
714
799
715
-
console.log(`[${clientId}] About to call mainHttpTransport.handleRequest for ${req.method}${req.originalUrl}`);
800
+
console.log(`[${clientId}] /mcp: About to call transport.handleRequest for session ${transportSessionIdToUse||httpTransport.sessionId} - Method: ${req.method}`);
716
801
try{
717
-
// Handle the incoming HTTP request using the pre-configured mainHttpTransport.
718
-
// This will parse the body and, if successful, trigger the mainHttpTransport.onmessage
719
-
// (which is our wrapper that calls the Server instance's handler).
// The response stream (res) is now managed by httpTransport.
723
-
// It will send SSE events (or a direct JSON if it were configured for it)
724
-
// and will end the response when appropriate.
725
-
console.log(`[${clientId}] mainHttpTransport.handleRequest completed for ${req.method}${req.originalUrl}. Response stream is now managed by the transport.`);
726
-
802
+
// The SDK's StreamableHTTPServerTransport.handleRequest should:
803
+
// - For new sessions (e.g., on InitializeRequest), establish the session,
804
+
// generate/obtain a session ID, and ensure Mcp-Session-Id header is in the response.
805
+
// - For existing sessions, use the provided Mcp-Session-Id.
806
+
// - Handle both POST (for client messages) and GET (for server-initiated SSE streams).
0 commit comments