claude-code - 💡(How to fix) Fix [BUG] Claude Code Native SSE MCP Transport [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#58759Fetched 2026-05-14 03:40:12
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Timeline (top)
labeled ×3commented ×1

When an MCP server is configured in ~/.claude.json using the native SSE transport ("type": "sse"), tool schemas load correctly (tools/list works), but every tools/call returns -32602 Invalid request parameters. Root cause: Claude Code's native SSE transport never sends the notifications/initialized message that the MCP spec requires after InitializeResult, so the server stays in Initializing state and rejects subsequent requests.

The bug affects every MCP server using the official Python MCP SDK on its server side, which is most of them.

Error Message

MCP error -32602: Invalid request parameters If the output includes MCP error -32602, bug is still present. If the output includes the tool's actual response, bug is fixed.

Error Messages/Logs

MCP error -32602: Invalid request parameters

Root Cause

When an MCP server is configured in ~/.claude.json using the native SSE transport ("type": "sse"), tool schemas load correctly (tools/list works), but every tools/call returns -32602 Invalid request parameters. Root cause: Claude Code's native SSE transport never sends the notifications/initialized message that the MCP spec requires after InitializeResult, so the server stays in Initializing state and rejects subsequent requests.

Fix Action

Fix / Workaround

  • Every MCP server configured in Claude Code via native SSE transport is unusable for tool calls. Schemas load (so /mcp looks healthy) but the server never accepts a single tools/call. Easy to miss in shallow testing.
  • The workaround (wrapping in npx mcp-remote) requires a Node subprocess per MCP server per Code session lifetime. Functional, but defeats the point of Claude Code having native SSE support.
  • This is likely under-reported because native SSE is presumably less commonly used than stdio transport in MCP setups. It bites the moment someone deploys their own MCP server on a remote host.

Code Example

{
  "mcpServers": {
    "repro-server": {
      "type": "sse",
      "url": "http://YOUR_MCP_HOST:8765/mcp/sse/path"
    }
  }
}

---

MCP error -32602: Invalid request parameters

---

{
  "mcpServers": {
    "repro-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://YOUR_MCP_HOST:8765/mcp/sse/path",
        "--allow-http"
      ]
    }
  }
}

---

case _:
    if self._initialization_state != InitializationState.Initialized:
        raise RuntimeError("Received request before initialization was complete")

---

WARNING Failed to validate notification: Received notification before initialization was complete.
        Message was: method='notifications/roots/list_changed' params=None jsonrpc='2.0'
WARNING Failed to validate request: Received request before initialization was complete

---

# Drop a minimal native-SSE config into a scratch settings file
cat > /tmp/sse-test.json <<EOF
{"mcpServers": {"repro": {"type": "sse", "url": "$URL"}}}
EOF
# Launch Claude Code pointing at the scratch config, exec a single tool call, observe the exit
claude --settings /tmp/sse-test.json --print 'Call the simplest tool on the repro MCP server and report the result verbatim.'

---
RAW_BUFFERClick to expand / collapse

Preflight Checklist

  • I have searched existing issues and this hasn't been reported yet
  • This is a single bug report (please file separate reports for different bugs)
  • I am using the latest version of Claude Code

What's Wrong?

Summary

When an MCP server is configured in ~/.claude.json using the native SSE transport ("type": "sse"), tool schemas load correctly (tools/list works), but every tools/call returns -32602 Invalid request parameters. Root cause: Claude Code's native SSE transport never sends the notifications/initialized message that the MCP spec requires after InitializeResult, so the server stays in Initializing state and rejects subsequent requests.

The bug affects every MCP server using the official Python MCP SDK on its server side, which is most of them.

Environment

  • Claude Code version: 2.1.140
  • macOS: 26.4.1 (Tahoe), Apple Silicon
  • Tested against MCP server: mem0ai/mem0 OpenMemory (mem0/openmemory-mcp, mem0ai==0.1.108, Python MCP SDK)
  • Server repo: https://github.com/mem0ai/mem0

Quick repro (~3 minutes)

Step 1. Add a native-SSE MCP server entry to ~/.claude.json. Substitute any reachable MCP server speaking SSE:

{
  "mcpServers": {
    "repro-server": {
      "type": "sse",
      "url": "http://YOUR_MCP_HOST:8765/mcp/sse/path"
    }
  }
}

Step 2. Restart Claude Code, then run /mcprepro-server shows as connected with its tool count populated. So far so good (schemas loaded).

Step 3. Ask Claude to call any tool exposed by the server. Observe:

MCP error -32602: Invalid request parameters

Step 4. Replace the same entry with the mcp-remote stdio bridge form:

{
  "mcpServers": {
    "repro-server": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://YOUR_MCP_HOST:8765/mcp/sse/path",
        "--allow-http"
      ]
    }
  }
}

Restart Claude Code, repeat Step 3 — tool call succeeds. Confirms the bug is in Claude Code's native SSE path, not in the server or the network.

Root cause (confirmed server-side)

In the MCP Python SDK at mcp/server/session.py:162, the server rejects any non-init request when self._initialization_state != InitializationState.Initialized:

case _:
    if self._initialization_state != InitializationState.Initialized:
        raise RuntimeError("Received request before initialization was complete")

The session state machine transitions:

  • NotInitialized → Initializing on InitializeRequest
  • Initializing → Initialized only when InitializedNotification (notifications/initialized) is received

Server-side logs from the repro show:

WARNING Failed to validate notification: Received notification before initialization was complete.
        Message was: method='notifications/roots/list_changed' params=None jsonrpc='2.0'
WARNING Failed to validate request: Received request before initialization was complete

The only notification ever observed from Claude Code's native SSE client is notifications/roots/list_changednever notifications/initialized. Per the MCP lifecycle spec, clients MUST send notifications/initialized after receiving InitializeResult and before any further requests.

Why this implicates Claude Code specifically

The same MCP server works correctly via:

  • npx -y mcp-remote <url> stdio bridge — used by Claude Desktop and Cowork. Handshake completes, notifications/initialized is sent, tool calls succeed.
  • The Python MCP SDK's ClientSession.initialize() — Handshake completes, tool calls succeed.

Both client implementations are spec-compliant. Only Claude Code's native SSE transport fails to send notifications/initialized.

Impact

  • Every MCP server configured in Claude Code via native SSE transport is unusable for tool calls. Schemas load (so /mcp looks healthy) but the server never accepts a single tools/call. Easy to miss in shallow testing.
  • The workaround (wrapping in npx mcp-remote) requires a Node subprocess per MCP server per Code session lifetime. Functional, but defeats the point of Claude Code having native SSE support.
  • This is likely under-reported because native SSE is presumably less commonly used than stdio transport in MCP setups. It bites the moment someone deploys their own MCP server on a remote host.

Suggested fix

Send notifications/initialized from Claude Code's native SSE transport client after receiving the server's InitializeResult response and before issuing any further requests. Per MCP spec, this is required behavior, not optional.

How to verify a fix

When a future Claude Code version claims to fix this, the verification is the Quick repro above with two changes — Step 1 uses the same native-SSE JSON config, Step 3 should now succeed.

A one-liner repro check from the laptop (assuming an SSE-capable MCP server is reachable at $URL):

# Drop a minimal native-SSE config into a scratch settings file
cat > /tmp/sse-test.json <<EOF
{"mcpServers": {"repro": {"type": "sse", "url": "$URL"}}}
EOF
# Launch Claude Code pointing at the scratch config, exec a single tool call, observe the exit
claude --settings /tmp/sse-test.json --print 'Call the simplest tool on the repro MCP server and report the result verbatim.'

If the output includes MCP error -32602, bug is still present. If the output includes the tool's actual response, bug is fixed.

Additional context

  • Only became observable after switching to a self-hosted MCP server reached over the network. Native SSE is presumably underused relative to stdio for MCP, which may explain why this hasn't been reported earlier.
  • tools/list works fine — schemas are fetched and displayed correctly under /mcp. The failure is specific to tools/call. This is consistent with the Python SDK's behavior: tools/list is permitted during Initializing, but tools/call requires Initialized.
  • Reproducible 100% of the time. Not a race condition. Not network-dependent (tested over both LAN and Tailscale overlay).
  • Discovered while debugging a self-hosted mem0ai/mem0 OpenMemory instance, but the bug is not specific to that server. Any MCP server using the official Python SDK on the server side will hit it.

What Should Happen?

After receiving the server's InitializeResult in response to its InitializeRequest, Claude Code's native SSE transport should send the notifications/initialized JSON-RPC notification before issuing any further requests — as required by the MCP lifecycle spec. With that notification sent, the server transitions from Initializing to Initialized state and accepts subsequent tools/call requests normally. The user-visible behavior should match what happens today when the same MCP server is configured via the npx mcp-remote stdio bridge: tools list, tools call, and all return their expected payloads without -32602 errors. In short — a server configured with "type": "sse" should be functionally equivalent to the same server reached via mcp-remote. There should be no difference in spec compliance between Claude Code's native SSE client and a Node-based bridge.

Error Messages/Logs

Steps to Reproduce

Spin up any MCP server speaking SSE that uses the official Python MCP SDK server-side. (I tested against mem0ai/mem0 OpenMemory, but the bug is independent of which server — the failure is in Claude Code's SSE client, not the server. Any spec-compliant SSE MCP server will repro.) Add the server to ~/.claude.json using the native SSE transport:

json{ "mcpServers": { "repro-server": { "type": "sse", "url": "http://YOUR_SSE_MCP_HOST:8765/mcp/sse/path" } } }

Restart Claude Code. Run /mcp. repro-server shows as connected with its tool count populated correctly. So far so good — schemas load. Ask Claude to call any tool exposed by repro-server. Observe the result:

MCP error -32602: Invalid request parameters

Confirm the bug is in Claude Code's native SSE transport (not in the server). Replace the same entry with the mcp-remote stdio bridge form:

json{ "mcpServers": { "repro-server": { "command": "npx", "args": [ "-y", "mcp-remote", "http://YOUR_SSE_MCP_HOST:8765/mcp/sse/path", "--allow-http" ] } } }

Restart Claude Code. Repeat step 4 — same server, same tool, but reached through mcp-remote. Tool call now succeeds with the expected payload. Inspect server-side logs from step 4 (any standard MCP Python SDK server logs to stderr by default). You'll see:

WARNING Failed to validate notification: Received notification before initialization was complete. Message was: method='notifications/roots/list_changed' params=None jsonrpc='2.0' WARNING Failed to validate request: Received request before initialization was complete The only notification received from Claude Code's native SSE client is notifications/roots/list_changed. The required notifications/initialized is never sent — but is sent correctly when the same server is reached via mcp-remote, which is why step 6 works. Note: Reproducible 100% of the time, not a race condition. Reproduces over LAN and over a Tailscale overlay network. tools/list works fine in the broken state — only tools/call is blocked, which matches the Python MCP SDK's behavior of permitting tools/list during Initializing but rejecting tools/call until Initialized.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.1.140

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING