feature: Proper way to handle session or http transports
Problem Statement
Now-days its quite often that HTTP services run in large number of pods in k8s. mcp-go in-memory session handling handling does not really work there. Tested with SSEServer and in order it worked, was forced to use single replica.
Basically if you have more than one backend, "Invalid session ID" will come if you hit different backend..
Also I think there is a bug (or made something wrong?). But MCPServer session registrations, does not affect SSEServer in where its used as SSEServer has its own session store.
mcpServerInstance = NewMCPServer(...)
sseServer = NewSSEServer(
mcpServerInstance,
)
mcpServerInstance.RegisterSession(ctx, session) // <-- does not affect SSEServer
Proposed Solution
Please provide way / example how to manage sessions for sse http transports between this kind of multiple backend situation. Ie so redis/db etc can be used as store...
Alternatives/Workarounds Considered
Only known workround - keep single backend...
even i am getting this issue a lot
We're looking at this issue right now except using the StreamableHTTPServer and trying to think about how to serialize the session in such a way that we cache it in Redis and then deserialize from there but a) streamableHttpSession is a private struct and b) most fields don't have a simple serialization path.
Any advice?
implements server.SessionIdManager interface use distribute cache like redis, and nextRequestID also should increment by distribute cache.
implements server.SessionIdManager interface use distribute cache like redis, and nextRequestID also should increment by distribute cache.
That doesn't really answer the question about what a session represents. It's one thing to be able to assign sessionIDs and cache them, it's another thing to be able to cache values within a session to be able to tie that session back to a request. There seems to be a gap in the standard^1 explaining what a session represents beyond the understanding that if an Mcp-Session-Id header is provided it determines something within the server state that allows for continuing the request pattern without requiring the initialization flow.
The implementation in this library isn't clear about how to reconstruct a session based on a given sessionID or what the implications are of persisting sessions vs not using sessions at all. There also doesn't seem to be a clear path towards opening notification channels based on a cached session ID either.
Yes I think this library isn't compliant with the spec in terms of session lifecycle. It is short lived and is only available during the duration of a request, and implementing long lived session has to be done through hooks which feels a bit off. I think you should be able to pass a SessionStore interface to the server
My .02
- Agree the spec is vague in terms of session handling. The fact that MCP is stateful is a poor design choice IMO.
- This library still has some corner cases to fix in session handling. I just posted an issue WRT to session re-use.
- In my own server implementation, I am about to implement Redis caching for sessions for streamable_http transport (using this library). The hooks are available to do it.
- Another option is to load balance across MCP servers using client IP as the load balancing key; you could also use the session ID as the load balancing key as well and then you don't have to worry about this issue.