Skip to content

Session+Transport tied lifecycle doesn't easily support stateless connections such as StreamableHttp #273

Open
@marianogonzalez

Description

@marianogonzalez

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:

  • TransportProvider dissapears and becomes simply McpServerTransport
  • Whenever a JsonRPCMessage is received, the McpServerTransport instantiates a new TransportRequest object 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 McpServerTransport will use the McpServerSessionFactory to 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions