Skip to content

SSEClientTransport doesn't re-establish lifecycle state on disconnect/reconnect #510

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
BobDickinson opened this issue May 18, 2025 · 0 comments
Labels
bug Something isn't working

Comments

@BobDickinson
Copy link

I am writing an SSE proxy (using this library, including the SSEServerTransport) and struggling with what I assess as some bad client behavior caused by the standard libraries (including SSEClientTransport).

A client will connect and initialize, and send some number of requests receiving responses (notifications, etc). All great so far. When that connection goes away (long timeout, server restart, etc), the EventSource used by the SSE client re-establishes a new session with the server via the event source fetch method (calling the SSE url endpoint, typically /sse, and getting a new /messages endpoint for a new session). The problem is that the client does not then re-initialize to establish proper lifecycle state - it assumes the server somehow understands that it has already initialized and just starts blasting requests, which fail (the server requires an initialize message exchange to initialize the new session before it can accept requests).

I'm going by the lifecycle documentation provided here: https://modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle

My reading of that and my understanding of how the MCP SSE protocol works indicate that if you make a new SSE endpoint request (/sse), that starts a new session, and you need to start the protocol again (initialize) with the /messages endpoint you get back (which is associated with that new session). I see no other way that multiple clients (or even multiple client connection instances from a single client) could use the same SSE server endpoint. In terms of trying to work around this on my server/proxy, I also see no reliable way to associate a client on a new connection with a previous session (especially while avoiding punishing a client who behaved correctly and re-initialized the new connection).

If my assessment is correct, and essentially all SSE clients in the wild do not correctly re-establish sessions on reconnect, then I'm not sure how a multi-user or multi-client SSE server can be made to work, at least if it implements the protocol lifecycle properly.

The fix to the client library for this is pretty straightforward, but it doesn't address the fact that all clients currently in the wild (many of which won't update anytime soon) aren't going to work in some common scenarios using SSE servers.

If anyone is curious, this is the basic new connection logic (more or less as advised):

app.get('/sse', async (req: Request, res: Response) => {
  const transport = new SSEServerTransport('/messages', res);
  activeSessions.set(transport.sessionId, transport);
  // This will  return the new endpoint with the new session id
  await transport.start(); 
}
@BobDickinson BobDickinson added the bug Something isn't working label May 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant