#9129·jaeger

Plan the mcptools migration to the stateless MCP spec revision (SEP-2575 / SEP-2567)

Author: lopster568Created Jul 28, 2026Updated Sep 14, 2026
Labelsenhancement

What changed upstream

The next MCP spec revision makes the protocol stateless. Both SEPs are accepted (labeled final) and merged into the spec's draft changelog; the Go SDK is implementing against it as protocol version 2026-07-28. As of filing, the revision is still draft with a 2026-07-28-RC prerelease tagged, not yet a published revision directory.

  • SEP-2567 removes protocol-level sessions and the Mcp-Session-Id header. Cross-call state moves to explicit server-minted handles passed as ordinary tool arguments, and list endpoints no longer vary per-connection.
  • SEP-2575 removes the initialize/notifications/initialized handshake. Protocol version and client capabilities travel per-request in _meta. Servers MUST implement a new server/discover RPC advertising supported versions, capabilities, and identity; the DiscoverResult schema also carries optional instructions. Clients MAY call it.

modelcontextprotocol/go-sdk support is in flight: #1111 (stateful servers rejecting SEP-2575 requests), #1025, #1095 (restricting advertised versions), and fixes are already landing (#1116 closed today).

What it touches in Jaeger (at current main)

Spec change Jaeger surface
initialize removed mcptools/server.go delivers the embedded INSTRUCTIONS.md as ServerOptions.Instructions, which ships in the initialize response today. The draft moves instructions to DiscoverResult.instructions, and since clients MAY skip server/discover, delivery becomes best-effort
sessions removed mcptools/server.go runs the streamable handler with Stateless: false and a 5 minute SessionTimeout (config.go)
list endpoints must not vary per-connection the jaegerai turn-scoped endpoint advertises per-turn UI tools in tools/list via receiving middleware (jaegerai/endpoint_turn_mcp.go). The variation is keyed by URL route id rather than the session header, so it may remain conformant, but that needs a read of the final text
unaffected tenancy extraction is transport-level (tenancy.ExtractTenantHTTPHandler in WrapHTTP) and independent of MCP sessions

Tests are mostly indirectly affected: the suites drive the SDK client through Connect, which performs the handshake and session management internally, so the harness follows whatever the SDK ships. The exception is mcptools/middleware_test.go, which references mcp.InitializeParams and the initialize method name directly.

Open questions

  1. Instructions delivery. Is DiscoverResult.instructions enough guidance surface for LLM clients, or should the key usage notes move into tool descriptions, which every client sees? Related: #8897 reports the Gemini sidecar already missing server instructions today, so this delivery gap predates the spec change. The draft also asks servers to return tools/list in deterministic order for prompt caching, which we already do.
  2. The turn-scoped UI-tools endpoint: keep per-URL variation, or move to the explicit state-handle pattern SEP-2567 describes?
  3. Timing. The SDK is mid-flight on exactly the behaviors we depend on. Migrating before it settles risks churn; waiting too long means running a stateful server against clients that have moved.

Plan

I'd like to drive this. Proposed sequence, gated on the go-sdk shipping stable 2026-07-28 support:

  • Move key usage guidance from INSTRUCTIONS.md into tool descriptions (valid under both revisions, useful now; PR to follow shortly)
  • Flip the streamable handler to stateless and drop the session timeout once the SDK settles
  • Wire instructions into server/discover
  • Rework the turn-scoped endpoint per the answer to question 2
  • Update the integration harness to whatever Connect becomes

Later phases land on top of #9125's in-progress refactor of the shared MCP server construction, so I would sequence behind it rather than conflict with it.

Questions 1 and 2 above are the direction calls I'd want input on before the later phases. @yurishkuro could you assign this to me?