Skip to main content
Version: 1.9.0

Move MCP clients and servers to 2026-07-28

MCP 2026-07-28 is the largest MCP revision so far: no handshake, no session, and new extensions such as Tasks and MCP Apps. DVARA, the AI governance platform, keeps every tool call governed while you move.

You do not have to move everything at once. The DVARA MCP Gateway serves MCP 2026-07-28, 2025-11-25 and 2025-06-18 on the same /mcp endpoint, at the same time. It also picks a revision for each upstream server on its own. So your clients and your servers can move separately, one at a time, in any order.

This page is the checklist. It says what changes, in what order to move, and what to check. The details are on the pages it links to.

Enterprise only

Not included in DVARA Open Source.

The short version​

  1. Measure. Find out which revisions your clients use today.
  2. Read the operator changes. A few answers and defaults differ from older releases. Know them before you upgrade the Gateway.
  3. Move clients. A client on 2026-07-28 drops the handshake and sends its version on every request.
  4. Move servers. Nothing to configure. The Gateway uses 2026-07-28 with a server as soon as the server speaks it. Expect one approval when a server's new release reports a new version.
  5. Turn on extensions, if you want them. Tasks and MCP Apps work only on 2026-07-28, and are off until a workspace allows them.

What the Gateway does on each revision​

2026-07-282025-11-25 and 2025-06-18No revision named
HandshakeNone. Each request carries its version and client details in _metainitialize, then requestsServed as an older client
HeadersMCP-Protocol-Version, Mcp-Method and Mcp-Name requiredOptional, but checked when sentNone
Invalid tool argumentsA tool result marked as an error, which a model can correct2025-11-25: a tool result marked as an error. 2025-06-18: JSON-RPC error -32602JSON-RPC error -32602
Caching hints on liststtlMs, 15 seconds at most, and cacheScope: "private"NoneNone
Change notificationssubscriptions/listenFetch the list againFetch the list again
Questions mid-call (elicitation)RelayedRefused with 502 MCP_INPUT_REQUIRED_UNSUPPORTEDRefused
Tasks and MCP AppsWhen the client, the workspace and the server all agreeNeverNever
Governance and auditThe same on every revisionThe sameThe same

Tool names keep the Gateway's form, serverId__toolName, on every revision. API keys and OAuth tokens work the same way on every revision.

Step 1: measure​

The Gateway counts every /mcp request by revision in the Prometheus metric mcp_requests_by_protocol_version_total. Its revision label is 2026-07-28, 2025-11-25, 2025-06-18, none (no revision named) or unsupported (refused for its revision).

Look at none first. Those clients get the oldest behaviour, and they are the easiest to fix: send the MCP-Protocol-Version header.

The audit record of each governed call also has mcp_protocol_version_source: header, meta or none. Use it to find which client sent a request with no version.

Clients that still use features 2026-07-28 deprecates (Roots, Sampling, Logging) are recorded as MCP_DEPRECATED_FEATURE_USED, at most once a day per client and feature.

See MCP protocol versions.

Step 2: read the changes operators must know​

Each of these is a default. Check it against what your clients expect.

ChangeWhat you seeWhat to do
A request with no version is treated as 2025-03-26A call with invalid arguments gets JSON-RPC error -32602, not a tool result marked as an errorHave clients send the MCP-Protocol-Version header. Clients on 2025-06-18 and later must send it anyway
Lists can be reused for a short time2026-07-28 lists carry ttlMs of 15 seconds at most, and cacheScope: "private". A longer time asked for by an upstream server is cut to 15 secondsA client or proxy must keep a separate copy per API key. Change the limit with dvara.mcp-gateway.caching.max-ttl; 0 means fetch every time
Tasks need the audit secretTask ids are sealed with a key made from DVARA_AUDIT_HMAC_SECRET. Without it, Tasks is not relayedSet the same secret on every Gateway replica. Changing it ends every open task id
Sampling is refusedA server's request for a model call fails the call with MCP_SAMPLING_REFUSEDTo allow it, a workspace chooses Make the call through the LLM Gateway and a model. See sampling
Extensions are offEvery extension a client declares is refused and recorded, and the client falls back to core MCPAllow the ones you want, per workspace. See Govern MCP Apps and Tasks
A changed server waits for approvalA change to a tool's description or schemas, a new server name or version, or a STDIO command or TLS key that no longer matches its pin quarantines the server until someone approves itPlan one approval for each server you upgrade. See a tool that changes after approval
Response trimming is offTool results are passed on wholeNothing to do. To trim, see keep only the fields a result needs
The old HTTP+SSE upstream transport has an end dateIt works until 2027-07-28, with a warning and an audit event on each use. From that date a call is refused with 410 mcp_transport_sunsetMove those servers to STREAMABLE_HTTP

Tool arguments are also checked against the tool's input schema. A schema with no $schema is read as JSON Schema 2020-12, as 2026-07-28 says. Arguments that fail it are refused before the server sees them.

Step 3: move a client​

Point the client at the same URL, https://<your-gateway>/mcp, with the same API key or OAuth token. Then change how it talks:

Before (2025-11-25 or 2025-06-18)After (2026-07-28)
Send initialize, then requestsSend requests straight away. initialize and ping now return 404 with "method not found"
Name the version once, in the handshakeSend MCP-Protocol-Version: 2026-07-28 on every request, with Mcp-Method (and Mcp-Name for a request that names a tool, prompt, resource or task)
Declare capabilities oncePut io.modelcontextprotocol/protocolVersion, clientCapabilities and, usually, clientInfo in each request's _meta
Fetch tools/list again to see changesKeep the list for its ttlMs, or open subscriptions/listen to be told when it changes
Ask initialize what the server offersSend server/discover
A long call blocksA call can return a task, if the workspace allows Tasks

Before, a client opened a session:

curl -s https://<your-gateway>/mcp \
-H "Authorization: Bearer $DVARA_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
"protocolVersion":"2025-11-25","capabilities":{},
"clientInfo":{"name":"my-agent","version":"1.0"}}}'

After, each request stands alone:

curl -s https://<your-gateway>/mcp \
-H "Authorization: Bearer $DVARA_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2026-07-28' \
-H 'Mcp-Method: tools/list' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"_meta":{
"io.modelcontextprotocol/protocolVersion":"2026-07-28",
"io.modelcontextprotocol/clientInfo":{"name":"my-agent","version":"1.0"},
"io.modelcontextprotocol/clientCapabilities":{}}}}'

What can go wrong, and why:

AnswerWhy
400 with MCP's header-mismatch error (-32020)A header and the body disagree: a different method, tool or version, or a tool argument sent in an Mcp-Param-… header with another value
400 with "unsupported protocol version" (-32022)The client named a revision the Gateway does not serve. The error lists the ones it does
400 with a missing-header or missing-capabilities errorA 2026-07-28 request without the required headers, or without the version and client capabilities in _meta
404 "method not found"A method 2026-07-28 removed, such as initialize or ping

Tool names stay serverId__toolName. Policies, approvals, PII scans, budgets and the audit trail work the same as before, so a client move changes no governance setting.

Details: Connect a 2026-07-28 client and tool arguments in headers.

Step 4: move an upstream server​

The Gateway is also an MCP client of each server you register. You do not configure the revision it uses.

HTTP servers (STREAMABLE_HTTP). The Gateway asks each server which revisions it speaks and uses the newest one both sides support. It remembers the answer for 15 minutes, and asks again sooner when you change the server's URL or credential, or when the server refuses the remembered revision. So when you upgrade a server to 2026-07-28, the Gateway moves to it on its own. A server that speaks only revisions the Gateway does not know fails the call with mcp_protocol_version_unsupported.

STDIO servers. A server the Gateway runs as a local process is asked the same question as its first message. If it answers as a 2026-07-28 server, it is called on that revision. If it gives any other answer, or none within 10 seconds, it is treated as an older server and started again with initialize. A STDIO server gets no headers and no credential from the Gateway. It reads its own settings from its environment.

Old HTTP+SSE servers (SSE). These stay on 2025-11-25 or 2025-06-18, and stop working on 2027-07-28. Move them to STREAMABLE_HTTP.

Expect one approval per upgraded server. A new release usually changes what the server reports about itself, and sometimes its tool text. The Gateway holds each of these for approval, and quarantines the server until then:

What changedAudit eventWho approves
A tool's description, input schema, output schema or hintsMCP_TOOL_DEFINITION_CHANGEDA platform operator (Release quarantine) or the workspace admin (Approve tool changes)
The server's reported name or versionMCP_SERVER_IDENTITY_CHANGEDThe same
A STDIO command's package version, image digest or program file, or an HTTPS server's TLS keyMCP_SERVER_PIN_MISMATCHThe same. The found value becomes the new pin

Agents keep seeing the approved version until then, and calls to the server are refused. To keep the gap short, sync the server's tools in Flightdeck right after the upgrade and approve the change at once. See a server that reports a new version and a server is pinned to what it runs.

Tool schemas. If a tool marks a parameter with x-mcp-header, the Gateway sends that value as an Mcp-Param-… header too. A tool whose markings break the protocol's rules is left out of the tool list, as the protocol requires.

A server that asks for input. On 2026-07-28 a server can answer a call with a request for more input. A question for the user (elicitation) is passed to 2026-07-28 clients after a prompt-injection scan. A request for a model call (sampling) is never passed to the client: the Gateway refuses it, or makes the call itself through the LLM Gateway if the workspace chose that. A request for the client's folders (roots) is refused by default.

Step 5: turn on Tasks and MCP Apps, if you want them​

Both are MCP extensions. Both work only on 2026-07-28, and only when the client, the workspace and the server all agree. Both are off by default. See Govern MCP Apps and Tasks for the order to turn them on and what to set first.

Check after each move​

  • mcp_requests_by_protocol_version_total shows traffic moving from none and the older revisions to 2026-07-28.
  • The audit record of each tool result names two revisions: the one your client used with the Gateway, and the one the Gateway used with the server.
  • MCP → Tool Calls in Flightdeck (platform roles), or Agents → MCP Tool Calls (workspace roles), shows the calls with no new refusals.
  • No server waits in quarantine longer than you planned.

What does not change​

  • The older revisions are not being switched off. If one is ever retired, it will be announced in advance, with a date.
  • Authentication: API keys and OAuth tokens work the same way on every revision.
  • Governance: policy, PII and injection scans, approvals, budgets, rate limits and the signed audit trail apply to every call on every revision.

Where to go next​