claude-in-chrome MCP server loses WebSocket bridge connection and can't recover
Summary
The --claude-in-chrome-mcp server uses a cloud WebSocket bridge (wss://bridge.claudeusercontent.com) to communicate with the Chrome extension (feature flag tengu_copper_bridge is enabled). The connection drops shortly after startup and the server never recovers, causing all mcp__claude-in-chrome__* tool calls to return "Browser extension is not connected." Survives full system reboot.
Environment
- Claude Code: 2.1.42
- OS: Ubuntu (Linux 6.17.0-14-generic) running in VirtualBox
- Chrome: stable channel, extension version 1.0.50
- Launch command:
claude --chrome
Reproduction
- Start Chrome
- Start Claude Code with
claude --chrome /chromeshows connected status- Any
mcp__claude-in-chrome__*tool call returns "Browser extension is not connected" /mcpreconnect briefly shows a failure message (disappears too fast to read), same error persists- Full reboot does not fix it
Root cause analysis
The cloud WebSocket bridge architecture
Binary analysis (strings on the claude binary) reveals the MCP server's connection path. When the tengu_copper_bridge feature flag is ON (which it is for this account), the MCP server connects to bridge.claudeusercontent.com (160.79.104.10:443) via WebSocket instead of using the local Unix socket.
When the flag is OFF, it falls back to the local native host Unix socket at /tmp/claude-mcp-browser-bridge-<user>/<pid>.sock.
The connection lifecycle (observed)
Startup — three processes launch correctly:
--chrome-native-host: Creates local socket, Chrome pings it successfullyclaude --chrome: Main session, has multiple healthy TCP connections to bridge server--claude-in-chrome-mcp: MCP server subprocess
Initial state — MCP server has two TCP connections:
- fd 16:
160.79.104.10:443(cloud bridge WebSocket) - fd 17:
34.149.66.137:443(telemetry)
After failure — MCP server loses the bridge connection:
- fd 16: gone (bridge connection dropped)
- fd 17:
34.149.66.137:443still alive (telemetry) - No Unix socket connections
- All tool calls return "not connected"
Meanwhile — Chrome maintains a healthy connection to the same bridge server with keepalive timers active. The main claude process also has multiple healthy connections.
The local socket is unused
Despite the native host creating a working Unix socket:
- The MCP server never attempts to
connect()to any Unix socket (confirmed viastrace) - The MCP server never calls
openat()on the bridge directory - The only time the socket is accessed is a brief connect/disconnect visible in journald during
/mcpreconnect:
````
[Claude Chrome Native Host] MCP client 1 connected. Total clients: 1
[Claude Chrome Native Host] MCP client 1 disconnected. Remaining clients: 0
This appears to be a validation step, not the data path.
- The local socket is manually connectable (verified via Python
socket.connect())
No system-level blockers
Verified these are not the cause:
- SELinux: not installed
- AppArmor: loaded, no profiles for claude
- Seccomp: disabled on MCP server process
- Namespaces: all processes share net/mnt/user namespaces
- Socket permissions: 0700 directory, 0600 socket, correct uid
- Network: VirtualBox NAT, other TCP connections (including to same IP) work fine
The reconnect code exists but doesn't help
The binary contains reconnect logic (maxReconnectAttempts=10, reconnectDelay=1000) for the local socket path, but the cloud bridge path does not recover from connection drops.
Suggested fixes
- The cloud bridge reconnect logic needs to recover from connection drops
- Fallback to the local Unix socket when the cloud bridge fails — the native host is running and healthy
- A user-facing way to force local socket mode (e.g., env var or setting) as a workaround
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗