anthropics / anthropics/claude-ai-mcp

Custom MCP connector tools never injected into chat despite fully spec-compliant backend (verified via manual curl)

Open
#792 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
No language data
Stars
471
Forks
76
PR merge metrics
No merged PRs in 30d

Description

### What happened?

Custom MCP connector (Streamable HTTP) never progresses past `initialize` in
claude.ai — no `notifications/initialized` or `tools/list` ever reaches the
server, despite the server being fully spec-compliant.

Setup: self-hosted MCP servers behind supergateway (stdio→Streamable HTTP),
authless, exposed via HTTPS reverse proxy. Tested with THREE independent
backends (Python mysql-mcp-server, Go-based mcp-grafana, custom Python/FastMCP
script) — all three show identical behavior.

Symptom: Settings shows "This connector has no tools available." Chat
conversations can sometimes produce a correct-looking answer (likely from
memory/context, not a live tool call), but explicit tool widgets fail with
"Failed to fetch."

Verified via manual curl (bypassing Claude entirely):
1. POST .../mcp {initialize} → 200 OK, valid capabilities, Mcp-Session-Id
returned
2. POST .../mcp {notifications/initialized} with session header → 202 Accepted
3. POST .../mcp {tools/list} with session header → 200 OK, full valid tool
array returned (3 tools, correct inputSchema)

supergateway logs show `initialize` received and answered correctly across
multiple client identities (Anthropic, Anthropic/Toolbox, Anthropic/ClaudeAI),
but `notifications/initialized`/`tools/list` never arrive from Claude's side
in any of them.

Already ruled out: --stateful vs stateless supergateway modes, CORS
enabled/disabled, root path vs sub-path routing, shared domain vs dedicated
subdomain — no change in behavior with any combination.

Possibly related to anthropics/claude-ai-mcp#552 and #572 (same symptom:
server confirmed healthy, tools never injected into chat).

### What did you expect to happen?

After adding a custom Streamable HTTP connector and having it show as "Connected,"
I expected Claude to call notifications/initialized followed by tools/list, and
for the server's tools to appear both in Settings and be usable in chat — the
same behavior documented for any spec-compliant remote MCP server.

Instead, the connector Settings page permanently shows "This connector has no
tools available," and no chat can successfully invoke a tool through the normal
MCP flow.

### Steps to reproduce

1. Deploy any Streamable HTTP MCP server (tested with 3 independent backends:
Python mysql-mcp-server, Go-based mcp-grafana, custom Python/FastMCP script)
behind supergateway (stdio→Streamable HTTP), exposed via HTTPS reverse proxy,
authless.
2. Add it in claude.ai as a custom connector (URL only, no OAuth).
3. Connector shows "Connected," but Settings reports "This connector has no
tools available." Server logs show `initialize` received and answered
correctly (multiple client identities: Anthropic, Anthropic/Toolbox,
Anthropic/ClaudeAI) — but notifications/initialized and tools/list are
never sent by the client.
4. Manually replicated the protocol via curl, bypassing Claude entirely:
- POST /mcp {initialize} → 200 OK, valid capabilities, Mcp-Session-Id returned
- POST /mcp {notifications/initialized} + session header → 202 Accepted
- POST /mcp {tools/list} + session header → 200 OK, full valid tool array
This confirms the server is 100% spec-compliant; the client never attempts
the same sequence.
5. Ruled out: --stateful vs stateless supergateway modes, CORS on/off, root
path vs sub-path routing, shared domain vs dedicated subdomain — no change
in behavior with any combination.

### Area

MCP Connector (adding/managing servers)

### MCP Server (if applicable)

Self-hosted, not publicly shared (server confirmed authless — see protocol trace in reproduction steps for full evidence instead of a live URL).

### Error messages or logs

```shell
Server-side log (supergateway), showing the pattern across all 3 client identities:

[supergateway] StreamableHttp → Child: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"Anthropic","version":"1.0.0"}}}
[supergateway] Child → StreamableHttp: {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25", ...valid capabilities...}}
[supergateway] Response finished
[supergateway] StreamableHttp → Child: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...,"clientInfo":{"name":"Anthropic/Toolbox","version":"1.0.0"}}}
[supergateway] Child → StreamableHttp: {"jsonrpc":"2.0","id":1,"result":{...valid capabilities...}}
[supergateway] StreamableHttp → Child: {"jsonrpc":"2.0","id":1,"method":"initialize","params":{...,"clientInfo":{"name":"Anthropic/ClaudeAI","version":"1.0.0"}}}
[supergateway] Child → StreamableHttp: {"jsonrpc":"2.0","id":1,"result":{...valid capabilities...}}

— log ends here every time. notifications/initialized and tools/list are
never sent, from any of the three client identities, across many repeated
connection attempts over several days.

---

Manual protocol replay via curl (same server, same endpoint), for comparison:

POST /mcp {initialize}
→ HTTP/1.1 200 OK
Content-Type: text/event-stream
Mcp-Session-Id:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-06-18", ...valid capabilities...}}

POST /mcp {notifications/initialized} [header: Mcp-Session-Id: ]
→ HTTP/1.1 202 Accepted

POST /mcp {tools/list} [header: Mcp-Session-Id: ]
→ HTTP/1.1 200 OK
{"jsonrpc":"2.0","id":2,"result":{"tools":[{"name":"execute_sql",...},
{"name":"get_schema_info",...},{"name":"get_table_sample",...}]}}

This confirms the exact same three-step sequence, against the exact same
endpoint, completes successfully when performed manually — the gap is
specifically in what the Claude client sends (or doesn't send) after
initialize.
```

### Additional context

_No response_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.