The MCP 2026-07-28 spec is final in the sense that matters to builders. The official MCP blog announced the release on July 28, 2026, the specification repository tags it as the stable release, and the spec site names it the current version. It is no longer a release candidate, even though pages written before that date still say it is.
The change is simple to state. MCP stopped being a stateful protocol. The initialize handshake and the Mcp-Session-Id header are gone, and every request carries what the server needs. If you run a remote server, you must implement server/discover, validate new routing headers, add cache hints to list results, and move mid-call questions to Multi Round-Trip Requests. Keep serving the old version too, because a legacy client cannot talk to a modern-only server.
Building with MCP for creative work?
Oakgen runs an MCP server for image, video and audio generation. See what it exposes and how teams connect an agent to it.
The short version
| Question | Short answer | Source |
|---|---|---|
| Is it final? | Released July 28, 2026. GitHub marks it the stable release and Latest. The spec site calls it Current. | MCP blog, Jul 28 2026 and GitHub releases |
| Biggest change | No handshake and no protocol session. Every request is self-describing. | Changelog |
| New required method | server/discover, which servers must implement. Clients may skip it. | Discovery page |
| New HTTP headers | Mcp-Method on every request, Mcp-Name on named calls, both checked against the body. | Streamable HTTP page |
| Server asks the user something | Return input_required and let the client retry (MRTR). | MRTR page |
| Next release | Official plan is 2027-03-30. Some secondary pages say December 15, 2026. | MCP blog, Nov 11 2026 |
Disclosure. Oakgen is our product and we do not make MCP. This explainer is written from the official pages, and Oakgen appears only in two short notes and the banners.
Is it final or a release candidate?
It is released, and the sources that disagree are mostly out of date rather than wrong. Here is every status signal we found, dated.
| Source | Date | What it says | How to read it |
|---|---|---|---|
| MCP blog, release candidate post | May 21, 2026 | Candidate locked, final to ship July 28 | Correct then, stale now |
| GitHub release 2026-07-28 RC | May 29, 2026 | Marked Pre-release, "this specification is not final" | Correct then, stale now |
| Agentic AI Foundation explainer | Jul 21, 2026 | Covers the candidate, says check details against the final text | Pre-final. Calls the deprecations "proposed" |
| MCP blog, release post | Jul 28, 2026 | "Officially pushing the release button" | Primary, final |
| GitHub release 2026-07-28 | Jul 28, 2026 | "Marks the stable release", tagged Latest | Primary, final |
| Spec site, versioning page | Read Nov 12, 2026 | "The current protocol version is 2026-07-28" | Primary, current |
One wording trap is worth knowing. The spec site's versioning page defines three labels. Draft is in progress, Current is ready for use, and Final means past, complete specifications that will not change. By that vocabulary 2026-07-28 is Current, not Final, because it can still receive backwards compatible changes. Anyone who says "final" means "shipped".
Who this is for
You maintain a remote MCP server and are tired of sticky sessions, or you build a client or gateway and need to know what changes on the wire. If you only use MCP servers through a desktop app, the advice is to update the app.
How we checked this
On November 12, 2026 we opened the 2026-07-28 changelog and the Streamable HTTP, MRTR, caching, discovery, versioning and deprecated-features pages on modelcontextprotocol.io, the GitHub releases page, the official MCP blog posts, and SDK release notes for TypeScript, Python, Go and Ruby.
We did not run a conformance suite or test any SDK. Behavior statements are the spec's own wording, and SDK versions move quickly, so re-check them before you pin.
What changed, in plain words
No handshake, no session
The changelog removes protocol-level sessions and the Mcp-Session-Id header (SEP-2567), and removes the initialize and notifications/initialized exchange (SEP-2575). Each request now carries its protocol version and client capabilities in _meta. Clients should also send their identity, and servers should return theirs in each result's _meta.
A request now looks like this on the wire, using the official blog's example.
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search","arguments":{"q":"otters"},
"_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}
In the official post's words, any request can land on any instance behind a plain round-robin load balancer. If your app needs state across calls, mint an explicit handle, such as a basket id, and let the model pass it back as a normal argument.
Discovery is a method, not a handshake
Servers must implement server/discover. It returns supportedVersions, capabilities, optional instructions and a self-reported serverInfo, with caching hints. Clients may call it first, but are not required to. They can send any request directly and handle UnsupportedProtocolVersionError if the version is wrong.
On stdio, a client that supports old and new servers should probe with server/discover first.
Server questions become Multi Round-Trip Requests
A server can no longer open a request to the client mid-call. For elicitation/create, sampling/createMessage and roots/list, the server now answers with resultType: "input_required" plus inputRequests, and the client retries the original call with inputResponses. The MRTR page allows this only on tools/call, resources/read and prompts/get.
The part developers miss is requestState. It is an opaque string the server hands out and the client echoes back unchanged. The spec says servers must treat it as attacker-controlled input and protect its integrity with an HMAC or AEAD whenever it influences authorization, resource access or business logic. It suggests binding it to the principal, a short expiry and a digest of the originating request.
The spec adds that this bounds replay but does not make state single-use. Enforce one-time redemption on the server.
Routing headers and header validation
Every POST must carry MCP-Protocol-Version, matching the version in _meta. Mcp-Method is required on all requests. Mcp-Name is required on tools/call, resources/read and prompts/get, taken from params.name or params.uri. Non-ASCII values use a Base64 sentinel encoding.
Servers must reject any request whose headers disagree with its body, with HTTP 400 and JSON-RPC error -32020 (HeaderMismatch). The reason is that a load balancer might route on the header while the server executes on the body.
An optional x-mcp-header annotation on a tool parameter mirrors its value into an Mcp-Param-{Name} header. It allows only string, integer and boolean parameters, so number is out. Clients on Streamable HTTP must drop a tool whose annotation is invalid.
Cacheable lists
Complete results from server/discover, tools/list, prompts/list, resources/list, resources/templates/list and resources/read must carry ttlMs (zero or more) and cacheScope, either public or private. Servers should also return tools in a deterministic order. A private result must not be shared across authorization contexts, and MRTR retry results must not be cached.
Everything else
Change notifications move to a single subscriptions/listen stream that clients opt into per type. Tasks leave the core and become the io.modelcontextprotocol/tasks extension, with tasks/get polling and a new tasks/update (SEP-2663). ping, logging/setLevel and SSE resumability with Last-Event-ID are removed, so a dropped stream loses the in-flight request and the client must re-issue it with a new id.
On authorization, clients must validate the iss parameter (RFC 9207) before redeeming a code, must set application_type in Dynamic Client Registration, and must bind credentials to the issuer that created them. Dynamic Client Registration is deprecated in favor of Client ID Metadata Documents.
A missing resource now returns -32602 instead of -32002, and MCP-reserved error codes sit in -32020 to -32099. Every result carries a required resultType.
Before and after, change by change
Keep this table open while you migrate. "Before" is 2025-11-25 behavior as described in the 2026-07-28 changelog and transport pages.
| Area | Before (2025-11-25) | After (2026-07-28) | What you do |
|---|---|---|---|
| Connection start | initialize then notifications/initialized | Removed. Version and capabilities ride in _meta on every request | Delete handshake state. Read _meta per request |
| Session | Mcp-Session-Id, DELETE to end | Removed. Modern-only servers ignore the header | Mint explicit handles for app state |
| Capability discovery | Exchanged once in the handshake | server/discover, mandatory on servers, optional for clients | Implement it, return versions, capabilities, identity |
| Server asks the client | elicitation/create, sampling/createMessage, roots/list on an open stream | input_required result, client retries with inputResponses | Rewrite those tools as retryable calls and sign requestState |
| Routing | Parse the JSON body | Mcp-Method, Mcp-Name, MCP-Protocol-Version headers, validated against the body | Add header checks and -32020 errors |
| Change notifications | HTTP GET stream, resources/subscribe | subscriptions/listen stream, opt in per type | Rework listeners or set list changes to false |
| Stream recovery | Last-Event-ID resumability | Removed. Re-issue the request with a new id | Make tool calls safe to retry |
| List caching | No hints | Required ttlMs and cacheScope, deterministic order | Add both fields to every list and read result |
| Long-running work | Experimental core Tasks | io.modelcontextprotocol/tasks extension, tasks/get and tasks/update, no tasks/list | Migrate if you shipped the experimental API |
| Client registration | DCR | DCR deprecated, Client ID Metadata Documents preferred, application_type required | Plan the move. Set application_type now |
| Roots, Sampling | Core client features | Deprecated, still working, earliest removal after July 28, 2027 | Do not adopt in new code |
| Transport | Streamable HTTP, deprecated HTTP+SSE still described | HTTP+SSE reclassified as Deprecated | Leave it if you must, plan the exit |
See how a creative agent talks to a real MCP server
Oakgen's MCP page lists the tools an agent can call for images, video and audio, and the limits that apply.
Migration checklist
Our own checklist, built from the changelog and the transport, MRTR and caching pages.
Server developers
- Remove every code path that reads or writes
Mcp-Session-Id, and every assumption thatinitializeran first. - Read
io.modelcontextprotocol/protocolVersionfrom_metaon each request, and returnUnsupportedProtocolVersionErrorwith asupportedlist when it is not one you serve. - Implement
server/discoverwithsupportedVersions,capabilities,instructionsif useful, andserverInfo. - Require
MCP-Protocol-Version,Mcp-Methodand, fortools/call,resources/readandprompts/get,Mcp-Name. Return 400 and-32020when a header is missing or disagrees with the body. - Add
resultType,ttlMsandcacheScopeto complete results, and returntools/listin a stable order. Useprivatefor anything user-specific. - Replace server-initiated elicitation with
input_requiredresults. SignrequestStatewith an HMAC or AEAD, and bind it to the user, a short expiry and the originating request. - Make tool calls safe to retry. A broken stream can no longer resume.
- If you used
x-mcp-header, check every annotated parameter is a string, integer or boolean at a statically reachable path. - Decide on dual-era support, and test one legacy and one modern client against the same endpoint.
Client and host developers
- Send version, capabilities and identity in
_metaon every request, plus theMCP-Protocol-VersionandMcp-Methodheaders, andMcp-Namewhere it applies. Treat a result withoutresultTypeascomplete. - Mirror
x-mcp-headerparameters intoMcp-Param-*headers, and exclude tools with invalid annotations. - Handle
input_required. Gather input, retry with a new request id, echorequestStatebyte for byte, and never cache the retry. - Honor
ttlMsandcacheScope, checking freshness on use. Re-issue broken requests with a new id. - Match
-32602for a missing resource, validateiss, key stored credentials by issuer, and setapplication_typeif you still register dynamically. - On stdio, probe with
server/discoverfirst, and fall back toinitializeon any error that is not a recognized modern one.
Gateway and platform teams
- Route and rate limit on
Mcp-MethodandMcp-Name, but only after confirmingMCP-Protocol-Versionsays the request needs header and body validation. - Forward unknown
Mcp-Param-*headers untouched, and never share cachedprivateresults across authorization contexts.
What the SDKs do
The July 28 release post listed the TypeScript, Python, Go and C# SDKs as ready, with Rust in beta. The official SDK page on November 12, 2026 lists Rust and Ruby as Tier 1 too. Support is not automatic.
| SDK | What we found | Source |
|---|---|---|
| TypeScript | v2 packages. Release 2.4.0 of Oct 23, 2026 notes a number parameter with x-mcp-header is rejected, and the server answers -32020 | TypeScript SDK releases |
| Python | v2 renames FastMCP to MCPServer. Release v2.3.0 of Oct 2, 2026 fails registration for an invalid x-mcp-header | Python SDK releases, beta post |
| Go | v1.7.0 serves 2026-07-28 over HTTP only when StreamableHTTPOptions.Stateless is true | Go SDK v1.7.0 |
| Ruby | Tier 1 assessment dated Aug 15, 2026 says v1.2.0 implemented the revision 18 days after the spec | Issue 3247 |
The Python rename and the TypeScript opt-in note come from the June 29 beta post, so re-check them against current release notes. The official Python tutorial requires Python SDK 2.0.0 or higher, and library authors who want to stay on v1 were told to cap the dependency, for example mcp>=1.27,<2.
Where the official sources disagree with each other
Two small conflicts sit inside the official material.
- HTTP+SSE timing. The July 28 blog says the legacy transport has a "year-long offramp". The registry says earliest removal is "three months after SEP-2596 reaches Final". Plan around neither date.
- Dynamic Client Registration timing. The blog says it "will be removed in a future version". The registry gives the first revision released on or after July 28, 2027, and adds that removal is a Core Maintainer decision that may come later.
Our inference, not an official statement. The registry's removal date is a floor, not a schedule. On the six-month calendar, the first release after July 28, 2027 would be the September 2027 one in the official timeline graphic.
How a creative team would apply this
Most creative teams will never touch the wire format. They will notice that a tool can now pause to ask the user to confirm something, such as a cost, before it acts, because MRTR makes that a protocol pattern. Our MCP security checklist for creative teams covers the approval side, and the MCP versus API comparison covers when you need MCP at all.
A note on our own server. The Oakgen repository runs its MCP endpoint as a stateless JSON transport with no session ids, on the TypeScript SDK 1.x line. We have not migrated it to 2026-07-28, so this post does not claim Oakgen speaks the new revision.
Common mistakes
- Treating the release candidate posts as current. Several still rank. Check the date and the status line.
- Shipping a modern-only server too early. A legacy client against it fails.
- Trusting
requestState. It passes through the client, so unsigned state is attacker-controlled input. - Caching a
privatelist for everyone. That leaks tool lists across users. - Putting a
numberparameter underx-mcp-header. Clients drop the tool, and some SDKs refuse it at registration. - Upgrading the SDK and assuming the wire changed. The Go and TypeScript notes show the new revision can be an explicit opt-in.
Decision framework
| Your situation | Move now | Can wait |
|---|---|---|
| Remote server with sticky sessions or a shared session store | Migrate and serve both eras | Session code on legacy paths |
| Remote server, already stateless JSON, no server-initiated requests | Add server/discover, headers, cache hints | MRTR |
| Server that uses elicitation or sampling | Plan the MRTR rewrite, stop adopting sampling | Removing sampling, due no earlier than mid-2027 |
| stdio-only local server | Update the SDK when it supports the revision | Header work, which is HTTP-only |
| Client or agent host | Dual-era client with discover probe | Subscriptions rework if you do not use list changes |
What I would do
I would ship dual-era first. Keep the legacy path alive, add the modern path next to it, and test one old and one new client against the same URL. The spec's own matrix shows that a dual-era server works with legacy and modern clients alike.
Next I would take the cheap wins. server/discover, header validation and ttlMs are small. MRTR is the real rewrite, so I would do it tool by tool, starting with tools that need user confirmation.
I would not use Roots, Sampling or Logging in new code, and I would not rush removing old code either, since no removal can come before July 28, 2027. For what comes after, read our post on the six-month MCP release cycle, and for the gateway side the MCP gateways explainer.
Plan creative work with an agent, then generate the assets
Start a brief in Oakgen Agent Chat, review the plan, and generate images, video and audio from the same workspace.
Connect an agent to Oakgen's MCP server
If you are wiring an agent to a creative toolset, start from the Oakgen MCP page and pick the client you already use.
Frequently asked questions
Is the MCP 2026-07-28 specification final or a release candidate?
It is released. The official MCP blog announced it on July 28, 2026, the specification repository's GitHub release for 2026-07-28 says it marks the stable release and is tagged Latest, and the spec site's versioning page names 2026-07-28 as the current protocol version. The release candidate was a separate pre-release dated May 29, 2026 on GitHub. Pages written before July 28, including the official release candidate post and an Agentic AI Foundation explainer dated July 21, still describe it as a candidate. Those are out of date on status. One wording detail is that the site's own versioning page reserves the label Final for past revisions and calls 2026-07-28 Current.
Does my existing MCP server break because of the new spec?
Not on its own. The official SDK beta post says that nothing breaks on July 28 for existing clients and servers, because that date only publishes the normative text. What breaks is the pairing of a legacy client (one that sends initialize) with a server that supports only 2026-07-28. The spec's compatibility matrix says that combination fails, and a modern-only client talking to a legacy server fails too. The fix is a dual-era implementation that serves both until your clients have moved.
What replaced the initialize handshake and the Mcp-Session-Id header?
Every request now carries its protocol version, client capabilities and (as a SHOULD) client identity in its _meta field, and over HTTP the version also goes in the MCP-Protocol-Version header. A new server/discover method, which servers must implement and clients may call, returns supported versions, capabilities and identity. State that must survive between calls is carried by explicit handles the server mints and the model passes back as ordinary tool arguments.
What happens to elicitation and sampling in a stateless protocol?
Servers can no longer send requests to the client on an open stream. Under Multi Round-Trip Requests (SEP-2322), the server answers a tools/call, resources/read or prompts/get with an input_required result that lists what it needs, and the client retries the original request with the answers in inputResponses. Roots, Sampling and Logging are deprecated and still work for at least twelve months. The registry lists the earliest removal as the first revision released on or after July 28, 2027.
Which SDK versions support MCP 2026-07-28?
The official release post of July 28, 2026 lists the TypeScript, Python, Go and C# SDKs as supporting it, with the Rust SDK in beta. When we read the SDK page on November 12, 2026 it listed Rust and Ruby as Tier 1 as well. Check each SDK's release notes, because adoption is not automatic. For example, the Go SDK v1.7.0 notes say HTTP serves 2026-07-28 only when StreamableHTTPOptions.Stateless is true, and the official Python server tutorial requires Python SDK 2.0.0 or higher.
When is the next MCP specification release?
The official MCP blog post of November 11, 2026 says specification releases move to a six-month schedule, generally the last Tuesday of March and September, and targets March 30, 2027 for version 2027-03-30. Some secondary pages, including a dev.to weekly dated November 11, 2026 and a GitHub issue from August 2026, say the next release is December 15, 2026. We did not find that date on an official MCP page, so treat the official post as the current plan.
Do I have to move from Dynamic Client Registration to Client ID Metadata Documents now?
No. The changelog deprecates Dynamic Client Registration in favor of Client ID Metadata Documents, but says it remains available for authorization servers that do not support them. The deprecated features registry lists the earliest removal as the first revision released on or after July 28, 2027, and says actual removal is a Core Maintainer decision that may happen later. If you keep using DCR, the new rule is that clients must set an appropriate application_type.
What is the first thing to change in a remote MCP server?
Stop reading session state from the transport. Remove any dependency on Mcp-Session-Id and on the initialize handshake, accept the per-request _meta fields, implement server/discover, validate Mcp-Method, Mcp-Name and MCP-Protocol-Version against the request body, and add ttlMs and cacheScope to list results. Then decide whether to stay dual-era. That order gets you to a server that runs behind a plain round-robin load balancer.
Sources
- Model Context Protocol, 2026-07-28 changelog, Key Changes (read 2026-11-12)
- Model Context Protocol, Specification 2026-07-28 (read 2026-11-12)
- Model Context Protocol, Versioning, Draft, Current and Final revisions (read 2026-11-12)
- Model Context Protocol, Versioning and Compatibility, 2026-07-28 (read 2026-11-12)
- Model Context Protocol, Streamable HTTP transport, 2026-07-28 (read 2026-11-12)
- Model Context Protocol, Multi Round-Trip Requests, 2026-07-28 (read 2026-11-12)
- Model Context Protocol, Caching, 2026-07-28 (read 2026-11-12)
- Model Context Protocol, Discovery, server/discover, 2026-07-28 (read 2026-11-12)
- Model Context Protocol, Deprecated Features registry, 2026-07-28 (read 2026-11-12)
- MCP blog, The 2026-07-28 Specification, Jul 28 2026 (read 2026-11-12)
- MCP blog, The 2026-07-28 MCP Specification Release Candidate, May 21 2026 (read 2026-11-12)
- MCP blog, Beta SDKs for the 2026-07-28 release candidate, Jun 29 2026 (read 2026-11-12)
- MCP blog, A More Predictable Release Cycle for MCP, Nov 11 2026 (read 2026-11-12)
- GitHub, modelcontextprotocol releases, 2026-07-28 and 2026-07-28 RC (read 2026-11-12)
- Model Context Protocol, official SDKs and tiers (read 2026-11-12)
- Model Context Protocol, Build an MCP server, 2026-07-28 docs (read 2026-11-12)
- GitHub, MCP Go SDK v1.7.0 release notes (read 2026-11-12)
- GitHub, MCP TypeScript SDK releases, 2.4.0 of Oct 23 2026 (read 2026-11-12)
- GitHub, MCP Python SDK releases, v2.3.0 of Oct 2 2026 (read 2026-11-12)
- Agentic AI Foundation, MCP 2026-07-28 What's Changing and How to Migrate, Jul 21 2026 (read 2026-11-12)
- GitHub, Ruby SDK Tier 1 assessment, issue 3247, Aug 15 2026 (read 2026-11-12)
- dev.to, AI Weekly, Fable 5.2, Muse Ember, and TPU 8i Max, Nov 11 2026 (read 2026-11-12)

