-
Notifications
You must be signed in to change notification settings - Fork 752
Description
Hello,
I'm trying to build an MCP server that uses the StremeableHttp transport (for which I created my own implementation). Although I finally got it to work, I found what I believe to be a design flaw in the way that McpAsyncServer -> McpServerSession -> Transport lifecycle are coupled and tied together. Let me explain:
Right now, the Session and Transport pretty much share the same lifecycle. They are created, used and stopped together. This works well for stdio and SSE transports, since those are stateful connections and the act of reconnecting results in brand new Session and Transport instances being created. This design works for SSE and will work for any other type of stateful connections (e.g: an eventual WebSockets transport).
This however doesn't work for stateless connection types such as streamable http, in which the session is created when the first initialize request is received but has a lifecycle that survives across many distinct http requests (even concurrent ones).
IMO, the root cause of the problem is that the McpServerTransport is missing the concept of TransportRequest or TransportMessage. Furthermore, the fact that the McpServerTransportProvider creates new Transport instances per each new request or session, suggests to me that the Transport is kind of partially assuming responsibilities that would better fit a request object.
Using StremeableHttp as an example, the advantages of introducing this Request object would be the following:
TransportProviderdissapears and becomes simplyMcpServerTransport- Whenever a JsonRPCMessage is received, the
McpServerTransportinstantiates a newTransportRequestobject that will contain all the relevant information. In the case of StremeableHttp, it would contain the HttpRequest object, some kind of callback or Writer to generate the response, client connection information, etc. NOTE: This would also make it quite easier to get that information than it is today, making things like security and tracing easier to implement - When needed, the
McpServerTransportwill use theMcpServerSessionFactoryto create new sessions. The session is then capable of handling further requests. - At this point, the lifecycle of all three components have been completely decoupled. Processing concurrent messages over stateless connections is now much much simpler than today