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)

未關閉
#93,290 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
area:mcp bug has repro platform:macos
主要語言
Python
星號
145k
分支
23.1k
PR 合併指標
PR 指標待擷取

描述

### 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.

貢獻指南

這個儲存庫沒有索引到貢獻指南

研究方向

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.

由索引模型根據 Issue 內容生成。

評估

技術堆疊
go, kubernetes
領域
api, networking
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
活躍
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。