Stateless MCP Is a Gift to Gateways

Route stateless MCP by validated headers, separate transport logs from tool outcomes, and migrate legacy clients with explicit policies, cache keys, and checks.

MCP request headers support gateway routing and limits while server validation, response inspection, and caching remain separate responsibilities
Headers simplify routing. Full authorization, reliable caching, and execution evidence still need explicit implementation.

The move

Put an existing Layer 7 gateway in front of a small MCP deployment and prove method routing, tool-specific limits, and per-request transport logs. Then add result-aware caching and legacy support only where your clients need them. You finish with a tested route policy and a migration checklist, not an assumption that a protocol upgrade supplies every control.

The news, once: MCP changed its HTTP shape

The July 28, 2026 MCP release removed the initialization handshake and protocol sessions from the core. Requests carry their own metadata; HTTP intermediaries get mirrored method and target headers. The official changelog also covers cache hints, subscriptions, and changed retry behavior.

The older HTTP+SSE transport remains deprecated. The feature lifecycle policy establishes the deprecation process; it does not schedule your organization’s migration for you. Set an internal deadline around tested compatibility and client ownership.

Use the existing 2026-07-28 spec explainer for the wider revision. Here, the question is how to turn the new transport shape into a reliable deployment.

Why acting agents changed the requirement

A tool call may read a ticket, apply a deployment, or request a payment. Operators need to identify and constrain those actions across replicas, rather than infer them from an opaque stream after a failure.

The new headers make coarse controls easier to place at the edge. They do not make an untrusted server honest or tell a gateway whether a deployment’s arguments are safe. Keep the gateway control-plane checklist alongside this runbook: protocol visibility and policy enforcement are related, but neither substitutes for the other.

The runbook: route at the edge, validate before execution

Start in a test environment with one authenticated client, two execution replicas, and a synthetic tool with no external side effects. Keep the initial policy small. All policy examples below are illustrative; translate them into your gateway’s actual configuration and test the resulting behavior.

Step 1: establish the header trust boundary

The Streamable HTTP transport specification defines MCP-Protocol-Version, Mcp-Method, and, for targeted methods such as tools/call, Mcp-Name. Servers must reject disagreement between mirrored headers and the request body with HTTP 400 and HeaderMismatch error -32020.

A gateway can use that contract only if the upstream actually enforces it. Probe each deployed server build with a harmless mismatch: put one test tool name in the header and another in the body. Verify rejection before execution. A version string sent by the caller is not evidence of server conformance.

Edge control Available without request-body parsing Still required elsewhere
Method routing Mcp-Method Matching body validated before dispatch
Tool-level limits Decoded Mcp-Name, upstream, principal Argument and resource authorization
Transport audit Route, method, target, status, timing Tool outcome and business operation ID
Tenant selection Authenticated tenant context Resource ownership checked by the tool
Catalog caching Not from headers alone Request parameters and cacheable result parsing

Authenticate before assigning budgets or routes. Match header names case-insensitively and method values case-sensitively. Decode the specified Base64 sentinel representation once before target comparisons; reject malformed or ambiguous values. Do not normalize tool names in ways that differ from your server.

Pass: the same authorization decision holds for valid plain and encoded representations, and mismatched headers never execute. Save the requests and server-side counters as test evidence.

Step 2: write a default-deny policy for an explicit version

Support the revision you tested, not an open-ended comparison that trusts any future date. Unsupported versions should fail clearly. An older version is not a reason to send a request automatically to a weaker policy path.

# Illustrative policy model; not executable vendor configuration.
listener: mcp.corp.example:443
modern_route:
  path: /mcp
  methods: [POST]
  authentication: required
  supported_versions: ['2026-07-28']
  require_headers: [MCP-Protocol-Version, Mcp-Method]
  unknown_method: deny
  missing_or_unsupported_version: reject
rules:
  - method: tools/list
    upstream: approved-tools
    permission: catalog.read
  - method: tools/call
    require_headers: [Mcp-Name]
    upstream: approved-tools
    target: decode_mcp_name_once
    permission: approved_tool_and_resource_policy
    rate_limit_key: [tenant, principal, upstream, target]
    cache: disabled
  - method: subscriptions/listen
    upstream: approved-tools
    permission: catalog.watch
    response_buffering: disabled
legacy_route:
  path: /mcp-legacy
  identities: [explicit_migration_allowlist]
  authorization: legacy_body_aware_policy
  owner: platform-oncall

approved_tool_and_resource_policy is a requirement for your implementation, not a capability supplied by YAML. If a tool accepts a repository, environment, or SQL statement in its arguments, its service or a body-aware policy adapter must authorize those values before acting.

Add prompts/get, resources/read, and other methods only when required, with their own target rules. The method allowlist prevents an accidental catch-all route from exposing an interface you never reviewed. Key global tool ceilings by server plus tool, because unrelated servers can use identical tool names.

Run a matrix of allowed, denied, missing-header, unknown-method, and wrong-tenant requests. Include direct upstream access; firewall or service identity policy should prevent governed clients from bypassing the gateway. Gateway selection itself is covered in open gateways versus vendor suites.

Step 3: scale replicas without losing streams or application state

Start with one logical MCP service behind the gateway. Method-based pools are an optional optimization once measurements show a reason to separate discovery, execution, and subscription capacity. All pools must expose a coherent catalog and policy version.

Gateway routes an explicitly supported MCP revision to list, execution, and subscription pools; a separate authorized legacy path retains its own policy Optional pool separation. Execution streams need the same buffering care as subscription streams; legacy access is explicitly authorized.

Round-robin distribution removes protocol-session affinity for modern requests. Your application can still have state: a job identifier, transaction, cursor, or server-minted handle may refer to shared backend data. Test a multi-call workflow with successive calls deliberately landing on different replicas. A working first request is not a complete scaling test.

subscriptions/listen opens a response stream for opted-in change notifications. If one replica handles subscriptions and another changes the catalog, connect their notification source. Otherwise a client can maintain a healthy stream and still miss changes made elsewhere.

Disable response buffering on every route that can return SSE, including tools/call; streaming is not limited to subscriptions. Set bounded idle and total timeouts for the workload, arrange heartbeats where appropriate, and test a quiet interval longer than the proxy’s idle threshold. Hours-long timeouts are not a universal requirement.

Closing a request’s SSE stream is a cancellation signal. It does not promise to roll back a side effect already committed. Disable automatic retries of writes at the proxy until the tool’s idempotency and reconciliation behavior has been verified. A JSON-RPC request ID is a correlation identifier, not a deduplication guarantee.

Step 4: add catalog caching deliberately

Keep caching off for the first acceptance run. Then implement it in an MCP-aware client or gateway adapter that understands the caching contract. An ordinary HTTP cache cannot infer a complete cache key from POST /mcp and a method header.

The result’s ttlMs describes freshness; cacheScope distinguishes public reuse from reuse within an authorization context. Parameters such as a pagination cursor or resource URI affect results. Retry continuations carrying inputResponses or requestState are not cacheable.

For a conservative first implementation, cache approved public catalog results only. A suggested key is:

upstream identity
+ protocol revision
+ authorization/policy generation
+ request method
+ all result-affecting parameters, including cursor

Store the result payload and construct the response for the current JSON-RPC request ID. Replaying an entire cached envelope can return someone else’s ID. Never put raw access tokens into cache logs; if private caching is later enabled, isolate it by the actual authorization context and invalidate on credential or policy changes.

On a list-change notification, invalidate affected pages. Re-fetch from the beginning when you need a coherent full catalog: pagination does not promise a cross-page snapshot. Compare newly received definitions with the approved catalog before serving them to the model, as described in runtime MCP manifest controls.

Acceptance checks: request two different cursors, rotate authorization, change the catalog, and repeat with a new RPC ID. Verify the correct result and ID each time. A lower request count is not enough to call caching correct.

Step 5: separate transport health from tool outcomes

The edge access log can record authenticated principal, upstream, protocol revision, method, decoded target, decision, HTTP status, and duration. Use a gateway-generated correlation ID; do not trust a caller to choose the identifier that joins security records.

Signal Source What it tells you
HTTP failures and route latency Gateway Admission and transport behavior
JSON-RPC error code Parsed response or server telemetry Protocol failure, including header mismatch
Tool isError and operation result Execution adapter or server Tool-level outcome
Approval and policy revision Enforcement point Why an action was admitted
Catalog generation Client or mediator Which tool definition was presented

MCP tools distinguish protocol errors from tool execution errors. An HTTP 200 alone does not prove success. Obtain tool outcomes from instrumented execution or bounded response parsing; do not fabricate them from status codes.

The OpenTelemetry propagation proposal documents trace-context conventions carried in _meta. An edge that never parses request bodies does not automatically read those fields. Configure propagation in the client/server instrumentation or deliberately bridge your HTTP trace context. Keep sensitive values out of baggage and avoid logging all Mcp-Param-* headers indiscriminately.

Build separate charts for transport errors, protocol errors, tool failures, and missing completion records. That separation tells an operator whether to fix a route, an SDK, authorization, or the action itself.

Step 6: migrate older clients through a controlled lane

Inventory client version, server version, transport, owner, and required features. GET or DELETE requests on the MCP endpoint, session headers, missing method headers, and older revision values are useful compatibility signals. Earlier Streamable HTTP implementations could use sessions and standalone GET streams; not every older server required all those optional mechanisms.

Give legacy clients an explicit endpoint and identity allowlist. Preserve any affinity their server actually needs, and keep authorization effective through a parser or adapter that understands the old body. If you cannot enforce a required tool-level restriction there, disable that tool during migration. Coarse rate limiting is not equivalent authorization.

Test the client’s negotiation behavior using unsupported-version and header-mismatch responses. A malformed modern request should not silently downgrade into permissive legacy access. Publish an internal retirement date, track active legacy identities, and obtain owner signoff when each dependency is removed.

Before disabling the endpoint, run one planned rejection exercise with the test identity and verify that the operator receives a useful error. A migration dashboard showing zero traffic during a quiet weekend may miss a monthly scheduled job.

What breaks, and how you’ll know

The version guard trusts a claim, not a deployment. A server advertises the new revision but ignores header/body disagreement. Detect with the mismatch fixture; block that build from header-based policy until fixed.

Two replicas reveal hidden application state. A handle works on one replica and fails on another. Move the referenced state to an appropriate shared backend or route that application deliberately while migrating. Do not claim stateless business logic merely because session IDs disappeared.

The proxy retries a committed write. Duplicate operation IDs or repeated side effects appear after stream disconnects. Disable automatic write retries, implement idempotency where supported, and reconcile uncertain outcomes before replay.

The catalog cache masks changes. Watch observation age, invalidation failures, and authorization changes that do not clear private results. Missing notifications require bounded refresh behavior; a long-lived stream is not proof of freshness.

A server is outside the route. Shadow MCP discovery and egress observations identify coverage gaps. Header policy affects only traffic you actually mediate.

The operating-layer frame

The gateway and upstream services provide enforcement and execution evidence. Operators still need to connect a denied request to the session that produced it, understand whether the agent is waiting, and resume or stop that work. Agentic ops combines those records without confusing their responsibilities.

Automater’s local fleet and session views support the desk side of that workflow. They do not enforce MCP gateway policy, validate mirrored headers, or replace server telemetry. Keep the server hardening checklist in the deployment review. Explore Automater Lite and Pro for the local operating layer.

Sources