[BUG] MCP Connection Status Shows "Failed to Connect" Despite Working Server (Protocol Violation in Health Checker)

Resolved 💬 3 comments Opened Sep 10, 2025 by ghost Closed Sep 11, 2025

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:

  1. 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"
    }
  }
}
  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:

  1. Client → initialize request
  2. Server → initialize response
  3. Client → notifications/initialized notification ⚠️ Claude Code health checker skips this
  4. 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:

  1. Client → initialize request
  2. Server → initialize response
  3. Client → notifications/initialized notification ⚠️ Claude Code health checker skips this
  4. 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

  1. Create any MCP server using FastMCP framework with stdio transport
  2. Configure it in Claude Code's .claude.json
  3. Run claude mcp list
  4. Observe "Failed to connect" status despite server working correctly
  5. 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:

  1. Send initialize request
  2. Wait for initialize response
  3. Send notifications/initialized notification ← Missing step
  4. Then test with tools/list or 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

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗