---
title: "Is MCP Stateless Now? Server Migration Guide 2026"
canonical: https://wavect.io/blog/mcp-stateless-server-migration-2026/
language: en
description: "MCP is stateless in the 2026-07-28 spec. Audit sessions, headers, discovery, state handles, caching and compatibility in your MCP server."
image: "https://wavect.io/img/blog/headers/header_mcp-stateless-server-migration-2026.png"
---

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

12 min read · 31 Jul 2026 Last reviewed July 31, 2026

[**Next**](/blog/yc-application-technical-readiness-checklist/)

# Is MCP Stateless Now? What to Change in Your Own MCP Server

TL;DR

Yes. The MCP 2026-07-28 specification makes the protocol core stateless: it removes the initialize and initialized handshake, removes Mcp-Session-Id, and requires each request to carry its protocol version, client information and capabilities. Streamable HTTP now uses one POST per message, with MCP-Protocol-Version and Mcp-Method headers plus Mcp-Name for tool, resource and prompt calls. This does not make your application data stateless. Durable workflows should use explicit, authenticated handles, the Tasks extension, requestState for multi-round-trip input and normal storage. For an existing remote server, inventory hidden session state, add server/discover, validate header and body parity, make list results deterministic and cache-aware, keep a tested legacy path while clients migrate, and run conformance, authorization, replay and round-robin tests before removing old infrastructure.

**Yes. MCP is stateless at the protocol layer as of specification version `2026-07-28`.** The initialize handshake and `Mcp-Session-Id` are gone. Each request now carries the protocol version, client identity and capabilities it needs. A remote request can reach any healthy server instance without sticky routing.

That answer needs one qualification: stateless MCP does not mean stateless software. Your shopping basket, browser job, approval flow or paid order may still need durable state. The difference is that this state must be explicit, addressable and secured by your application instead of hiding inside an MCP transport session.

This guide owns the transport and migration question. For permissions and tenant isolation, use our separate [enterprise MCP authorization architecture](/blog/enterprise-mcp-authorization-architecture/). For the deeper question of where protection must be enforced, read why [MCP is not the complete security boundary](/blog/mcp-security-boundary-data-level-access-control/).

Once the wire contract is ready, use our [MCP Cloud vs Manufact Cloud hosting guide](/blog/mcp-cloud-vs-manufact-cloud/) to compare managed deployment, governance, pricing and exit paths.

## What is the direct answer?

**MCP 2026-07-28 is a stateless, self-contained request protocol. Protocol state is gone. Application state is still allowed and often necessary.**

The official specification now lists “stateless, self-contained requests” and “per-request capability negotiation” as base protocol properties. On Streamable HTTP, every message is a new POST. The response is either one JSON object or a request-scoped SSE stream. The old standalone GET stream, protocol session, `Mcp-Session-Id` and resumable SSE mechanism are not part of this revision.

## What changed in MCP 2026-07-28?

| Concern | 2025-11-25 and earlier | 2026-07-28 |
| --- | --- | --- |
| Startup | `initialize`, then `notifications/initialized` | No initialization handshake; optional `server/discover` |
| Protocol session | Server may mint `Mcp-Session-Id` | No protocol session or session ID |
| Request context | Version and capabilities negotiated once | Version, client info and capabilities travel in request `_meta` |
| HTTP routing | Session affinity or shared session storage may be needed | Any instance can process a self-contained request |
| HTTP metadata | Gateway often needs to inspect the JSON body | `MCP-Protocol-Version`, `Mcp-Method` and sometimes `Mcp-Name` are required |
| Server-to-client input | Server could issue a request over SSE | Return `input_required`; client retries with `inputResponses` and optional `requestState` |
| Long-running work | Experimental task behavior in core | Official opt-in Tasks extension with durable task handles |
| Lists | Change notifications and polling | Deterministic order plus required `ttlMs` and `cacheScope` |

The [official 2026-07-28 changelog](https://modelcontextprotocol.io/specification/2026-07-28/changelog) is the best source for the complete breaking-change list. It also records the new `resultType` field, the end of stream resumability, JSON Schema 2020-12 support, new error codes and the deprecation of Roots, Sampling, Logging and the old HTTP+SSE transport.

## Does stateless MCP mean the server cannot remember anything?

No. It means a later request cannot depend on invisible protocol-session memory.

Suppose a tool opens a browser and a later tool continues the same automation. The first response can return a random, opaque `browser_id`. The client passes that handle to the next call. The server resolves it in a Durable Object, database or another appropriate store after checking the caller and expiry. The workflow is stateful, but the MCP request is self-contained.

Choose the state mechanism by lifecycle:

- **One request:** keep state in local variables and return the final result.
- **Several immediate round trips:** return integrity-protected `requestState` with `input_required`. Bind it to the authenticated subject, original operation and expiry.
- **Long-running work:** use the [MCP Tasks extension](https://modelcontextprotocol.io/extensions/tasks/overview) and a durable `taskId`.
- **Business entities:** return an application handle such as `order_id`, `basket_id` or `document_id`, then authorize every later use.
- **Live change notifications:** use `subscriptions/listen`. The open SSE response is request-scoped, not a revived protocol session.

Do not put secrets or writable business state into a readable bearer handle. Prefer an opaque identifier or an authenticated, encrypted state token with strict size, audience and expiry limits.

## Do all MCP servers need a migration?

Every implementation should be audited, but the work differs.

| Your current server | Likely work | Priority |
| --- | --- | --- |
| Local stdio, no session-dependent features | Upgrade the SDK, schemas, per-request metadata and discovery behavior | Medium |
| Remote Streamable HTTP with no stored sessions | Add the modern wire contract, headers, validation, result types, cache metadata and compatibility tests | High |
| Remote server with `Mcp-Session-Id`, sticky routing or a session map | Externalize business state, add a dual-era path, then retire session infrastructure after client adoption | Highest |
| Legacy HTTP+SSE server | Move to Streamable HTTP and plan the stateless cutover | Highest |
| Server using sampling, roots or protocol logging | Plan replacements because these features are deprecated | High |

A server can be operationally stateless and still speak a legacy protocol. Conversely, a server can speak the new stateless protocol while storing durable application state. Audit the wire behavior and the data lifecycle separately.

## What should you change in your own MCP server?

1. **Inventory hidden connection state.** Search for session maps, sticky cookies, `Mcp-Session-Id`, transport objects reused across requests, per-connection tool lists and resumable SSE event stores. Classify each item as protocol state, transient request state or durable business state.
2. **Implement modern version discovery.** Servers must support `server/discover`. Return supported versions, capabilities, server info, instructions, `ttlMs` and `cacheScope`. Do not use self-reported server info as a security decision.
3. **Validate per-request metadata.** Require the protocol version and client metadata in `_meta`. On HTTP, require `MCP-Protocol-Version` and `Mcp-Method`, plus `Mcp-Name` for named calls. Reject header and body mismatches with `HeaderMismatch` instead of trusting whichever layer is more convenient.
4. **Make results modern and cacheable.** Add `resultType: "complete"` to ordinary results. Keep `tools/list` ordering deterministic. Set truthful `ttlMs` and `cacheScope`, especially when authorization changes the visible tool set.
5. **Replace implicit state with explicit handles.** Make handles unguessable, subject-bound, scoped and revocable. Make mutations idempotent. A retry after a broken stream must not charge, send or delete twice.
6. **Support both eras deliberately.** A dual-era server can serve modern requests statelessly and still answer legacy `initialize` traffic. Keep the compatibility path isolated, measured and covered by an expiry plan.
7. **Test the architecture, not only the handler.** Send consecutive calls to different instances behind real round-robin routing. Test missing and mismatched headers, unsupported versions, expired handles, replayed mutations, cancelled streams, retries and cross-tenant access.

The [Streamable HTTP specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http) defines the required request headers and mismatch behavior. The [versioning and compatibility matrix](https://modelcontextprotocol.io/specification/2026-07-28/basic/versioning) is essential before choosing a hard cutover or dual-era rollout.

## What did we change in Wavect's own MCP Worker?

We applied the same checklist to our Cloudflare Pages Function on 31 July 2026, then completed a direct cutover because we did not need to preserve legacy clients.

- **Stateless in process and protocol:** the handler keeps no in-memory session map and now accepts only self-contained `2026-07-28` requests.
- **Durable business state is already explicit:** commerce tools use quote IDs, order IDs, access tokens and idempotency keys instead of transport-session memory.
- **Modern discovery is live:** `server/discover` reports the supported version, capabilities, server info, instructions and cache metadata.
- **The HTTP contract is enforced:** requests require `MCP-Protocol-Version`, `Mcp-Method`, and `Mcp-Name` for tool calls, with header-body parity checks and explicit origin validation.
- **Results use the 2026 shape:** discovery, list and call results include `resultType`; deterministic list results also include truthful cache metadata.
- **The legacy lifecycle is gone:** `initialize`, `ping` and `notifications/initialized` return method-not-found responses instead of silently keeping an old contract alive.

This is why “we do not store MCP sessions” is not a sufficient migration check. Runtime topology, protocol version and response schema can be at different maturity levels. For our server, the business-state redesign was small. The wire contract, security checks and conformance suite were the real work.

![Kevin Riedl](/img/team/kevin.webp)

"Stateless MCP removes hidden transport memory. It does not remove durable workflows. Make state explicit, authenticated and safe to retry."

## How should a production rollout work?

1. Record current client versions, transports, session features and error rates.
2. Add conformance tests for the modern request and result shapes before changing production traffic.
3. Deploy a dual-era endpoint or a separate modern endpoint, depending on how tightly you control clients.
4. Route internal and canary clients to the modern path. Exercise different server instances on consecutive calls.
5. Observe unsupported-version errors, header mismatches, retries, latency, duplicate side effects and authorization failures.
6. Publish a client migration date and a rollback window. Do not delete legacy storage because one SDK test passed.
7. Remove sticky routing and session stores only after telemetry shows that legacy traffic and session-dependent features are gone.

Cloudflare now documents a stateless handler path and a staged migration for sessionful features in its [MCP SDK v2 migration guide](https://developers.cloudflare.com/agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/). Even if you use another runtime, the separation between protocol state and application state is a useful design model.

## What should you ask an MCP development partner?

- Which protocol versions and client eras will the deployed server support?
- Which state is request-local, which is durable and which is still tied to a transport session?
- How are state handles bound to identity, tenant, operation and expiry?
- How are retries made idempotent for payments, writes and external side effects?
- Can the team prove two consecutive calls work on different server instances?
- How are required HTTP headers validated against the JSON body at the origin and gateway?
- What is cached, for how long, and can private tool lists reach a shared cache?
- Which deprecated features remain, and what is the replacement plan?
- What evidence closes the legacy path: telemetry, client inventory, rollback test and removal date?

If a proposal says only “upgrade the SDK,” it is incomplete. The commercial deliverable should include a state inventory, compatibility decision, threat model, migration tests, canary evidence and rollback plan.

## Frequently asked questions

### Is MCP fully stateless now?

The 2026-07-28 protocol core is stateless. Applications can still keep durable state through explicit handles, storage, Tasks and request state.

### Is Streamable HTTP still used?

Yes. It remains the standard remote transport, but each message is now its own POST and the old GET stream and protocol-session behavior were removed.

### Do I still send initialize?

Not for a modern 2026-07-28 request. Use per-request metadata, and optionally call `server/discover`. A dual-era server may still answer `initialize` for legacy clients.

### Do I still need Redis or Durable Objects?

Not for MCP protocol sessions. You may still need durable storage for jobs, orders, browser instances, rate limits, locks or other application state.

### Can I remove sticky sessions immediately?

Only after modern traffic works across different instances and telemetry confirms no supported client or feature still depends on the legacy session path.

## Final thoughts

MCP is now stateless where it matters for protocol scalability: no initialize lifecycle, no Mcp-Session-Id and no hidden connection state required to understand a request. Your product may remain stateful. Move that state behind explicit, authorized handles; adopt discovery, required headers, modern result shapes and cache semantics; keep a measured compatibility path; then prove the migration behind round-robin routing before deleting legacy infrastructure.

## Primary sources

- [Model Context Protocol specification, 2026-07-28](https://modelcontextprotocol.io/specification/2026-07-28)
- [MCP 2026-07-28 key changes and deprecations](https://modelcontextprotocol.io/specification/2026-07-28/changelog)
- [MCP Streamable HTTP transport](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/streamable-http)
- [MCP server discovery specification](https://modelcontextprotocol.io/specification/2026-07-28/server/discover)
- [MCP tools, caching and multi-round-trip results](https://modelcontextprotocol.io/specification/2026-07-28/server/tools)
- [MCP Tasks extension](https://modelcontextprotocol.io/extensions/tasks/overview)
- [GitHub MCP Server support for the stateless specification](https://github.blog/changelog/2026-07-23-github-mcp-server-supports-the-next-mcp-specification/)
- [Cloudflare migration guide for stateless MCP handlers](https://developers.cloudflare.com/agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/)

## You may also like..

[**MCP is not a security boundary** Place identity, data policy and authorization at controls an agent cannot bypass.](/blog/mcp-security-boundary-data-level-access-control/) [**Enterprise MCP authorization architecture** Design OAuth, audience binding, delegated access and tenant isolation for a production MCP server.](/blog/enterprise-mcp-authorization-architecture/)

Agent engineering

## Continue through this cluster

Coding agents, MCP, context systems, evaluation and the controls required for dependable automation.

[Start with the cornerstone**Graph Engineering for AI Agents: When Does a Knowledge Graph Pay Off?**](/blog/graph-engineering-ai-agents/)

- [TrueForge Review: Is the Open-Source Agent Harness Production-Ready?](/blog/trueforge-agent-harness-review/)
- [Agent-Readable Websites: llms.txt, Markdown Mirrors and What Breaks](/blog/agent-readable-website-llms-txt-markdown-mirrors/)
- [Localized URLs Break hreflang: Keep One English Slug](/blog/english-slugs-vs-localized-urls-hreflang/)
- [Can an AI Agent Use Your Product, or Only Read About It?](/blog/can-an-ai-agent-use-your-product/)
- [Graft Review 2026: Do Agent Repo Maps Belong in Git?](/blog/graft-review-agent-repo-map/)

Inbox, without the noise

## Follow the work that matters to you

Get a short email when we publish something new. Follow the whole blog or only the problems you care about.

[**Back**](/blog/overview/)

[![Kevin Riedl](/img/team/kevin.webp)](/team/kevin-riedl/)

[Kevin Riedl](/team/kevin-riedl/) https://linkedin.com/in/wsdt

12 min read · 31 Jul 2026 Last reviewed July 31, 2026

[**Next**](/blog/yc-application-technical-readiness-checklist/)

New posts by email ×

×

Get new posts by email

A short email when we publish. Free, no tracking.

## Structured Data

```json
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@id": "https://wavect.io/#organization",
      "@type": [
        "Organization",
        "ProfessionalService",
        "LocalBusiness"
      ],
      "employee": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "founder": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "legalRepresentative": [
        {
          "@id": "https://wavect.io/team/kevin-riedl/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Kevin Riedl",
          "url": "https://wavect.io/team/kevin-riedl/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        },
        {
          "@id": "https://wavect.io/team/christof-jori/#person",
          "@type": "Person",
          "jobTitle": "Managing Director",
          "name": "Christof Jori",
          "url": "https://wavect.io/team/christof-jori/",
          "worksFor": {
            "@id": "https://wavect.io/#organization",
            "@type": [
              "Organization",
              "ProfessionalService",
              "LocalBusiness"
            ]
          }
        }
      ],
      "name": "Wavect GmbH",
      "subjectOf": {
        "@id": "https://wavect.io/verified-claims.json#dataset",
        "@type": "Dataset",
        "creator": {
          "@id": "https://wavect.io/#organization",
          "@type": [
            "Organization",
            "ProfessionalService",
            "LocalBusiness"
          ]
        },
        "description": "A machine-readable registry of quantitative and qualitative claims published by Wavect, with review dates, localized page appearances and public third-party citations where available.",
        "inLanguage": "en",
        "isAccessibleForFree": true,
        "license": "https://creativecommons.org/licenses/by/4.0/",
        "name": "Wavect verified publication claims",
        "url": "https://wavect.io/verified-claims.json"
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/team/kevin-riedl/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Kevin Riedl",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796365",
        "https://www.linkedin.com/in/wsdt",
        "https://github.com/wsdt"
      ],
      "url": "https://wavect.io/team/kevin-riedl/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/team/christof-jori/#person",
      "@type": "Person",
      "jobTitle": "Managing Director",
      "name": "Christof Jori",
      "sameAs": [
        "https://www.wikidata.org/wiki/Q139796367",
        "https://www.linkedin.com/in/jocr77/",
        "https://github.com/jo-chris"
      ],
      "url": "https://wavect.io/team/christof-jori/",
      "worksFor": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      }
    },
    {
      "@id": "https://wavect.io/#website",
      "@type": "WebSite",
      "inLanguage": [
        "en",
        "de",
        "es",
        "zh"
      ],
      "name": "Wavect",
      "potentialAction": {
        "@type": "SearchAction",
        "query-input": "required name=search_term_string",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://wavect.io/search/?q={search_term_string}"
        }
      },
      "publisher": {
        "@id": "https://wavect.io/#organization",
        "@type": [
          "Organization",
          "ProfessionalService",
          "LocalBusiness"
        ]
      },
      "url": "https://wavect.io/"
    },
    {
      "@id": "https://wavect.io/blog/mcp-stateless-server-migration-2026/#webpage",
      "@type": "WebPage",
      "dateModified": "2026-08-01",
      "inLanguage": "en",
      "isPartOf": {
        "@id": "https://wavect.io/#website",
        "@type": "WebSite"
      },
      "lastReviewed": "2026-08-01",
      "url": "https://wavect.io/blog/mcp-stateless-server-migration-2026/"
    }
  ]
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "abstract": "Yes. The MCP 2026-07-28 specification makes the protocol core stateless: it removes the initialize and initialized handshake, removes Mcp-Session-Id, and requires each request to carry its protocol version, client information and capabilities. Streamable HTTP now uses one POST per message, with MCP-Protocol-Version and Mcp-Method headers plus Mcp-Name for tool, resource and prompt calls. This does not make your application data stateless. Durable workflows should use explicit, authenticated handles, the Tasks extension, requestState for multi-round-trip input and normal storage. For an existing remote server, inventory hidden session state, add server/discover, validate header and body parity, make list results deterministic and cache-aware, keep a tested legacy path while clients migrate, and run conformance, authorization, replay and round-robin tests before removing old infrastructure.",
  "articleBody": " Blog overview/AI and agents/Agent engineering Is MCP Stateless Now? What to Change in Your Own MCP Server TL;DR Yes. The MCP 2026-07-28 specification makes the protocol core stateless: it removes the initialize and initialized handshake, removes Mcp-Session-Id, and requires each request to carry its protocol version, client information and capabilities. Streamable HTTP now uses one POST per message, with MCP-Protocol-Version and Mcp-Method headers plus Mcp-Name for tool, resource and prompt calls. This does not make your application data stateless. Durable workflows should use explicit, authenticated handles, the Tasks extension, requestState for multi-round-trip input and normal storage. For an existing remote server, inventory hidden session state, add server/discover, validate header and body parity, make list results deterministic and cache-aware, keep a tested legacy path while clients migrate, and run conformance, authorization, replay and round-robin tests before removing old infrastructure. Yes. MCP is stateless at the protocol layer as of specification version 2026-07-28. The initialize handshake and Mcp-Session-Id are gone. Each request now carries the protocol version, client identity and capabilities it needs. A remote request can reach any healthy server instance without sticky routing. That answer needs one qualification: stateless MCP does not mean stateless software. Your shopping basket, browser job, approval flow or paid order may still need durable state. The difference is that this state must be explicit, addressable and secured by your application instead of hiding inside an MCP transport session. This guide owns the transport and migration question. For permissions and tenant isolation, use our separate enterprise MCP authorization architecture. For the deeper question of where protection must be enforced, read why MCP is not the complete security boundary. Once the wire contract is ready, use our MCP Cloud vs Manufact Cloud hosting guide to compare managed deployment, governance, pricing and exit paths. What is the direct answer? MCP 2026-07-28 is a stateless, self-contained request protocol. Protocol state is gone. Application state is still allowed and often necessary. The official specification now lists “stateless, self-contained requests” and “per-request capability negotiation” as base protocol properties. On Streamable HTTP, every message is a new POST. The response is either one JSON object or a request-scoped SSE stream. The old standalone GET stream, protocol session, Mcp-Session-Id and resumable SSE mechanism are not part of this revision. What changed in MCP 2026-07-28? Concern2025-11-25 and earlier2026-07-28 Startupinitialize, then notifications/initializedNo initialization handshake; optional server/discover Protocol sessionServer may mint Mcp-Session-IdNo protocol session or session ID Request contextVersion and capabilities negotiated onceVersion, client info and capabilities travel in request _meta HTTP routingSession affinity or shared session storage may be neededAny instance can process a self-contained request HTTP metadataGateway often needs to inspect the JSON bodyMCP-Protocol-Version, Mcp-Method and sometimes Mcp-Name are required Server-to-client inputServer could issue a request over SSEReturn input_required; client retries with inputResponses and optional requestState Long-running workExperimental task behavior in coreOfficial opt-in Tasks extension with durable task handles ListsChange notifications and pollingDeterministic order plus required ttlMs and cacheScope The official 2026-07-28 changelog is the best source for the complete breaking-change list. It also records the new resultType field, the end of stream resumability, JSON Schema 2020-12 support, new error codes and the deprecation of Roots, Sampling, Logging and the old HTTP+SSE transport. Does stateless MCP mean the server cannot remember anything? No. It means a later request cannot depend on invisible protocol-session memory. Suppose a tool opens a browser and a later tool continues the same automation. The first response can return a random, opaque browser_id. The client passes that handle to the next call. The server resolves it in a Durable Object, database or another appropriate store after checking the caller and expiry. The workflow is stateful, but the MCP request is self-contained. Choose the state mechanism by lifecycle: One request: keep state in local variables and return the final result. Several immediate round trips: return integrity-protected requestState with input_required. Bind it to the authenticated subject, original operation and expiry. Long-running work: use the MCP Tasks extension and a durable taskId. Business entities: return an application handle such as order_id, basket_id or document_id, then authorize every later use. Live change notifications: use subscriptions/listen. The open SSE response is request-scoped, not a revived protocol session. Do not put secrets or",
  "articleSection": "Engineering",
  "author": {
    "@id": "https://wavect.io/team/kevin-riedl/#person",
    "@type": "Person",
    "name": "Kevin Riedl",
    "sameAs": [
      "https://www.wikidata.org/wiki/Q139796365",
      "https://www.linkedin.com/in/wsdt",
      "https://github.com/wsdt"
    ],
    "url": "https://wavect.io/team/kevin-riedl/"
  },
  "dateModified": "2026-07-31",
  "datePublished": "2026-07-31",
  "description": "Yes. The MCP 2026-07-28 specification makes the protocol core stateless: it removes the initialize and initialized handshake, removes Mcp-Session-Id, and requires each request to carry its protocol version, client information and capabilities. Streamable HTTP now uses one POST per message, with MCP-Protocol-Version and Mcp-Method headers plus Mcp-Name for tool, resource and prompt calls. This does not make your application data stateless. Durable workflows should use explicit, authenticated handles, the Tasks extension, requestState for multi-round-trip input and normal storage. For an existing remote server, inventory hidden session state, add server/discover, validate header and body parity, make list results deterministic and cache-aware, keep a tested legacy path while clients migrate, and run conformance, authorization, replay and round-robin tests before removing old infrastructure.",
  "headline": "Is MCP Stateless Now? Your Server Migration Checklist",
  "image": "https://wavect.io/img/blog/headers/header_mcp-stateless-server-migration-2026.svg",
  "inLanguage": "en",
  "keywords": "stateless MCP server, MCP 2026-07-28 migration, Streamable HTTP",
  "mainEntityOfPage": {
    "@id": "https://wavect.io/blog/mcp-stateless-server-migration-2026/",
    "@type": "WebPage"
  },
  "publisher": {
    "@id": "https://wavect.io/#organization",
    "@type": [
      "Organization",
      "ProfessionalService",
      "LocalBusiness"
    ]
  },
  "url": "https://wavect.io/blog/mcp-stateless-server-migration-2026/",
  "wordCount": 2177
}
```

```json
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "item": "https://wavect.io/",
      "name": "Home",
      "position": 1
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/overview/",
      "name": "Blog overview",
      "position": 2
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/topics/ai-agents/",
      "name": "AI and agents",
      "position": 3
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/clusters/agent-engineering/",
      "name": "Agent engineering",
      "position": 4
    },
    {
      "@type": "ListItem",
      "item": "https://wavect.io/blog/mcp-stateless-server-migration-2026/",
      "name": "Is MCP Stateless Now? Server Migration Guide 2026 | ",
      "position": 5
    }
  ]
}
```
