stdio MCP servers fail to connect — process never spawned

Resolved 💬 3 comments Opened Mar 23, 2026 by rccypher Closed Mar 27, 2026

Environment

  • Claude Code version: 2.1.81 (native install)
  • macOS: Darwin 24.6.0 (x86_64)
  • Shell: zsh

Problem

All stdio MCP servers fail to connect with "Failed to connect" status. The server process is never spawned — verified by wrapping the binary in a logging shell script that captures invocation. The wrapper script's log files remain empty.

Reproduction

  1. Create any stdio MCP server (tested with Swift binary, Python script, Node.js script, and bash script — ALL fail):
# Minimal test server
cat > /tmp/test_mcp.py << 'EOF'
import sys, json
def read_msg():
    header = ""
    while True:
        line = sys.stdin.readline()
        if line.strip() == "": break
        header += line
    length = int(header.split(":")[1].strip())
    return json.loads(sys.stdin.read(length))

def write_msg(obj):
    body = json.dumps(obj)
    sys.stdout.write(f"Content-Length: {len(body)}\r\n\r\n{body}")
    sys.stdout.flush()

while True:
    try: req = read_msg()
    except: break
    method = req.get("method", "")
    if method == "initialize":
        write_msg({"jsonrpc":"2.0","id":req["id"],"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"test","version":"1.0"}}})
    elif method == "tools/list":
        write_msg({"jsonrpc":"2.0","id":req["id"],"result":{"tools":[]}})
    elif method == "ping":
        write_msg({"jsonrpc":"2.0","id":req["id"],"result":{}})
EOF
  1. Register the server:
claude mcp add -s user test-mcp /usr/local/bin/python3 /tmp/test_mcp.py
  1. Check health:
claude mcp list
# Output: test-mcp: /usr/local/bin/python3 /tmp/test_mcp.py - ✗ Failed to connect
  1. The server works perfectly when tested manually:
MSG='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test"}}}'
LEN=${#MSG}
printf "Content-Length: %d\r\n\r\n%s" "$LEN" "$MSG" | python3 /tmp/test_mcp.py
# Returns correct initialize response

Verification that process is never spawned

Created a wrapper script that logs invocation:

#!/bin/bash
echo "[wrapper] Invoked at $(date)" >> /tmp/mcp_trace.log
exec /path/to/server

After running claude mcp list, /tmp/mcp_trace.log does not exist — the wrapper was never executed.

What works

  • HTTP MCP servers (claude.ai Gmail, Google Calendar) appear correctly
  • The server binaries work when spawned manually via pipe
  • Config format is correct per claude mcp get output

Tested server types (all fail)

  1. Swift binary (custom MCP server with Content-Length framing)
  2. Python 3.14.3 script
  3. Node.js (v22) script
  4. Bash script

Config locations tested

  • ~/.claude.json top-level mcpServers
  • ~/.claude.json project-level mcpServers
  • .mcp.json in project root
  • ~/.mcp.json

All produce the same "Failed to connect" with no process spawn.

Expected behavior

claude mcp list should spawn the server process, send initialize, and report the connection status.

View original on GitHub ↗

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