MCPG
Concepts
Concepts

Protocol versions

MCPG negotiates two MCP revisions on one listener — the stateful 2025-11-25 release and the stateless DRAFT-2026-v1 draft. How version selection works, what changed between them, and why a single deployment serves both.

The Model Context Protocol is a moving target. MCPG's answer is to speak more than one revision of it at the same time, on the same listener, so a fleet doesn't have to fork or re-deploy to track the spec.

Today MCPG negotiates both:

  • 2025-11-25 — the current production-grade release revision. Stateful: initialize handshake, sessions, SSE.
  • DRAFT-2026-v1 — the draft of the next revision (it graduates to 2026-07-28 on final release). Stateless: no handshake, no sessions, MRTR.

Both are served by one gateway process. This page is the mental model; the wire details and config keys live in the configuration reference.

How version selection works

A client signals its revision; the gateway routes the request to the matching protocol handler and serves that revision's wire shape. Internally each revision is a typed ProtocolVersion selected from a registry, not branched at ad-hoc call sites — so adding the next revision is a registration, not a rewrite.

  • The stateful revisions (2025-11-25 and its accepted legacy peers 2025-06-18, 2025-03-26) signal the version via the Mcp-Protocol-Version HTTP header, run initialize negotiation, and pin a session.
  • The modern revision (DRAFT-2026-v1) is stateless. There is no handshake; the version, client info, and client capabilities travel in _meta on every request, and routing headers (Mcp-Method, Mcp-Name) let an intermediary route without parsing the body.

The default for new deployments is 2025-11-25 — a single compile-time constant selects the default, so an operator pinning the modern revision is a one-line change. The gateway accepts both the DRAFT-2026-v1 and the final 2026-07-28 wire strings for the modern revision, so clients on either string land on the same handler when the spec ships final.

Why the modern revision is a rewrite, not an iteration

DRAFT-2026-v1 is structurally a rewrite. One shift drives most of the rest:

The protocol is now stateless. Sessions are gone. The handshake is gone. Every request is self-contained.

That cascades into the rest of the delta:

Concern2025-11-25 (stateful)DRAFT-2026-v1 (stateless)
Handshakeinitialize + notifications/initializednone — context rides in _meta per request
Discoverylearned from initialize resultserver/discover (a callable method)
SessionsMcp-Session-Id, server-pinnedno sessions; DELETE /mcp removed
Server→client requestsSSE-based (elicitation/sampling/roots)Multi Round-Trip Requests (MRTR)
Long-lived streamGET /mcp (SSE)subscriptions/listen
HTTP routingbody-parsedMcp-Method / Mcp-Name routing headers
Tasksexperimental corean official extension with its own lifecycle
roots / sampling / loggingcoredeprecated

The practical payoff of statelessness: load balancers can plain round-robin. No sticky sessions, no shared session store required for the modern wire — each request is independent. (Shared coordination is still needed for subscriptions/listen streams and tasks.)

MRTR — pausing a call to ask the client

The biggest mechanical change is how the server asks the client for something mid-call. In the stateful revision, a tool that needs input (an elicitation, an LLM sampling, a roots/list) sends a server-initiated request over the session's SSE channel and waits.

In the modern revision that becomes Multi Round-Trip Requests (MRTR): the call returns an "input required" result carrying an opaque requestState; the client answers; the call resumes. Because there's no session to hold the paused state, MCPG persists it in a hybrid scheme — encrypted inline up to a size threshold, KV-backed handle above it. The encryption key is operator- configurable. In MCPG this is exactly the suspension model the pipeline step kinds already use — the elicitation, sampling, roots_list, and multi-entry gather steps suspend and resume identically, mapped onto whichever wire the client is speaking.

What this means for you

You usually don't touch any of this — the gateway negotiates the right revision for each client automatically. But the model has real operational consequences:

  • No forced migration. Clients on 2025-11-25 keep working unchanged while newer clients adopt the modern wire against the same endpoint. You roll forward client-by-client, not all-at-once.
  • One deployment, two protocols. You don't run two gateways or two endpoints. A single MCPG listener serves both revisions.
  • Backends never see the version. The protocol revision is entirely client-facing. A backend gets an HTTP / NATS / SQL request in its own protocol regardless of which MCP revision the client spoke — so a binding written today works under both revisions with no change.
  • Statelessness simplifies scaling. Modern-wire traffic round-robins across instances with no session affinity, which is the cheaper HA story.

Where to go next