Title: Session+Transport tied lifecycle doesn't easily support stateless connections such as StreamableHttp · Issue #273 · modelcontextprotocol/java-sdk · GitHub
Open Graph Title: Session+Transport tied lifecycle doesn't easily support stateless connections such as StreamableHttp · Issue #273 · modelcontextprotocol/java-sdk
X Title: Session+Transport tied lifecycle doesn't easily support stateless connections such as StreamableHttp · Issue #273 · modelcontextprotocol/java-sdk
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 -> ...
Open Graph 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...
X 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 de...
Opengraph URL: https://github.com/modelcontextprotocol/java-sdk/issues/273
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Session+Transport tied lifecycle doesn't easily support stateless connections such as StreamableHttp","articleBody":"Hello,\n\nI'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 -\u003e McpServerSession -\u003e Transport lifecycle are coupled and tied together. Let me explain:\n\nRight 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).\n\nThis 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). \n\nIMO, 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. \n\nUsing StremeableHttp as an example, the advantages of introducing this `Request` object would be the following:\n\n* `TransportProvider` dissapears and becomes simply `McpServerTransport`\n* 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\n* When needed, the `McpServerTransport` will use the `McpServerSessionFactory` to create new sessions. The session is then capable of handling further requests. \n* 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\n\n","author":{"url":"https://github.com/marianogonzalez","@type":"Person","name":"marianogonzalez"},"datePublished":"2025-05-28T16:01:02.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/273/java-sdk/issues/273"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:d4ac2c97-6b19-a952-0556-27d43dda3857 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | BCB6:24A924:46ADDF:5C9BFB:6A5B2653 |
| html-safe-nonce | 256b2b5d60acaf560ae92d89d2bded2a9297c8397d7193b9fac7f7ad375242ff |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCQ0I2OjI0QTkyNDo0NkFEREY6NUM5QkZCOjZBNUIyNjUzIiwidmlzaXRvcl9pZCI6IjEzNTc2MTY2MjgzNTY1NTYzNzEiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | dd53e26eab9a5482d7c850d2d9f24f4421de033499724b4d62f34cdc7455da7c |
| hovercard-subject-tag | issue:3097857094 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/modelcontextprotocol/java-sdk/273/issue_layout |
| twitter:image | https://opengraph.githubassets.com/6510c2a21de3189b361dc6187ebf6df9dac6c13c5a9e740c7795cb582653ce6a/modelcontextprotocol/java-sdk/issues/273 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/6510c2a21de3189b361dc6187ebf6df9dac6c13c5a9e740c7795cb582653ce6a/modelcontextprotocol/java-sdk/issues/273 |
| og:image:alt | 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... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | marianogonzalez |
| hostname | github.com |
| expected-hostname | github.com |
| None | 5290d7e14309ad1e76106a9c4237bd1041517e83ea182c8ab756752cb0c6940b |
| turbo-cache-control | no-preview |
| go-import | github.com/modelcontextprotocol/java-sdk git https://github.com/modelcontextprotocol/java-sdk.git |
| octolytics-dimension-user_id | 182288589 |
| octolytics-dimension-user_login | modelcontextprotocol |
| octolytics-dimension-repository_id | 919609219 |
| octolytics-dimension-repository_nwo | modelcontextprotocol/java-sdk |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 919609219 |
| octolytics-dimension-repository_network_root_nwo | modelcontextprotocol/java-sdk |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 9c975978430e9ad293956f2bbdaf153b1bd84a99 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width