Repository navigation
RFC: support legacy stateless Streamable HTTP - #8856
Open
brandon-julio-t wants to merge 1 commit into
Open
brandon-julio-t wants to merge 1 commit into
brandon-julio-t wants to merge 1 commit into
Conversation
Clients using rotating HTTP backends lose process-local MCP sessions between initialization and later tool requests. Servers whose tools do not require persistent MCP state need a transport that accepts those requests independently. Offer an opt-in stateless HTTP mode while retaining stateful sessions by default. Use conservative request-scoped client profiles and expose the mode's limitations so applications can choose whether it fits their tool workflows. Related: Effect-TS#6752
🦋 Changeset detectedLatest commit: a8066ee The changes in this PR will be included in the next version bump. This PR includes changesets to release 32 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
Bundle Size AnalysisGenerated from PR build output; treat the content below as untrusted.
|
This branch is waiting to be deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
RFC
This is a working proposal for #6752. Feedback is requested on the public option and the
conservative client profile used after initialization; the implementation and regression tests are
included for review.
Motivation: requests across backend replacement
A legacy MCP client initializes against backend A and receives a session ID. A deployment replaces
A, or a later request reaches backend B. The healthy backend has no record of that process-local
session, so the request returns 404 and the client must initialize again.
For tools that authenticate each request and keep their application state in external storage, this
session affinity creates an unnecessary deployment constraint. These tools need each request to work
on any healthy backend, without relying on persistent sampling capabilities, subscriptions, or
logging settings.
The regression tests exercise this directly: initialize one handler runtime, dispose it, and issue
the next request against a fresh runtime. The proposed mode omits session IDs and reconstructs a
conservative client profile for each request. This addresses session loss between requests; it does
not prevent network disconnects or preserve in-flight work across process replacement.
The same behavior supports the serverless-isolate scenario in #6752. Clients can retain their
supported legacy MCP revisions without migrating to the newer
2026-07-28protocol.Proposal
The
Streamable HTTP specification
permits servers to omit session IDs. This adds an opt-in transport mode:
Initialization still negotiates the legacy protocol, but issues no
Mcp-Session-Id. Later POSTsderive a request-scoped binding from
MCP-Protocol-Version, with the specified2025-03-26fallback when the header is absent. Bindings are released through the existing request disconnect
path. Unsupported revisions return 400; stale session IDs still return 404 rather than silently
becoming sessionless requests.
The default remains stateful. Stdio, custom transports, and the modern
2026-07-28protocol retaintheir existing behavior. The
2024-11-05coverage exercises Effect's existing Streamable HTTPcompatibility adapter, not the historical HTTP+SSE transport.
Tradeoffs and design questions
Legacy requests do not repeat initialize capabilities or client info, so subsequent requests receive
empty client capabilities and unknown client info. This mode does not advertise list-change
notifications, resource subscriptions, or logging; persistent logging settings are rejected.
Cancellation across separate POSTs and session termination are unavailable. It does not preserve
in-flight work across process replacement or prevent network disconnects.
sessionMode: "stateless"onlayerHttpthe preferred API for this constrained mode?an explicit profile provider? An external session-store API could be considered separately for
applications that need persistent capabilities or subscriptions.
Validation
McpStatelessHttp,McpServer, andMcpProtocol, including 9 newcases.
modern-protocol cases pass.
hk checkusing the installed Effect TypeScript-Gocompiler with
-b tsconfig.json.pnpm lint-fix,pnpm lint, andgit diff --checkpass.pnpm jsdocs --checkreports 3 existing documentation errors in unchangedpackages/effect/src/PubSub.ts; the same check fails against the original source. No errors arereported for the changed MCP modules.
POST. This verifies request independence across handler replacement.
Prepared with assistance from OpenAI Codex. Related to #6752; this RFC does not assume agreement on
the API or close the issue before that discussion.