[BUG] MCP Connection Status Shows "Failed to Connect" Despite Working Server (Protocol Violation in Health Checker)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Bug Report: MCP Connection Status Shows "Failed to Connect" Despite Working Server
Summary
The /mcp command incorrectly reports MCP servers as "Failed to connect" even when they are functioning perfectly and responding correctly to all MCP protocol requests. The issue appears to be in Claude Code's MCP connection health checker, which doesn't follow the proper MCP initialization protocol sequence.
Environment
- Claude Code Version: 1.0.110
- Platform: macOS (Darwin 24.6.0)
- MCP Server: Custom server using FastMCP framework (mcp==1.9.1)
- Transport: stdio
- Python Version: 3.13.7
Current Behavior
$ claude mcp list
Checking MCP server health...
Aina MCP: /path/to/server --transport stdio - ✗ Failed to connect
However, all MCP functions work perfectly:
# These all work correctly:
mcp__Aina_MCP__health() # ✅ Returns {"status": "ok", "version": "1.0.0"}
mcp__Aina_MCP__get_ai_rules() # ✅ Returns complete response
mcp__Aina_MCP__discover_indexes() # ✅ Handles auth correctly
Expected Behavior
The connection status should show "✓ Connected" when the MCP server is responding correctly to protocol requests.
Root Cause Analysis
Server Protocol Compliance ✅
The MCP server correctly implements the protocol:
- Proper Initialize Response:
{
"jsonrpc":"2.0",
"id":1,
"result":{
"protocolVersion":"2024-11-05",
"capabilities":{
"experimental":{},
"prompts":{"listChanged":false},
"resources":{"subscribe":false,"listChanged":false},
"tools":{"listChanged":false}
},
"serverInfo":{
"name":"kibana-logs",
"version":"1.9.1"
}
}
}
- All MCP Functions Work: Tools, resources, and prompts all function correctly through the MCP interface.
Claude Code Health Checker Issue ❌
When testing the connection sequence, we discovered that Claude Code's health checker violates the MCP protocol:
Error Observed:
RuntimeError: Received request before initialization was complete
Analysis: Claude Code's health checker sends requests like tools/list immediately after receiving the initialize response, skipping the required notifications/initialized step.
Correct MCP Protocol Sequence
Per the MCP specification:
- Client →
initializerequest - Server →
initializeresponse - Client →
notifications/initializednotification ⚠️ Claude Code health checker skips this - Client → other requests (
tools/list, etc.)
Evidence
Test Case 1: Manual Protocol Test
# Send initialize request
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | python -m server --transport stdio
# ✅ Server responds correctly:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05",...}}
Test Case 2: Invalid Sequence (What Claude Code Does)
# Send tools/list immediately after initialize (without initialized notification)
echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | python -m server --transport stdio
# ❌ Server correctly rejects:
RuntimeError: Received request before initialization was complete
Test Case 3: MCP Functions in Claude Code
# All MCP functions work perfectly in actual usage:
mcp__Aina_MCP__health() # ✅ Works
Configuration
Server configuration in .claude.json:
{
"Aina MCP": {
"type": "stdio",
"command": "/path/to/python3",
"args": ["-m", "src.server", "--transport", "stdio"],
"cwd": "/path/to/server",
"autoApprove": ["health", "get_ai_rules", ...]
}
}
What Should Happen?
Expected Behavior
The connection status should show "✓ Connected" when the MCP server is responding correctly to protocol requests.
Correct MCP Protocol Sequence
Per the MCP specification:
- Client →
initializerequest - Server →
initializeresponse - Client →
notifications/initializednotification ⚠️ Claude Code health checker skips this - Client → other requests (
tools/list, etc.)
Error Messages/Logs
### **Claude Code Health Checker Issue ❌**
When testing the connection sequence, we discovered that Claude Code's health checker violates the MCP protocol:
**Error Observed:**
RuntimeError: Received request before initialization was complete
**Analysis:** Claude Code's health checker sends requests like `tools/list` immediately after receiving the `initialize` response, **skipping the required `notifications/initialized` step**.
Steps to Reproduce
Reproduction Steps
- Create any MCP server using FastMCP framework with stdio transport
- Configure it in Claude Code's
.claude.json - Run
claude mcp list - Observe "Failed to connect" status despite server working correctly
- Test MCP functions directly - they work fine
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
1.0.110
Platform
Google Vertex AI
Operating System
macOS
Terminal/Shell
iTerm2
Additional Information
Impact
- Functional Impact: None - all MCP features work correctly
- User Experience Impact: Confusing status display showing "Failed to connect"
- Development Impact: Developers may think their MCP servers are broken when they're actually working fine
Proposed Fix
Update Claude Code's MCP connection health checker to follow the proper MCP protocol initialization sequence:
- Send
initializerequest - Wait for
initializeresponse - Send
notifications/initializednotification ← Missing step - Then test with
tools/listor other requests
Workaround
None needed - MCP servers work correctly despite the status display issue.
Additional Context
- This affects any properly implemented MCP server using stdio transport
- The issue is specifically in the connection health checker, not the MCP runtime
- Other transport types (SSE, HTTP) may not be affected
- The server works fine with other MCP clients that follow proper protocol sequence
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗