[BUG] Claude Desktop / Claude Code CLI send Mcp-Protocol-Version: 2025-11-25 with _meta protocolVersion 2026-07-28 via claude.ai connectors — spec-compliant stateless servers reject every call (-32020 header mismatch)

Status Open
Reported on v2.1.267
Maintainer reply None cached
Activity 0 comments · opened Sep 10, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet (closest: #92835, which covers the legacy header-vs-negotiated-version case and later drifted to a VS Code tools-loading problem)
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code (2.1.267)

What's Wrong?

When Claude Desktop or the Claude Code CLI talks to a remote MCP server through a claude.ai custom connector, every request after the handshake carries a 2026-07-28 body but a 2025-11-25 header:

  • JSON-RPC params._meta["io.modelcontextprotocol/protocolVersion"] = "2026-07-28" (SEP-2575, the client negotiated the 2026-07-28 protocol via server/discover)
  • HTTP header Mcp-Protocol-Version: 2025-11-25

SEP-2575 requires the header to match the per-request _meta value, so a spec-compliant stateless server rejects the request with JSON-RPC -32020 (HEADER_MISMATCH), HTTP 400. The connector relays it to the client as -32603. Result: the connector shows as connected, but every tool call fails.

Server side: Go, github.com/modelcontextprotocol/go-sdk v1.7.0, StreamableHTTPOptions{Stateless: true}, behind a plain Kubernetes ingress that only adds CORS headers — nothing in the chain rewrites Mcp-* headers. The rejection is the SDK's own SEP-2575 check (mcp/streamable.go, "header mismatch" branch).

The same server, reached through the same claude.ai connector from the Claude Code VS Code extension (2.1.267, Linux devcontainer), works: that path sends a legacy initialize (2025-11-25) with no _meta, so the check never arms. So the failure depends on which client implementation drives the connector, not on the server.

This is the client-side mirror of what the Go SDK fixed on its own client in modelcontextprotocol/go-sdk#1162 / #1164 (header taken from a default/context while the body carries the negotiated version).

What Should Happen?

After negotiating 2026-07-28, the client must send Mcp-Protocol-Version: 2026-07-28 on every request that carries _meta.protocolVersion = "2026-07-28" (and Mcp-Method/Mcp-Name mirroring per SEP-2575). Alternatively, stay entirely on the legacy 2025-11-25 handshake and send no _meta.

Error Messages/Logs

{"code": -32603, "message": "header mismatch: Mcp-Protocol-Version header \"2025-11-25\" does not match request io.modelcontextprotocol/protocolVersion \"2026-07-28\"", "data": null, "request_id": "req_011CeuMUHDFhBEndkga4oR8N"}

Reproduction of the server side against a bare go-sdk v1.7.0 stateless server (no proxy involved), showing the exact rejection and that the legacy shape passes:

# B — what Claude Desktop / CLI send: rejected
curl -s -X POST http://127.0.0.1:18081 -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' -H 'Mcp-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28"}}}'
# -> 400 {"jsonrpc":"2.0","id":2,"error":{"code":-32020,"message":"Mcp-Protocol-Version header \"2025-11-25\" does not match request io.modelcontextprotocol/protocolVersion \"2026-07-28\""}}

# E — legacy shape (what the VS Code extension path sends): accepted
curl -s -X POST http://127.0.0.1:18081 -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' -H 'Mcp-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":5,"method":"tools/list","params":{}}'
# -> 200 {"jsonrpc":"2.0","id":5,"result":{"tools":[]}}

Steps to Reproduce

  1. Run a stateless Streamable HTTP MCP server built with modelcontextprotocol/go-sdk v1.7.0 (StreamableHTTPOptions{Stateless: true}), reachable over HTTPS.
  2. Register it as a claude.ai custom connector.
  3. In Claude Desktop (macOS 1.49585.0) or the Claude Code CLI 2.1.267 (macOS), call any tool of the connector.
  4. Observe the -32603 header mismatch error above on every call; server logs show Mcp-Protocol-Version: 2025-11-25 with _meta.protocolVersion: 2026-07-28.
  5. Same connector from the Claude Code VS Code extension 2.1.267 (Linux devcontainer): tool calls succeed.

Claude Model

Sonnet / Opus (model-independent)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.267 (CLI, macOS — failing); 2.1.267 (VS Code extension, Linux — working). Claude for Mac 1.49585.0 (41ad1d) — failing.

Platform

claude.ai custom connector (remote MCP)

Operating System

macOS (failing clients), Linux devcontainer (working client)

Terminal/Shell

zsh / Claude Desktop

Additional Information

Happy to provide server-side request logs (headers + body) on request.

View original on GitHub ↗