Parent: #1287 (Slice B decomposition)
This is Slice B-2 of the MCP 2026-07-28 stateless migration. Depends on #1511 (B-1: capability flag + synthesize_capabilities).
Scope (this issue — ≤200 lines)
Add the stateless request path that bypasses the initialize/initialized handshake and routes requests with inline _meta routing context. This is the core behavioral change — the 4 session.initialize() sites and 11 dispatch sites get a flag-gated alternative path.
Specific changes
-
Skip session.initialize() for stateless servers (4 sites): gate each behind if self._stateless_enabled and self._is_stateless_server: — synthesize the session instead of calling the handshake.
- Line 2426 (stdio transport)
- Line 2732 (SSE transport)
- Line 2789 (streamable_http, new API)
- Line 2821 (streamablehttp, deprecated API)
-
server/discover RPC: add a method that calls the new server/discover RPC (introduced in the finalized spec) to obtain server capabilities without a session. This replaces the information previously obtained from the initialize handshake response.
-
Inline _meta routing: when sending RPCs in stateless mode, embed routing context (Mcp-Method, Mcp-Name) as inline _meta in the request body instead of relying on a pinned session. Cover the critical hot path: call_tool (audit line ~4263).
-
_get_session_id sites (2 sites): in stateless mode, these should return None / skip the session-id header entirely (SEP-2567 removes Mcp-Session-Id).
| Group |
Lines |
Count |
session.initialize() |
2426, 2732, 2789, 2821 |
4 |
self.session.* dispatches |
~4263 (call_tool) + 10 others |
11 |
_get_session_id |
2 sites |
2 |
| Total |
|
17 |
What this issue does NOT do
Success criteria
Dependencies
Audit reference
Full call-site map: docs/mcp/2026-07-28-stateless-migration-audit.md
Parent: #1287 (Slice B decomposition)
This is Slice B-2 of the MCP 2026-07-28 stateless migration. Depends on #1511 (B-1: capability flag + synthesize_capabilities).
Scope (this issue — ≤200 lines)
Add the stateless request path that bypasses the
initialize/initializedhandshake and routes requests with inline_metarouting context. This is the core behavioral change — the 4session.initialize()sites and 11 dispatch sites get a flag-gated alternative path.Specific changes
Skip
session.initialize()for stateless servers (4 sites): gate each behindif self._stateless_enabled and self._is_stateless_server:— synthesize the session instead of calling the handshake.server/discoverRPC: add a method that calls the newserver/discoverRPC (introduced in the finalized spec) to obtain server capabilities without a session. This replaces the information previously obtained from theinitializehandshake response.Inline
_metarouting: when sending RPCs in stateless mode, embed routing context (Mcp-Method,Mcp-Name) as inline_metain the request body instead of relying on a pinned session. Cover the critical hot path:call_tool(audit line ~4263)._get_session_idsites (2 sites): in stateless mode, these should returnNone/ skip the session-id header entirely (SEP-2567 removesMcp-Session-Id).Call sites (from Slice A audit)
session.initialize()self.session.*dispatches_get_session_idWhat this issue does NOT do
Success criteria
session.initialize()is skipped for stateless-flagged servers (4 sites gated)server/discoverRPC call implemented and returns capabilitiescall_toolhot path routes via_metainline when stateless_get_session_idreturns None in stateless mode (2 sites)Dependencies
synthesize_capabilities()Audit reference
Full call-site map:
docs/mcp/2026-07-28-stateless-migration-audit.md