A network bridge that enables Claude Code running on a remote Linux machine to control Google Chrome on a Windows machine through the Claude Chrome extension.
Claude Code uses Chrome's Native Messaging API to communicate with the Claude Chrome extension. Native Messaging only works locally via stdin/stdout pipes. This bridge tunnels that communication over TCP, allowing remote browser control.
Use Cases:
- Run Claude Code on a powerful Linux server while browsing on your Windows desktop
- Headless Linux environments that need browser automation on a separate Windows machine
- Development setups where Claude Code runs in WSL or a VM
┌─────────────────────────────────────────────────────────────────────────────┐
│ LINUX MACHINE │
│ │
│ ┌─────────────┐ ┌──────────────────────────────────────────┐ │
│ │ Claude Code │ ───► │ Unix Socket │ │
│ │ CLI │ │ /tmp/claude-mcp-browser-bridge-{user} │ │
│ └─────────────┘ └──────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ socat │ │
│ │ UNIX-LISTEN → TCP forward │ │
│ └───────────────────────────────┘ │
│ │ │
└────────────────────────────────────────┼────────────────────────────────────┘
│ TCP:9222
▼
┌────────────────────────────────────────┼────────────────────────────────────┐
│ WINDOWS MACHINE │
│ │ │
│ ┌───────────────────────────────┐ │
│ │ windows-bridge.js │ │
│ │ TCP:9222 → Named Pipe │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ Claude Chrome Extension │ │
│ │ (Native Messaging Host) │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ Google Chrome Browser │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
- Windows 10/11
- Node.js v16 or later
- Google Chrome
- Claude Chrome extension (v1.0.36+)
- Network access from Linux machine (port 9222)
- Claude Code CLI (v2.0.73+)
socatutility- Network access to Windows machine
git clone https://github.com/yourusername/claude-chrome-bridge.git
cd claude-chrome-bridgeCopy windows-bridge.js to your Windows machine and run:
node windows-bridge.jsYou should see:
[Bridge] ✓ TCP server listening on 0.0.0.0:9222
First-time setup: Before running the bridge, ensure the Claude Chrome extension's native messaging host is initialized:
- Install the Claude Chrome extension
- Run Claude Code locally on Windows once (
claude --chrome) - This registers the native messaging host with Chrome
Install socat if not already installed:
# Debian/Ubuntu
sudo apt install socat
# RHEL/CentOS/Fedora
sudo dnf install socat
# Arch Linux
sudo pacman -S socatStart the socket forwarder:
# Replace WINDOWS_IP with your Windows machine's IP address
WINDOWS_IP="192.168.1.100"
# Remove any existing socket
rm -f /tmp/claude-mcp-browser-bridge-$(whoami)
# Start the forwarder (runs in background)
socat UNIX-LISTEN:/tmp/claude-mcp-browser-bridge-$(whoami),fork,mode=600 \
TCP:${WINDOWS_IP}:9222 &
echo "Bridge started!"# Verify socat is running
ps aux | grep socat
# Check socket exists
ls -la /tmp/claude-mcp-browser-bridge-*
# Test TCP connectivity to Windows
nc -zv ${WINDOWS_IP} 9222claude --chromeOr within Claude Code, use the /chrome command.
Allow incoming connections on port 9222:
netsh advfirewall firewall add rule name="Claude Chrome Bridge" ^
dir=in action=allow protocol=TCP localport=9222Or via Windows Defender Firewall UI:
- Open "Windows Defender Firewall with Advanced Security"
- Click "Inbound Rules" → "New Rule"
- Select "Port" → "TCP" → "9222"
- Allow the connection
- Name it "Claude Chrome Bridge"
For persistent operation, run the bridge as a Windows service using node-windows or NSSM.
Using NSSM:
# Download NSSM from https://nssm.cc/
nssm install ClaudeBridge "C:\Program Files\nodejs\node.exe" "C:\path\to\windows-bridge.js"
nssm start ClaudeBridgeCreate /etc/systemd/user/claude-chrome-bridge.service:
[Unit]
Description=Claude Chrome Bridge Forwarder
After=network.target
[Service]
Type=simple
Environment="WINDOWS_IP=192.168.1.100"
ExecStartPre=/bin/rm -f /tmp/claude-mcp-browser-bridge-%u
ExecStart=/usr/bin/socat UNIX-LISTEN:/tmp/claude-mcp-browser-bridge-%u,fork,mode=600 TCP:${WINDOWS_IP}:9222
Restart=always
RestartSec=5
[Install]
WantedBy=default.targetEnable and start:
systemctl --user daemon-reload
systemctl --user enable claude-chrome-bridge
systemctl --user start claude-chrome-bridgeWarning: The default configuration has no authentication. Only use on trusted networks.
Instead of exposing port 9222 directly, tunnel through SSH:
On Linux:
# Create SSH tunnel to Windows (requires SSH server on Windows)
ssh -L 9222:localhost:9222 user@windows-machine -N &
# Point socat at localhost instead
socat UNIX-LISTEN:/tmp/claude-mcp-browser-bridge-$(whoami),fork,mode=600 \
TCP:localhost:9222 &Modify windows-bridge.js to only listen on a specific interface:
const TCP_HOST = '192.168.1.100'; // Instead of '0.0.0.0'Run both machines on a VPN (WireGuard, Tailscale, etc.) and only expose the bridge on the VPN interface.
[Bridge] Pipe not available: connect ENOENT \\.\pipe\claude-mcp-browser-bridge-username
Solutions:
- Ensure Chrome is running
- Verify Claude extension is installed and enabled (check
chrome://extensions) - Run Claude Code locally on Windows once to initialize the native host
- Restart Chrome after installing the extension
# Test connectivity
nc -zv 192.168.1.100 9222
# If connection refused:
# 1. Check Windows bridge is running
# 2. Check Windows Firewall settings
# 3. Verify IP address is correct# Check who owns the socket
ls -la /tmp/claude-mcp-browser-bridge-*
# Remove and recreate if owned by wrong user
rm /tmp/claude-mcp-browser-bridge-*
# Then restart socatCheck if port 9222 is reachable before starting socat:
nc -zv ${WINDOWS_IP} 9222 && \
socat UNIX-LISTEN:/tmp/claude-mcp-browser-bridge-$(whoami),fork,mode=600 \
TCP:${WINDOWS_IP}:9222| Variable | Default | Description |
|---|---|---|
TCP_PORT |
9222 |
Port for TCP connections |
TCP_HOST |
0.0.0.0 |
Interface to bind on Windows |
WINDOWS_IP |
- | Windows machine IP (Linux side) |
Windows (windows-bridge.js):
const TCP_PORT = 9333; // Change to desired portLinux:
socat UNIX-LISTEN:/tmp/claude-mcp-browser-bridge-$(whoami),fork,mode=600 \
TCP:${WINDOWS_IP}:9333| Component | Minimum Version |
|---|---|
| Claude Code CLI | 2.0.73+ |
| Claude Chrome Extension | 1.0.36+ |
| Node.js | 16+ |
| Chrome | Any recent version |
- Latency: Network round-trip adds delay compared to local execution
- Single session: One Claude Code session at a time per bridge instance
- Chrome only: Does not work with Chromium variants (Brave, Arc, etc.)
- Visible window: Requires a visible Chrome window on Windows (no headless mode)
- No authentication: Relies on network security
#!/bin/bash
# Start Claude Chrome bridge forwarder
WINDOWS_IP="${WINDOWS_IP:-192.168.1.100}"
TCP_PORT="${TCP_PORT:-9222}"
SOCKET_PATH="/tmp/claude-mcp-browser-bridge-$(whoami)"
# Kill existing forwarder
pkill -f "socat.*claude-mcp-browser-bridge" 2>/dev/null
sleep 1
# Remove old socket
rm -f "${SOCKET_PATH}"
# Test connectivity first
if ! nc -z "${WINDOWS_IP}" "${TCP_PORT}" 2>/dev/null; then
echo "Error: Cannot reach ${WINDOWS_IP}:${TCP_PORT}"
echo "Ensure Windows bridge is running and firewall allows connections"
exit 1
fi
# Start forwarder
socat UNIX-LISTEN:${SOCKET_PATH},fork,mode=600 TCP:${WINDOWS_IP}:${TCP_PORT} &
SOCAT_PID=$!
echo "Bridge started (PID: ${SOCAT_PID})"
echo " Socket: ${SOCKET_PATH}"
echo " Target: ${WINDOWS_IP}:${TCP_PORT}"@echo off
cd /d "%~dp0"
echo Starting Claude Chrome Bridge...
node windows-bridge.js
pauseContributions are welcome! Please feel free to submit issues and pull requests.
MIT License - See LICENSE for details.
- Built for use with Claude Code by Anthropic
- Uses the Claude Chrome extension's native messaging infrastructure