-
Notifications
You must be signed in to change notification settings - Fork 10
Open
Description
Simply put, to have multiple clients (CLI, GUI interface, multiple agents) interact with the server can't be done with the stdio transport architecture.
Here's a breakdown of how the MCP SDK interacts with different communication methods (transports):
- Transport Determines Multiplicity: The standard input/output streams of a process are inherently single-channel.
- StdioClientTransport is designed to spawn a dedicated server process for a single client.
- StdioServerTransport listens on the current process's stdio, again implying a single connected client for that specific server process.
- Therefore, the stdio transports are designed for a 1:1 client-server relationship.
- Network Transports (SSE/WebSocket): These are fundamentally different and are designed for multiple clients connecting to a single server endpoint.
- SSE ( SSEServerTransport ): The SDK explicitly supports multiple clients via SSE.
- The SSEServerTransport is created per incoming HTTP connection (the GET request that establishes the event stream).
- It generates a unique sessionId.
- The server needs to manage these multiple SSEServerTransport instances, typically keyed by their sessionId.
- When the client sends messages via POST , the sessionId (usually passed as a query parameter, as shown in the example cli.ts and server/sse.ts in the Typescript SDK repo) is used to route the incoming message to the correct SSEServerTransport instance using its handlePostMessage method.
- You would typically create a new Server instance and connect it to the newly created SSEServerTransport for each incoming client connection. The README.md and cli.ts examples demonstrate this pattern.
- WebSocket ( WebSocketClientTransport ): The SDK provides a WebSocketClientTransport , but it does not currently provide a built-in WebSocketServerTransport.
- To support multiple WebSocket clients, you would need to use a standard WebSocket server library (like ws for Node.js).
- For each incoming WebSocket connection, you would likely:
- Create a custom Transport implementation that wraps the WebSocket connection, piping messages back and forth.
- Instantiate a new Server instance.
- Connect the Server instance to your custom WebSocket transport wrapper using server.connect().
- This allows a single network endpoint (your WebSocket server) to accept connections from multiple clients, with each connection being managed by its own Server and Transport instance pair on the server-side.
One major downside of SSEServerTransport is that it ruins the simplicity of the StdioServerTransport architecture, where a client can spin up its own process, completely obviating the need for the user to separately "start the server" and potentially debug connection and firewall issues, teardown processes, etc. So I would not want to simply strip out StdioServerTransport and replace it with SSE. Rather, this is a separate project that should go in a separate repo.
Metadata
Metadata
Assignees
Labels
No labels