Chrome DevTools MCP Setup for WSL2: Complete Guide
Chrome DevTools MCP Setup for WSL2
Complete guide for running Chrome on Windows while controlling it from Claude Code in WSL2.
Overview
This setup allows Claude Code running in WSL2 to control Chrome browser running on Windows host through the Chrome DevTools Protocol.
Architecture:
Claude Code (WSL2) → 172.30.64.1:9222 → Port Proxy (Windows) → 127.0.0.1:9222 → Chrome (Windows)
Prerequisites
- Windows 11 with WSL2 installed
- Chrome installed on Windows
- Claude Code running in WSL2
- Administrator privileges on Windows
Quick Start
1. Start Chrome with Debugging
From WSL2, run:
./start-chrome-windows.sh
Or manually from Windows PowerShell:
Start-Process "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "--remote-debugging-port=9222","--user-data-dir=C:\Temp\chrome-debug"
2. Verify Connection
Test from WSL2:
curl -s http://172.30.64.1:9222/json/version
Expected output:
{
"Browser": "Chrome/138.0.7204.97",
"Protocol-Version": "1.3",
...
}
3. Restart Claude Code
The MCP configuration is already set up in ~/.claude.json. Just restart Claude Code to activate the chrome-devtools MCP server.
Configuration Details
MCP Configuration (~/.claude.json)
"chrome-devtools": {
"command": "npx",
"args": [
"-y",
"chrome-devtools-mcp@latest",
"--remoteDebuggingPort",
"9222"
],
"env": {
"CHROME_HOST": "172.30.64.1"
}
}
Windows Port Proxy
Forwards connections from WSL2 network interface to Chrome:
Listen: 172.30.64.1:9222
Forward to: 127.0.0.1:9222
View configuration:
powershell.exe -Command "netsh interface portproxy show v4tov4"
Windows Firewall Rules
Two firewall rules allow inbound connections:
- Chrome Remote Debugging: General rule for port 9222
- Chrome Debug WSL: Specific rule for WSL adapter IP (172.30.64.1)
View rules:
powershell.exe -Command "Get-NetFirewallRule -DisplayName 'Chrome*Debug*' | Format-List DisplayName,Enabled,Action"
Setup Scripts
start-chrome-windows.sh
Starts Chrome on Windows with remote debugging enabled:
#!/bin/bash
# Start Chrome on Windows with remote debugging enabled for Claude Code in WSL2
echo "Starting Chrome on Windows with remote debugging..."
echo "Port 9222 will be accessible from WSL2 via 172.30.64.1"
echo
# Check if Chrome is already running
if powershell.exe -Command "Get-Process chrome -ErrorAction SilentlyContinue" > /dev/null 2>&1; then
echo "⚠️ Chrome is already running. Stopping existing instances..."
powershell.exe -Command "Stop-Process -Name chrome -Force" 2>/dev/null
sleep 2
fi
# Start Chrome with debugging enabled
echo "🚀 Starting Chrome..."
powershell.exe -Command "Start-Process 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' -ArgumentList '--remote-debugging-port=9222','--user-data-dir=C:\Temp\chrome-debug' -WindowStyle Normal" 2>/dev/null
# Wait for Chrome to start
sleep 3
# Check if Chrome started successfully
if ! powershell.exe -Command "Get-Process chrome -ErrorAction SilentlyContinue" > /dev/null 2>&1; then
echo "❌ Failed to start Chrome. Please check if Chrome is installed at:"
echo " C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
exit 1
fi
# Verify debugging port is accessible
echo "🔍 Checking if Chrome debugging port is accessible..."
sleep 2
if curl -s http://172.30.64.1:9222/json/version > /dev/null 2>&1; then
echo "✅ Chrome started successfully and is accessible from WSL2!"
echo
echo "Chrome DevTools Protocol endpoint: http://172.30.64.1:9222"
echo
echo "Test connection:"
echo " curl -s http://172.30.64.1:9222/json/version"
echo
echo "You can now restart Claude Code to use the chrome-devtools MCP server."
else
echo "⚠️ Chrome started but debugging port is not accessible yet."
echo "This may take a few more seconds. Try testing manually:"
echo " curl -s http://172.30.64.1:9222/json/version"
echo
echo "If connection fails, run: ./check-connection.sh"
fi
setup-network.sh
One-time network setup script that configures Windows port proxy and firewall rules:
#!/bin/bash
# One-time network setup for Chrome DevTools MCP in WSL2
# Configures Windows port proxy and firewall rules
echo "Chrome DevTools MCP Network Setup for WSL2"
echo "=========================================="
echo
# Get WSL adapter IP from Windows
echo "🔍 Detecting WSL adapter IP address..."
WSL_IP=$(powershell.exe -Command "Get-NetIPAddress -InterfaceAlias 'vEthernet (WSL)' -AddressFamily IPv4 | Select-Object -ExpandProperty IPAddress" | tr -d '\r')
if [ -z "$WSL_IP" ]; then
echo "❌ Failed to detect WSL adapter IP address"
echo "Please run this command manually in PowerShell (as Administrator):"
echo " Get-NetIPAddress -InterfaceAlias 'vEthernet (WSL)' -AddressFamily IPv4"
exit 1
fi
echo "✅ WSL adapter IP: $WSL_IP"
echo
# Check if running with admin privileges
echo "🔐 Checking administrator privileges..."
powershell.exe -Command "if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) { exit 1 }" 2>/dev/null
if [ $? -ne 0 ]; then
echo "❌ This script requires administrator privileges"
echo
echo "Please run PowerShell as Administrator and execute:"
echo " wsl -d Ubuntu bash /home/panxf/devtools/setup-network.sh"
exit 1
fi
echo "✅ Running with administrator privileges"
echo
# Configure port proxy
echo "⚙️ Configuring port proxy..."
echo " Forwarding: $WSL_IP:9222 → 127.0.0.1:9222"
# Remove existing port proxy rule if it exists
powershell.exe -Command "netsh interface portproxy delete v4tov4 listenport=9222 listenaddress=$WSL_IP" 2>/dev/null
# Add new port proxy rule
powershell.exe -Command "netsh interface portproxy add v4tov4 listenport=9222 listenaddress=$WSL_IP connectport=9222 connectaddress=127.0.0.1" 2>/dev/null
if [ $? -eq 0 ]; then
echo "✅ Port proxy configured successfully"
else
echo "❌ Failed to configure port proxy"
exit 1
fi
echo
# Configure firewall rules
echo "🛡️ Configuring Windows Firewall rules..."
# Rule 1: General Chrome Remote Debugging
echo " Creating rule: Chrome Remote Debugging"
powershell.exe -Command "Remove-NetFirewallRule -DisplayName 'Chrome Remote Debugging' -ErrorAction SilentlyContinue" 2>/dev/null
powershell.exe -Command "New-NetFirewallRule -DisplayName 'Chrome Remote Debugging' -Direction Inbound -LocalPort 9222 -Protocol TCP -Action Allow -Profile Any" 2>/dev/null | Out-Null
if [ $? -eq 0 ]; then
echo " ✅ Chrome Remote Debugging rule created"
else
echo " ❌ Failed to create Chrome Remote Debugging rule"
fi
# Rule 2: Specific WSL adapter rule
echo " Creating rule: Chrome Debug WSL ($WSL_IP)"
powershell.exe -Command "Remove-NetFirewallRule -DisplayName 'Chrome Debug WSL' -ErrorAction SilentlyContinue" 2>/dev/null
powershell.exe -Command "New-NetFirewallRule -DisplayName 'Chrome Debug WSL' -Direction Inbound -LocalAddress $WSL_IP -LocalPort 9222 -Protocol TCP -Action Allow -Profile Any" 2>/dev/null | Out-Null
if [ $? -eq 0 ]; then
echo " ✅ Chrome Debug WSL rule created"
else
echo " ❌ Failed to create Chrome Debug WSL rule"
fi
echo
# Update Claude Code config with correct IP
echo "📝 Updating Claude Code MCP configuration..."
CLAUDE_CONFIG="$HOME/.claude.json"
if [ -f "$CLAUDE_CONFIG" ]; then
# Check if chrome-devtools MCP exists
if grep -q '"chrome-devtools"' "$CLAUDE_CONFIG"; then
# Update CHROME_HOST with new IP
sed -i.bak "s/\"CHROME_HOST\": \"[^\"]*\"/\"CHROME_HOST\": \"$WSL_IP\"/" "$CLAUDE_CONFIG"
echo "✅ Updated CHROME_HOST to $WSL_IP in $CLAUDE_CONFIG"
else
echo "⚠️ chrome-devtools MCP not found in $CLAUDE_CONFIG"
echo " Please add it manually or run Claude Code to generate it"
fi
else
echo "⚠️ $CLAUDE_CONFIG not found"
fi
echo
# Display configuration summary
echo "✅ Network setup completed!"
echo
echo "Configuration Summary:"
echo "====================="
echo "WSL Adapter IP: $WSL_IP"
echo "Port Proxy: $WSL_IP:9222 → 127.0.0.1:9222"
echo "Firewall Rules: Chrome Remote Debugging, Chrome Debug WSL"
echo
echo "Next Steps:"
echo "1. Start Chrome: ./start-chrome-windows.sh"
echo "2. Verify connection: curl -s http://$WSL_IP:9222/json/version"
echo "3. Restart Claude Code to use the chrome-devtools MCP server"
echo
echo "View configuration:"
echo " Port Proxy: powershell.exe -Command 'netsh interface portproxy show v4tov4'"
echo " Firewall: powershell.exe -Command \"Get-NetFirewallRule -DisplayName 'Chrome*Debug*' | Format-List\""
check-connection.sh
Diagnostic script to verify the entire setup:
#!/bin/bash
# Diagnostic script for Chrome DevTools MCP connection in WSL2
echo "Chrome DevTools MCP Connection Diagnostics"
echo "=========================================="
echo
# Get WSL adapter IP
echo "🔍 WSL Network Configuration"
echo "----------------------------"
WSL_IP=$(powershell.exe -Command "Get-NetIPAddress -InterfaceAlias 'vEthernet (WSL)' -AddressFamily IPv4 | Select-Object -ExpandProperty IPAddress" | tr -d '\r')
if [ -z "$WSL_IP" ]; then
echo "❌ Failed to detect WSL adapter IP"
else
echo "✅ WSL Adapter IP: $WSL_IP"
fi
DNS_SERVER=$(grep nameserver /etc/resolv.conf | awk '{print $2}')
echo "ℹ️ DNS Server: $DNS_SERVER"
echo
# Check Chrome process
echo "🌐 Chrome Process Status"
echo "------------------------"
CHROME_RUNNING=$(powershell.exe -Command "Get-Process chrome -ErrorAction SilentlyContinue | Measure-Object | Select-Object -ExpandProperty Count" | tr -d '\r')
if [ "$CHROME_RUNNING" -gt 0 ]; then
echo "✅ Chrome is running ($CHROME_RUNNING process(es))"
# Check Chrome listening ports
echo
echo "🔌 Chrome Listening Ports"
echo "-------------------------"
powershell.exe -Command "netstat -ano | Select-String ':9222' | Select-String 'LISTENING'" 2>/dev/null | head -5
else
echo "❌ Chrome is not running"
echo " Start Chrome: ./start-chrome-windows.sh"
fi
echo
# Check port proxy configuration
echo "🔀 Port Proxy Configuration"
echo "---------------------------"
PROXY_CONFIG=$(powershell.exe -Command "netsh interface portproxy show v4tov4 | Select-String '9222'" | tr -d '\r')
if [ -n "$PROXY_CONFIG" ]; then
echo "✅ Port proxy configured:"
powershell.exe -Command "netsh interface portproxy show v4tov4 | Select-String '9222'" 2>/dev/null
else
echo "❌ Port proxy not configured for port 9222"
echo " Run: ./setup-network.sh"
fi
echo
# Check firewall rules
echo "🛡️ Firewall Rules"
echo "------------------"
FIREWALL_RULES=$(powershell.exe -Command "Get-NetFirewallRule -DisplayName 'Chrome*Debug*' -ErrorAction SilentlyContinue | Measure-Object | Select-Object -ExpandProperty Count" | tr -d '\r')
if [ "$FIREWALL_RULES" -gt 0 ]; then
echo "✅ Firewall rules configured ($FIREWALL_RULES rule(s))"
powershell.exe -Command "Get-NetFirewallRule -DisplayName 'Chrome*Debug*' | Select-Object DisplayName,Enabled,Action | Format-Table -AutoSize" 2>/dev/null
else
echo "❌ No firewall rules found for Chrome debugging"
echo " Run: ./setup-network.sh"
fi
echo
# Check connectivity from WSL2
echo "🔗 WSL2 Connectivity Test"
echo "-------------------------"
if [ -z "$WSL_IP" ]; then
echo "❌ Cannot test connectivity without WSL adapter IP"
else
echo "Testing connection to http://$WSL_IP:9222/json/version..."
RESPONSE=$(curl -s -m 5 http://$WSL_IP:9222/json/version 2>&1)
CURL_EXIT=$?
if [ $CURL_EXIT -eq 0 ]; then
echo "✅ Connection successful!"
echo
echo "Chrome Version Info:"
echo "$RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RESPONSE"
else
echo "❌ Connection failed (exit code: $CURL_EXIT)"
echo
echo "Error details:"
echo "$RESPONSE"
echo
echo "Troubleshooting steps:"
echo "1. Verify Chrome is running: powershell.exe -Command 'Get-Process chrome'"
echo "2. Check port proxy: powershell.exe -Command 'netsh interface portproxy show v4tov4'"
echo "3. Verify firewall rules: ./check-connection.sh"
echo "4. Restart Chrome: ./start-chrome-windows.sh"
echo "5. Re-run network setup: ./setup-network.sh"
fi
fi
echo
# Check Claude Code MCP configuration
echo "⚙️ Claude Code MCP Configuration"
echo "---------------------------------"
CLAUDE_CONFIG="$HOME/.claude.json"
if [ -f "$CLAUDE_CONFIG" ]; then
if grep -q '"chrome-devtools"' "$CLAUDE_CONFIG"; then
echo "✅ chrome-devtools MCP server configured"
# Extract CHROME_HOST value
CHROME_HOST=$(grep -A 10 '"chrome-devtools"' "$CLAUDE_CONFIG" | grep '"CHROME_HOST"' | sed 's/.*"CHROME_HOST": "\([^"]*\)".*/\1/')
if [ -n "$CHROME_HOST" ]; then
echo " CHROME_HOST: $CHROME_HOST"
if [ "$CHROME_HOST" = "$WSL_IP" ]; then
echo " ✅ CHROME_HOST matches WSL adapter IP"
else
echo " ⚠️ CHROME_HOST ($CHROME_HOST) differs from WSL adapter IP ($WSL_IP)"
echo " Consider updating: Run ./setup-network.sh"
fi
fi
else
echo "❌ chrome-devtools MCP not found in configuration"
fi
else
echo "❌ Claude Code configuration not found at $CLAUDE_CONFIG"
fi
echo
# Summary
echo "📊 Diagnostic Summary"
echo "--------------------"
echo "Chrome Running: $([ "$CHROME_RUNNING" -gt 0 ] && echo 'YES' || echo 'NO')"
echo "Port Proxy: $([ -n "$PROXY_CONFIG" ] && echo 'CONFIGURED' || echo 'NOT CONFIGURED')"
echo "Firewall: $([ "$FIREWALL_RULES" -gt 0 ] && echo 'CONFIGURED' || echo 'NOT CONFIGURED')"
echo "WSL2 Connection: $([ $CURL_EXIT -eq 0 ] && echo 'WORKING' || echo 'FAILED')"
echo
if [ "$CHROME_RUNNING" -gt 0 ] && [ -n "$PROXY_CONFIG" ] && [ "$FIREWALL_RULES" -gt 0 ] && [ $CURL_EXIT -eq 0 ]; then
echo "✅ All systems operational!"
echo " You can now use chrome-devtools MCP in Claude Code"
echo " Restart Claude Code if it's already running"
else
echo "⚠️ Some issues detected. Follow the troubleshooting steps above."
fi
Troubleshooting
Check if Chrome is Running
powershell.exe -Command "Get-Process chrome -ErrorAction SilentlyContinue | Select-Object Id,ProcessName"
Check Chrome Listening Ports
powershell.exe -Command "netstat -ano | Select-String ':9222' | Select-String 'LISTENING'"
Expected output:
TCP 127.0.0.1:9222 0.0.0.0:0 LISTENING <PID>
TCP 172.30.64.1:9222 0.0.0.0:0 LISTENING <PID>
Check WSL Adapter IP Address
If connection fails, verify the WSL adapter IP hasn't changed:
powershell.exe -Command "Get-NetIPAddress -InterfaceAlias 'vEthernet (WSL)' -AddressFamily IPv4 | Select-Object IPAddress"
If IP changed from 172.30.64.1, update:
- Port proxy configuration (run
./setup-network.sh) - MCP configuration in
~/.claude.json(CHROME_HOSTvalue)
Stop Chrome
powershell.exe -Command "Stop-Process -Name chrome -Force"
Network Architecture Details
Why Port Proxy is Needed
Chrome binds the debugging port to 127.0.0.1 (localhost only) for security. WSL2 runs in a separate network namespace and cannot access Windows localhost directly. The port proxy forwards connections from the WSL network interface (172.30.64.1) to Windows localhost (127.0.0.1).
IP Address Explanation
127.0.0.1- Windows localhost (Chrome listens here)172.30.64.1- Windows WSL adapter IP (WSL2 connects here)10.255.255.254- DNS server in WSL2 (not used for Chrome connection)
Security Notes
- Chrome debugging port is only accessible from the local machine
- Firewall rules restrict access to WSL2 subnet only
- Use a separate Chrome profile (
--user-data-dir) to avoid conflicts - Never expose debugging port to external networks
Resources
Changelog
2025-10-31
- Initial setup completed
- WSL adapter IP: 172.30.64.1
- Port proxy configured: 172.30.64.1:9222 → 127.0.0.1:9222
- Firewall rules created
- MCP configuration updated
- Connection verified working