Complete guide to setting up Antigravity's browser subagent in a WSL2 + Windows 11 environment.
- Overview
- Requirements
- The Challenge
- Solution Architecture
- Setup Instructions
- Troubleshooting
- Known Issues
This guide documents the complete setup process for enabling Antigravity's browser subagent to control Chrome from WSL2, including solutions to common networking and security issues.
- OS: Windows 11 Pro/Enterprise (tested on Build 26200+)
- WSL: WSL2 with Ubuntu or similar
- Python: 3.10+ (on Windows)
- Chrome: Chrome for Testing (not regular Chrome)
Antigravity's browser subagent needs to connect to Chrome's remote debugging interface via CDP (Chrome DevTools Protocol). In WSL2, this requires bridging the network gap between the Linux environment and Windows Chrome, which is complicated by:
- Chrome security restrictions - Chrome 136+ ignores
--remote-debugging-address=0.0.0.0and only binds to127.0.0.1 - Port conflicts - Windows IP Helper service (
iphlpsvc) occupies port 9222 by default - WSL2 network isolation - WSL can't access Windows localhost services directly
- WSL localhost forwarding issues - The
localhostForwardingfeature in.wslconfigis unreliable
A three-layer bridge architecture:
┌─────────────────────────────────────────┐
│ WSL2 (Ubuntu) │
│ │
│ Antigravity Browser Subagent │
│ ↓ │
│ localhost:9222 (socat bridge) │
│ ↓ │
└───────────┼─────────────────────────────┘
│
↓ TCP to <WINDOWS_IP>:9222
│
┌───────────┼─────────────────────────────┐
│ │ Windows 11 │
│ ↓ │
│ Python TCP Proxy (0.0.0.0:9222) │
│ ↓ │
│ Chrome for Testing (127.0.0.1:9223) │
└─────────────────────────────────────────┘
# Download from: https://googlechromelabs.github.io/chrome-for-testing/
# Select latest stable Windows x64 version
# Extract to: C:\ChromeForTesting\Port 9222 (Chrome's default debugging port) is typically occupied by Windows IP Helper service:
# PowerShell (Admin)
Stop-Service iphlpsvc
# Verify
Get-Service iphlpsvc # Should show "Stopped"Note: IP Helper provides IPv6 transition technologies. Stopping it is generally safe, but you can restart it later if needed: Start-Service iphlpsvc
# Using winget (recommended) - if you are running an admin version of PowerShell, you will need to suffix "--scope machine" to the command
winget install Python.Python.3.12
# Or download from python.orgClose and reopen PowerShell after installation, then verify:
python --version # Should show Python 3.12.xCreate chrome-proxy.py in your user directory (e.g., C:\Users\<YourUsername>\chrome-proxy.py):
#!/usr/bin/env python3
"""TCP proxy: 0.0.0.0:9222 -> 127.0.0.1:9223"""
import socket
import threading
LISTEN_PORT = 9222
TARGET_HOST = "127.0.0.1"
TARGET_PORT = 9223
def handle_client(client_socket, client_addr):
try:
target = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
target.connect((TARGET_HOST, TARGET_PORT))
def forward(source, destination):
try:
while True:
data = source.recv(8192)
if not data:
break
destination.sendall(data)
except:
pass
finally:
source.close()
destination.close()
c2t = threading.Thread(target=forward, args=(client_socket, target), daemon=True)
t2c = threading.Thread(target=forward, args=(target, client_socket), daemon=True)
c2t.start()
t2c.start()
c2t.join()
t2c.join()
except Exception as e:
print(f"Error: {e}")
finally:
try:
client_socket.close()
except:
pass
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("0.0.0.0", LISTEN_PORT))
server.listen(5)
print(f"Chrome Debug Proxy")
print(f"Listening: 0.0.0.0:{LISTEN_PORT} -> {TARGET_HOST}:{TARGET_PORT}")
print("Press Ctrl+C to stop\n")
try:
while True:
client, addr = server.accept()
print(f"[{addr[0]}:{addr[1]}] Connected")
threading.Thread(target=handle_client, args=(client, addr), daemon=True).start()
except KeyboardInterrupt:
print("\nShutting down...")
finally:
server.close()
if __name__ == "__main__":
main()# PowerShell (Admin)
New-NetFirewallRule -DisplayName "Chrome Debug Proxy 9222" `
-Direction Inbound `
-LocalPort 9222 `
-Protocol TCP `
-Action Allow `
-Profile Any# WSL Terminal
cat > ~/dummy-browser.sh << 'EOF'
#!/bin/bash
echo "DevTools listening on ws://127.0.0.1:9222/devtools/browser/fake-uuid"
sleep 365d
EOF
chmod +x ~/dummy-browser.shWhy needed: Antigravity expects a local browser binary. This script satisfies that requirement while the actual Chrome runs on Windows.
sudo apt update
sudo apt install socat -y# Get the Windows host IP from WSL
ip route show | grep -i default | awk '{print $3}'Note this IP - you'll need it later (e.g., 172.29.112.1 or similar). We'll call this <WINDOWS_IP>.
Alternatively, from Windows PowerShell:
(Get-NetIPAddress -AddressFamily IPv4 | Where-Object {$_.IPAddress -notlike "127.*" -and $_.IPAddress -notlike "169.*"}).IPAddressIn Antigravity/VS Code settings:
- Browser Binary Path:
/home/<your-username>/dummy-browser.sh - Browser CDP Port:
9222
You need 2 Windows PowerShell windows + 1 WSL terminal:
# Launch Chrome for Testing
& "C:\ChromeForTesting\chrome-win64\chrome.exe" `
--remote-debugging-port=9223 `
--user-data-dir="C:\ChromeTestingProfile" `
--no-first-runKeep this window open. Chrome will launch with debugging enabled on port 9223.
# Run Python proxy
python C:\Users\<YourUsername>\chrome-proxy.pyYou should see:
Chrome Debug Proxy
Listening: 0.0.0.0:9222 -> 127.0.0.1:9223
Press Ctrl+C to stop
Keep this window open.
Replace <WINDOWS_IP> with your actual Windows IP:
# Start socat bridge
killall socat 2>/dev/null
nohup socat TCP-LISTEN:9222,fork,reuseaddr TCP:<WINDOWS_IP>:9222 > /tmp/socat.log 2>&1 &From WSL, test the connection:
# Direct test (to Python proxy)
curl http://<WINDOWS_IP>:9222/json/version
# Via socat (to localhost)
curl http://localhost:9222/json/versionExpected output (both commands):
{
"Browser": "Chrome/143.0.7499.192",
"Protocol-Version": "1.3",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
"webSocketDebuggerUrl": "ws://..."
}When you first run the Antigravity browser subagent:
- Chrome will open to an onboarding page
- Follow the link to install the Antigravity browser extension
- Accept permission prompts
- The browser subagent will now work
If you get an error while trying to install the extension, then launch ChromeForTesting not via the command line (navigate to it in your directory structure and double click the .exe file), and then install the extension manually. Close the browser. Verify that launching via the command line (command above) has the extension installed.
Check if Chrome is running:
# Windows
Get-Process | Where-Object {$_.ProcessName -like "*chrome*"}
netstat -an | findstr 9223Should show: TCP 127.0.0.1:9223 ... LISTENING
Fix: Restart Chrome for Testing (Terminal 1)
Test Chrome locally on Windows:
Invoke-WebRequest -Uri "http://127.0.0.1:9223/json/version" -UseBasicParsingIf this fails, Chrome debugging isn't working.
Fix:
# Kill Chrome
taskkill /F /IM chrome.exe /T
# Restart
& "C:\ChromeForTesting\chrome-win64\chrome.exe" `
--remote-debugging-port=9223 `
--user-data-dir="C:\ChromeTestingProfile" `
--no-first-runCheck firewall:
Get-NetFirewallRule -DisplayName "Chrome Debug Proxy 9222"Fix if missing:
New-NetFirewallRule -DisplayName "Chrome Debug Proxy 9222" `
-Direction Inbound `
-LocalPort 9222 `
-Protocol TCP `
-Action Allow `
-Profile AnyCheck what's using it:
Get-NetTCPConnection -LocalPort 9222 | ForEach-Object {
$proc = Get-Process -Id $_.OwningProcess
$proc.ProcessName + " (PID: " + $proc.Id + ")"
}Options:
- Stop the service/process
- Modify the Python proxy script to use a different port
- Reboot Windows
Check socat logs:
# WSL
cat /tmp/socat.logTest direct connection:
curl http://<WINDOWS_IP>:9222/json/versionIf direct works but localhost doesn't, restart socat:
killall socat
nohup socat TCP-LISTEN:9222,fork,reuseaddr TCP:<WINDOWS_IP>:9222 > /tmp/socat.log 2>&1 &❌ Windows PortProxy - Unreliable on Windows 11 25H2
❌ PowerShell TCP proxies - Threading issues with bidirectional relay
❌ Chrome --remote-debugging-address=0.0.0.0 - Ignored on Windows
❌ WSL localhost forwarding - Broken/unreliable even with .wslconfig
✅ Chrome for Testing - Specifically built for automation ✅ Python TCP proxy - Mature socket library handles bidirectional relay ✅ Port side-step - Using 9223 avoids IP Helper conflicts ✅ Three-layer architecture - Each layer verified independently
Windows PowerShell (save as start-chrome-debug.ps1):
# Start Chrome for Testing
Start-Process powershell -ArgumentList `
"-NoExit", `
"-Command", `
"& 'C:\ChromeForTesting\chrome-win64\chrome.exe' --remote-debugging-port=9223 --user-data-dir='C:\ChromeTestingProfile' --no-first-run"
Start-Sleep -Seconds 2
# Start Python proxy
Start-Process powershell -ArgumentList `
"-NoExit", `
"-Command", `
"python C:\Users\$env:USERNAME\chrome-proxy.py"
Write-Host "`nChrome for Testing and proxy started!"
Write-Host "`nIn WSL, run:"
Write-Host " killall socat 2>/dev/null; nohup socat TCP-LISTEN:9222,fork,reuseaddr TCP:<YOUR_WINDOWS_IP>:9222 > /tmp/socat.log 2>&1 &"
Write-Host "`nReplace <YOUR_WINDOWS_IP> with your actual Windows IP"Usage:
.\start-chrome-debug.ps1- Latency: ~5-10ms additional latency from Python proxy
- Stability: Very stable - Python's socket library is battle-tested
- Resource Usage: Python proxy uses ~10-20MB RAM
Windows:
- Windows 11 (tested on Build 26200+)
- Python 3.10+
- ~500MB disk space for Chrome for Testing
- Firewall rule for port 9222
WSL:
- WSL2 (Ubuntu or similar)
- socat package
- Network access to Windows host
This guide is provided as-is for educational and setup purposes. Chrome for Testing is provided by Google under the Chromium license.
Created during extensive troubleshooting of Antigravity browser subagent setup in WSL2 environment. Special thanks to the Antigravity team for their excellent debugging documentation.
If you find issues or improvements:
- Test on your system configuration
- Document your Windows build and WSL version
- Share what worked/didn't work
- Submit issues or PRs with details
Last Updated: January 2026 Tested On: Windows 11 Build 26200.7462, WSL2 Ubuntu 22.04
I wonder how the Cursor IDE does this because it can easily launch and control my windows chrome browser from within WSL without any configuration from my side.