# MCP protocol `2026-07-28` — full delta vs `2025-11-25`

> `mcp-server-builder` v`1.0.0` · covers spec revision `2026-07-28` · last
> verified **2026-07-29**

**Sources**
- Announcement — https://claude.com/blog/bringing-mcp-2026-07-28-to-claude
- Changelog (this document's basis) — https://modelcontextprotocol.io/specification/2026-07-28/changelog
- Spec — https://modelcontextprotocol.io/specification/2026-07-28/
- Deprecated registry — https://modelcontextprotocol.io/specification/2026-07-28/deprecated
- Feature lifecycle policy — https://modelcontextprotocol.io/community/feature-lifecycle

SEP numbers below link to `github.com/modelcontextprotocol/modelcontextprotocol/pull/<n>`.

The headline: **MCP stopped being a bidirectional stateful protocol and became a
request/response model**, so servers can run on serverless and edge infrastructure
with no session management.

---

## Major changes

### 1. Sessions removed (SEP-2567)
Protocol-level sessions and the `Mcp-Session-Id` header are gone from Streamable
HTTP. `tools/list`, `resources/list`, `prompts/list` **no longer vary per
connection**.

Servers needing cross-call state mint an explicit **handle** and pass it as an
ordinary tool argument. There is no ambient per-connection state to lean on.

### 2. Stateless: no handshake (SEP-2575)
`initialize` and `notifications/initialized` are removed. Every request carries
its own context in `_meta`:

| `_meta` key | Direction | Requirement |
|---|---|---|
| `io.modelcontextprotocol/protocolVersion` | client → server | on every request |
| `io.modelcontextprotocol/clientCapabilities` | client → server | on every request |
| `io.modelcontextprotocol/clientInfo` | client → server | SHOULD |
| `io.modelcontextprotocol/serverInfo` | server → client | SHOULD, in every result's `_meta` |
| `io.modelcontextprotocol/logLevel` | client → server | per-request log level |

Version mismatch returns `UnsupportedProtocolVersionError`.

### 3. `server/discover` is mandatory (SEP-2575)
Every server **MUST** implement `server/discover`, advertising supported protocol
versions, capabilities and identity. Clients **MAY** call it before anything else
for up-front version selection, or use it as a backward-compatibility probe on
stdio.

Note the late schema move: `serverInfo` lives in the result's **`_meta`**, not in
the `DiscoverResult` body (spec PR #3002).

### 4. `subscriptions/listen` replaces subscribe + GET (SEP-2575)
The HTTP GET endpoint and `resources/subscribe`/`resources/unsubscribe` are gone.
One long-lived POST-response stream carries opted-in change notifications.

Clients opt in per type: `toolsListChanged`, `promptsListChanged`,
`resourcesListChanged`, `resourceSubscriptions`. The server acknowledges and tags
each notification with `io.modelcontextprotocol/subscriptionId`.

**Request-scoped** notifications (`notifications/progress`,
`notifications/message`) still flow on the response stream of the request they
belong to — *not* on the `subscriptions/listen` stream.

### 5. `ping`, `logging/setLevel`, roots-changed removed (SEP-2575)
Log level is now per-request via `io.modelcontextprotocol/logLevel` in `_meta`.
Servers **MUST NOT** emit `notifications/message` for a request that did not
include that field.

### 6. Tasks moved out of core (SEP-2663)
Now the official extension `io.modelcontextprotocol/tasks`:

| Before | After |
|---|---|
| `tasks/result` (blocking) | `tasks/get` (polling) |
| — | `tasks/update` (client → server input) |
| `tasks/list` | removed |
| per-request opt-in | servers may return task handles unsolicited |

### 7. MRTR replaces server-initiated requests (SEP-2322)
Multi Round-Trip Requests. A server that needs more information does **not** call
back into the client. It returns:

```json
{
  "resultType": "input_required",
  "inputRequests": [ /* what it needs */ ]
}
```

The client retries **the original request** with `inputResponses`. This is what
replaces `roots/list`, `sampling/createMessage` and `elicitation/create`.

A server that must correlate an elicitation across retries encodes its own
identifier in `requestState` — `elicitationId` and
`notifications/elicitation/complete` (both added in `2025-11-25`) are gone.

### 8. `resultType` required on all results (SEP-2322)
`"complete"` for ordinary results, `"input_required"` for MRTR interim results.
Clients **MUST** treat a missing field from an earlier-protocol server as
`"complete"`.

### 9. No SSE resumability (SEP-2575)
`Last-Event-ID` and SSE event IDs are gone from Streamable HTTP. A broken
response stream loses the in-flight request; the client **MUST** re-issue it as a
new request with a **new request id**. Design tools to be safely retryable.

---

## Minor changes worth acting on

1. **`extensions` field** added to `ClientCapabilities` and `ServerCapabilities`.
2. **OpenTelemetry trace context** conventions documented for `_meta`:
   `traceparent`, `tracestate`, `baggage` (SEP-414).
3. **Deterministic `tools/list` order** — SHOULD, enables client-side caching and
   improves LLM prompt-cache hit rate.
4. **Standard HTTP request headers** `Mcp-Method` and `Mcp-Name` required on
   Streamable HTTP POST; custom headers from tool parameters via `x-mcp-header`
   (SEP-2243).
5. **`CacheableResult`** — `ttlMs` and `cacheScope` now **required** on results of
   `tools/list`, `prompts/list`, `resources/list`, `resources/read`,
   `resources/templates/list`. `ttlMs` is a freshness hint in milliseconds;
   `cacheScope` is `"public"` or `"private"` and controls whether shared
   intermediaries may cache. Complements `listChanged` (SEP-2549).
6. **Resource-not-found error code** `-32002` → **`-32602`** (Invalid Params).
7. **Auth**: authorization servers SHOULD include `iss` (RFC 9207); clients
   **MUST** validate a present `iss` against the recorded issuer before redeeming
   the code (SEP-2468).
8. **DCR**: clients must specify `application_type` to avoid OIDC redirect-URI
   conflicts (SEP-837).
9. **Credential binding**: clients MUST key persisted credentials by issuer
   identifier, MUST NOT reuse across authorization servers, MUST re-register when
   the authorization server changes (SEP-2352).
10. **Schemas loosened** — `inputSchema`/`outputSchema` accept any JSON Schema
    2020-12 keyword; `structuredContent` accepts any JSON value. Adds `$ref`
    resolution requirements and composition-keyword resource bounds (SEP-2106).

### Error-code allocation policy

| Range | Owner |
|---|---|
| `-32000` … `-32019` | implementation-defined (existing SDK usage grandfathered) |
| `-32020` … `-32099` | **reserved for the MCP specification** |

Renumbered in this revision:

| Error | Old | New |
|---|---|---|
| `HeaderMismatch` | `-32001` | `-32020` |
| `MissingRequiredClientCapability` | `-32003` | `-32021` |
| `UnsupportedProtocolVersion` | `-32004` | `-32022` |

`HeaderMismatchError` was added to the schema (previously only in transport prose).

---

## Deprecated — do not adopt in new code

A formal **feature lifecycle policy** now exists (Active / Deprecated / Removed)
with a **minimum twelve-month deprecation window** and a public registry at
`/specification/2026-07-28/deprecated`.

| Feature | Suggested migration |
|---|---|
| **Roots** (SEP-2577) | pass directories/files via tool parameters, resource URIs, or server config |
| **Sampling** (SEP-2577) | integrate directly with the LLM provider API |
| **Logging** (SEP-2577) | log to `stderr` (stdio) or use OpenTelemetry |
| **HTTP+SSE transport** (SEP-2596) | Streamable HTTP |
| `includeContext: "thisServer"` / `"allServers"` (SEP-2596) | omit the field, or `"none"` |
| **OAuth 2.0 DCR / RFC 7591** (PR #2858) | Client ID Metadata Documents (DCR stays for AS that lack CIMD) |

---

## New official extensions

| Extension | What it gives |
|---|---|
| **MCP Apps** | server renders interactive UI directly in the conversation |
| **MCP Tasks** (`io.modelcontextprotocol/tasks`) | long-running work without core protocol changes |

Both ship under a versioned extensions framework, declared through the new
`extensions` field on capabilities.

---

## What Claude gained (per the announcement)

- MCP Apps for inline UI rendering
- Enterprise-managed auth via identity providers (Entra, Okta) — real OAuth 2.0 /
  OIDC alignment, no workarounds
- Observability dashboards for published connectors
- MCP tunnels for private-network access
