The MCP specification update in one paragraph

Revision 2026-07-28 of the Model Context Protocol was released on 28 July 2026, after a release candidate in May. It removes the initialize handshake and the Mcp-Session-Id header: every request carries its own protocol version and client capabilities. A server that needs more input mid-request returns an input_required result, and the client answers by retrying the request (the multi round-trip requests pattern). Tasks move to an extension, resumable streams are gone, authorization is tightened, and Roots, Sampling and Logging are deprecated with a twelve-month minimum window. The full changelog covers the rest.

This article asks a narrower question, as of October 2026: what does the revision change for an agent that writes to your CRM or ERP? I read it against the six requirements in my checklist for MCP servers with write access.

The six requirements against the 2026-07-28 revision

Requirement What the revision changes What is still yours
1. Exact approval State echoed by the client must be integrity-protected when it drives authorization or business logic, and should carry the user, an expiry and a request digest. Showing a person the exact parameters; refusing any change after approval.
2. Write classification Nothing: annotations stay untrusted. Headers now expose the tool name. The versioned manifest that says a tool writes; denying unknown tools.
3. Single execution A broken stream is retried as a new request with a new ID; single use of requestState is not guaranteed. One approval, one idempotency key, preconditions at execution.
4. Provable log Logging is deprecated; trace-context keys are documented. The whole audit log, in storage nobody can rewrite.
5. The user’s rights Issuer validation; issuer-bound client credentials; still a separate token upstream, no passthrough. Making the downstream call carry the user’s rights, by token exchange.
6. Failure behaviour Asking now ends the request: an input_required result, then a retry (or tasks/update for a task). Accept, decline and cancel are unchanged. Failing closed, expiring approvals, an owner for pending writes.

None of the good answers on the printable scorecard (PDF) changes. What changes is how much of the problem the protocol now names.

1. Exact approval: the specification now says what to bind

Under the new pattern, a server that needs a decision returns resultType: "input_required", with its questions in inputRequests and, optionally, an opaque requestState that the client must echo back unchanged on the retry (Multi Round-Trip Requests). The server can keep nothing in between; the state rides with the client.

Servers MUST treat requestState as attacker-controlled. Where it influences authorization, resource access or business logic, they MUST protect its integrity (an HMAC or AEAD) and reject state that fails verification. To prevent replay they SHOULD include the authenticated principal, a short expiry, and an identifier of the originating request such as the method name and a digest of its salient parameters.

The digest matters most for writes, because the retry carries the tool’s arguments again, from the client. In my reading, a server that skips this SHOULD can approve one refund and execute another. The page does not say which parameters are salient; the server chooses, so a server in front of writes should digest every argument. That is the closest the protocol comes to the checklist’s rule that any change voids an approval.

Two limits. The page covers any round trip, not approvals in particular. And an accept proves only that a client said accept: the same page lets clients gather input “from the user or other sources”. I would keep the approval itself in the gateway and treat requestState as the carrier, not the proof.

2. Write classification: still not the server’s own label

Nothing in the revision changes who decides that a tool writes. The tools page still says clients MUST consider annotations untrusted unless they come from trusted servers; readOnlyHint remains a hint.

What is new is visibility. On Streamable HTTP every request carries an Mcp-Method header, and a tools/call carries the tool name in Mcp-Name, so that gateways and load balancers can route without parsing the body. Servers that process the body MUST reject a request whose headers disagree with it (Streamable HTTP transport).

That helps routing but classifies nothing: a header gives the tool’s name, not what it does, and no arguments unless the server mirrors some. A gateway that approves exact parameters reads the body anyway, and keeps the classification in its own manifest.

3. Single execution: retries are ordinary now, and running once is yours

The revision removes stream resumability. If a response stream breaks, the in-flight request is lost and the client MUST re-issue it as a new request with a new ID (changelog). On Streamable HTTP a closed stream is also how a client cancels, and the cancellation page warns that processing may already be complete when the cancellation arrives.

Take a refund. The payment system commits, the stream drops before the result returns, and the client re-issues the call. Nothing in the protocol links the two requests, and the JSON-RPC ID cannot: the retry MUST use a new one, and an ID only has to be unique among the sender’s unanswered requests (base protocol).

MRTR says as much of its own state: principal, expiry and digest bound the replay window but do not by themselves guarantee single use, and a server that needs at-most-once MUST enforce it server-side. In the Tasks extension, cancellation is cooperative; the server is not obliged to stop the work.

So idempotency matters more under this revision, and it is still yours: one key per approval, as in the checklist, with the preconditions described in the human-in-the-loop design guide.

A specification can tell you what to bind an approval to. It cannot make your server refuse the second execution.

4. Provable log: the protocol never had an audit log

The revision deprecates the Logging feature, which let servers send log messages to the client (Logging); the suggested replacements are stderr and OpenTelemetry. It also reserves traceparent, tracestate and baggage in _meta for OpenTelemetry trace context.

Neither is an audit log. Trace context helps you follow one call through client, gateway and target, but the sender sets it, so it proves nothing. The same holds for clientInfo, which the base protocol page calls self-reported and not to be relied on for security decisions. The tools page asks clients to log tool usage for audit; I found nothing that asks the server or gateway for a record that would survive a dispute.

The log in requirement 4 is entirely yours, and its identities should come from the verified token.

5. The user’s rights: tighter authorization, passthrough still forbidden

Authorization is still OPTIONAL in MCP. Where it is used, the client side is tighter: issuer validation per RFC 9207, issuer-bound client credentials, and Client ID Metadata Documents in place of the deprecated Dynamic Client Registration. A server still accepts only tokens issued for it (Authorization).

Earlier revisions already covered the next hop, from your server to the system it writes to. The authorization security considerations say a server calling upstream APIs may act as an OAuth client with a separate token from the upstream authorization server, and MUST NOT pass through the token it received. For third-party services, URL-mode elicitation has the user authorize the server directly, with tokens bound to that user.

The specification does not require the downstream call to carry the user’s rights, and I found nothing in it that rules out a broad service account. The Enterprise-Managed Authorization extension uses token exchange (RFC 8693), but for the client’s access to the MCP server; I found nothing applying it to the server’s downstream call. For targets federated with your identity provider I would still use OAuth 2.0 Token Exchange, so the ERP sees the user and refuses what they could not do; the URL-mode pattern suits a third-party SaaS with its own OAuth.

6. Failure behaviour: asking is a protocol pattern, answering is optional

Asking the user is not new; how the question travels is. Instead of sending its own elicitation/create mid-call, the server ends the call with an input_required result and the client retries; a task waits in input_required until the client answers through tasks/update, and the Tasks page lists approval gates as a use. The elicitation-complete notification is gone. Accept, decline and cancel are unchanged, as are the elicitation page’s rules that clients show which server is asking and offer decline and cancel.

Read the verbs, though. Clients SHOULD implement approval controls for elicitation requests, and the protocol mandates no interaction model. The Tasks page tells clients to present input requests “to the user or model”. Servers MUST NOT assume a client will answer or retry at all. Under the round-trip pattern, a write awaiting approval is a request nobody has retried yet; under Tasks, a task nobody has answered.

What happens then is your design, as requirement 6 of the checklist sets out. The protocol does not fail closed for you.

Two new things to watch: state handles and mixed versions

State handles. Without sessions, a server that needs state across calls mints a handle that comes back as an ordinary tool argument. The Security Best Practices call the risk state handle hijacking: servers MUST NOT treat possession of a handle as authentication, and SHOULD bind it to the user taken from the verified token.

Mixed versions. In the compatibility matrix, a modern client against a legacy server fails: the server may reject the request, stay silent, or process an ambiguous method under legacy semantics. A gateway in front of older servers must know which era each speaks before anything writes through it.

Trade-offs and limits

This is a reading of the specification as of October 2026, not a field report; it makes no claim about any gateway, SDK or product.

Several rules that matter most for writes are SHOULD, not MUST: the digest in requestState, approval controls for elicitation, binding handles to the user. A conforming implementation may skip them, so ask for each by name.

The specification will move: a deprecated feature becomes eligible for removal after at least twelve months, sooner only for an active security risk (lifecycle policy).

Digesting every argument has a price: any legitimate edit, however small, means a new approval, by design.

Common questions

Is MCP stateless now?

Yes, in the 2026-07-28 revision. There is no initialize handshake and no session ID: every request carries its protocol version and client capabilities. A server that needs state across calls mints an explicit handle, passed back as an ordinary tool argument.

Does the new MCP specification require human approval for tool calls?

No. The tools page says there SHOULD always be a human in the loop able to deny tool invocations, and the elicitation page says clients SHOULD offer approval controls for its requests; neither is enforced. The new patterns let a server ask; they do not prove that a person answered.

What is requestState and is it safe?

An opaque string the server returns with an input-required result, echoed back by the client on retry. The specification treats it as attacker-controlled, requires integrity protection when it affects authorization or business logic, and recommends binding it to the user, an expiry and the request. It does not guarantee single use.

Are retries safe in the new MCP specification?

Not by themselves. A broken stream loses the in-flight request, and the client re-issues it as a new request with a new ID. The protocol does not link the two, so a write that committed before the break can run again unless your server enforces an idempotency key.

What is deprecated in the 2026-07-28 revision?

Roots, Sampling and Logging; the old HTTP+SSE transport; the thisServer and allServers values of includeContext; and Dynamic Client Registration, in favour of Client ID Metadata Documents. Deprecated features remain in the specification for at least twelve months, shorter only for an active security risk, and new implementations should not adopt them.

In practice

On the ENSO platform, I specified agentic actions through a single MCP action server with versioned tool manifests, human validation on every write, idempotency and precondition checks, and an append-only decision log that makes every AI decision replayable, with a WORM export to S3 Object Lock. The AI inherits the user’s permissions through OAuth2 Token Exchange (Keycloak, OIDC) and IRSA workload identities. See the ENSO case study and the AI agents governance page. This article is a reading of the 2026-07-28 specification, not a report on ENSO.

Sources