---
title: "MCP Became Stateless: Migrating a Real AgentCore Gateway"
description: "MCP 2026-07-28 removes protocol sessions from remote calls. Here is what changed in a working AgentCore WebSearch gateway, what stayed untouched, and how to migrate without breaking older clients."
canonical_url: "https://artificialcuriositylabs.ai/posts/mcp-became-stateless-agentcore-gateway-migration/"
md_url: "https://artificialcuriositylabs.ai/posts/mcp-became-stateless-agentcore-gateway-migration.md"
published_at: "2026-08-03T07:00:00.000Z"
tags:
  - "agents"
  - "mcp"
  - "infrastructure"
  - "patterns"
---

MCP no longer needs a protocol session for remote tool calls. The [2026-07-28 specification](https://modelcontextprotocol.io/specification/2026-07-28/changelog) removes the initialization handshake and `Mcp-Session-Id`, then makes every request carry enough information to stand alone.

I migrated a working Amazon Bedrock AgentCore Gateway that exposes the managed WebSearch connector. The change was smaller than the specification makes it sound: one gateway configuration update and one client-side request change. The WebSearch target, IAM authorization, tool schema, and local Codex connection stayed intact.

The result is the useful part. The gateway now serves old and new MCP clients at the same endpoint, and the new path reaches WebSearch without a handshake or protocol session.

## The state before the migration

My existing setup already used the pattern from [Web Search as a Managed Connector](https://artificialcuriositylabs.ai/posts/agentcore-websearch-managed-connector/):

```text
Codex
  -> local stdio MCP shim
    -> SigV4-signed HTTPS request
      -> AgentCore Gateway
        -> managed WebSearch connector
```

The local shim presented one tool to Codex, signed the outbound request with an AWS identity, and called WebSearch through the gateway. It worked, but both the shim and gateway were pinned to MCP `2025-06-18`.

The request carried `MCP-Protocol-Version: 2025-06-18` in an HTTP header. Its JSON-RPC body contained the tool name and arguments, but no per-request client information or capabilities.

## What stateless MCP changes

Earlier remote MCP versions established protocol context through `initialize`, followed by `notifications/initialized`. Streamable HTTP servers could then issue an `Mcp-Session-Id` that clients returned on later requests. That couples subsequent traffic to state established earlier.

[SEP-2575](https://modelcontextprotocol.io/seps/2575-stateless-mcp) removes the initialization handshake, while [SEP-2567](https://modelcontextprotocol.io/seps/2567-sessionless-mcp) removes protocol-level sessions from Streamable HTTP. Under `2026-07-28`, each request declares its version, method, tool name, client identity, and capabilities.

The new WebSearch call adds three HTTP headers:

```http
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: web-search-tool___WebSearch
```

It also adds request metadata inside `params`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "web-search-tool___WebSearch",
    "arguments": {
      "query": "MCP 2026-07-28 specification",
      "maxResults": 2
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {
        "name": "agentcore-websearch-shim",
        "version": "0.2.0"
      },
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}
```

The header and body versions must agree. [AgentCore Gateway rejects mismatches](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-using-mcp-call.html), which gives gateways and other HTTP infrastructure a trustworthy routing signal without parsing the entire body.

Normal results also carry `resultType: "complete"`. Interactive operations can instead return `resultType: "input_required"` and continue through a later request using the specification's [Multi Round-Trip Request model](https://modelcontextprotocol.io/seps/2322-MRTR). State becomes explicit data, not hidden connection history.

## Quantifying the change

For a conventional session-aware client, the first tool call drops from an initialization exchange followed by the tool exchange to one self-contained tool exchange. That removes one network round trip from the cold path. The savings equal the client-to-server round-trip time, but only before the first call.

AgentCore Gateway already accepted my shim's direct `tools/call` without a preceding handshake, so its remote request count stayed `1 -> 1`. I measured the compact JSON body for the same WebSearch call:

| Measure | MCP 2025-06-18 | MCP 2026-07-28 |
|---|---:|---:|
| Remote requests per search | 1 | 1 |
| Compact JSON request body | 162 bytes | 372 bytes |

The new request adds 210 body bytes plus two routing headers. There is no credible latency win to claim for this client because WebSearch execution dominates the call and the old shim had already skipped the handshake. The immediate client benefit is conformance with the new protocol and access to its result, discovery, caching, tracing, and multi-round-trip contracts.

The server-side arithmetic is stronger:

- **Protocol session state:** `N` active clients previously meant up to `N` protocol sessions or a shared session store. The new core holds zero protocol-session records. Application state remains separate.
- **Load balancing:** any request can reach any healthy instance. The [stateless MCP proposal](https://modelcontextprotocol.io/seps/2575-stateless-mcp) describes the previous choice between connection affinity and shared state; the new protocol removes that requirement.
- **Cold-call traffic:** a conforming client removes one response-bearing exchange before its first tool result, a 50% reduction from two exchanges to one.
- **Failure recovery:** losing one server instance no longer invalidates protocol sessions pinned to it. In-flight work can still fail, but recovery becomes one ordinary request retry rather than session recovery plus retry.

The gain is not smaller JSON or faster search. It is removing coordination: fewer cold-start exchanges, no protocol session store, no sticky routing, and less custom recovery logic.

## What this means for builders

**Client and host builders** replace session management with request construction. They need a `2026-07-28`-capable SDK or equivalent support for the new headers, `_meta`, `resultType`, discovery, HTTP errors, cache metadata, and multi-round-trip responses. Supporting both versions means selecting the protocol explicitly for each request.

**Remote server builders** need handlers that understand each request in isolation. Application state still exists: a coding workspace, shopping basket, or long-running job needs an explicit handle passed as a tool argument and authorized on every call. Any healthy server instance can then process the next request.

**Tool builders behind a gateway** often change nothing. My WebSearch target, IAM policy, tool name, and arguments stayed the same because AgentCore Gateway owns the MCP boundary. The backend does not need to know which MCP version the caller selected.

**Interactive-tool builders** have the largest conceptual change. Instead of relying on a persistent connection, the tool returns `input_required`, the client gathers the missing input, and a later request resumes the work with explicit state.

**Platform operators** gain standard HTTP control points. `Mcp-Method` and `Mcp-Name` can drive routing, rate limits, metrics, and policy without opening the JSON body. Cache metadata and trace context bring catalog traffic and distributed tracing into the same request model.

Local stdio MCP servers do not need an immediate rewrite. The migration boundary is remote Streamable HTTP; a shim or gateway can adopt the new contract while the local host keeps its existing protocol version.

## The migration boundary matters

The shim is the protocol boundary, so the change stayed narrow:

| Component | Change required |
|---|---|
| Local Codex MCP configuration | No |
| Local stdio initialization | No |
| Shim's outbound Gateway request | Yes |
| Gateway `supportedVersions` | Yes |
| IAM/SigV4 authorization | No |
| Managed WebSearch target | No |
| WebSearch tool arguments | No |

## Dual-version rollout is the safe path

AgentCore Gateway makes the transition opt-in. Its [`supportedVersions` configuration](https://aws.amazon.com/blogs/machine-learning/how-agentcore-gateway-supports-the-mcp-2026-07-28-spec/) is a complete list, not an appended value. Replacing an older version with the new one would strand every client that has not migrated.

I kept the old version while adding the new one:

```json
["2025-06-18", "2026-07-28"]
```

Both paths completed a WebSearch request, and the new path returned `resultType: "complete"`. Six local tests also passed for argument validation, metadata, headers, SigV4 signing, and response parsing. Version selection at the request boundary lets clients migrate independently.

## What else arrived with this release

Statelessness is the architectural center, but the revision goes further:

- **HTTP operations:** [`Mcp-Method` and `Mcp-Name`](https://modelcontextprotocol.io/seps/2243-http-standardization) expose request intent to routing, metering, and policy layers.
- **Caching and tracing:** [list responses can declare cache lifetime and scope](https://modelcontextprotocol.io/seps/2549-TTL-for-list-results), while [W3C trace context](https://modelcontextprotocol.io/seps/414-request-meta) can cross client, gateway, and tool boundaries.
- **Schemas and extensions:** tools support [JSON Schema 2020-12](https://modelcontextprotocol.io/seps/2106-json-schema-2020-12), and [extensions have a governed lifecycle](https://modelcontextprotocol.io/seps/2133-extensions). Tasks moved from core into an official extension.
- **Authorization and lifecycle:** authorization aligns more closely with [OAuth 2.0 and OpenID Connect practice](https://aws.amazon.com/blogs/machine-learning/how-agentcore-gateway-supports-the-mcp-2026-07-28-spec/). Roots, Sampling, and Logging are [deprecated under a formal lifecycle policy](https://modelcontextprotocol.io/seps/2577-deprecate-roots-sampling-and-logging), though they remain functional during the compatibility window.

These changes move remote MCP closer to ordinary HTTP infrastructure: independently routable requests, explicit caching, standard tracing, and transport errors represented by real HTTP status codes.

## What's missing

I have not removed `2025-06-18` from the gateway. Both versions work, but successful tests do not prove that every occasional client has migrated. Removing the old version needs caller inventory and protocol-version telemetry, not confidence based on one active shim.

The other open question is how quickly MCP hosts will expose the new protocol natively. A translation shim makes the migration manageable, but the cleaner end state is a host that can negotiate `2026-07-28` directly and use `server/discover`, cache metadata, trace context, and multi-round-trip interactions without custom code.

## So what

Remote MCP is becoming normal web infrastructure. Gateways can route and meter calls from headers, servers can scale without sticky sessions, and clients can retry self-contained operations against any healthy instance. Application state still exists, but it has to be named and carried deliberately.

For my client, the trade was 210 extra request bytes in exchange for removing an entire category of connection state. The migration follows the same logic: advertise both versions, update one client at a time, and retire the old path only when usage proves it is safe.
