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
- 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
- Register the server:
claude mcp add -s user test-mcp /usr/local/bin/python3 /tmp/test_mcp.py
- Check health:
claude mcp list
# Output: test-mcp: /usr/local/bin/python3 /tmp/test_mcp.py - ✗ Failed to connect
- 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 getoutput
Tested server types (all fail)
- Swift binary (custom MCP server with Content-Length framing)
- Python 3.14.3 script
- Node.js (v22) script
- Bash script
Config locations tested
~/.claude.jsontop-levelmcpServers~/.claude.jsonproject-levelmcpServers.mcp.jsonin 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.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗