anthropics / anthropics/claude-code
[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)
- Vorherrschende Sprache
- Python
- Sterne
- 145k
- Forks
- 23.1k
- PR-Merge-Kennzahlen
- PR-Kennzahlen ausstehend
Beschreibung
### 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
```json
{"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:
```sh
# 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
- Header mismatch rejection in the Go SDK: https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0/mcp/streamable.go (SEP-2575 block in `serveStateless`)
- Go SDK's own client-side fix of the same asymmetry: https://github.com/modelcontextprotocol/go-sdk/issues/1164, https://github.com/modelcontextprotocol/go-sdk/issues/1162
- Related but different: #92835 (legacy header vs negotiated version, no `_meta`)
- Spec ambiguity discussion for the *legacy* path (not applicable to the SEP-2575 path): https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2721
Happy to provide server-side request logs (headers + body) on request.
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Start by reproducing the request through a claude.ai custom connector and compare the Mcp-Protocol-Version header with params._meta.protocolVersion. Use mcp/streamable.go in the referenced Go SDK as the server-side rejection reference, and compare the failing Desktop/CLI path with the working VS Code extension path. Done means requests use matching negotiated versions or consistently use the legacy shape.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- go, kubernetes
- Bereich
- api, networking
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 45/100