Working with Chrome DevTools Protocol (CDP) from Antigravity IDE over WSL

Before migrating to WSL, Chrome DevTools Protocol (CDP) and the Antigravity chrome-devtools-mcp server functioned perfectly because everything was running natively within the same Windows realm (using standard localhost).

However, after migrating dependencies and workflows to WSL, the network boundary separated the Chrome browser instance (running on the Windows host) from the MCP server (running in WSL). This breaks standard accessibility due to internal Chrome security restrictions on Host definitions and IP bridging. Compounding the network issues, the standard JavaScript runtimes in WSL can struggle with WebSocket protocols over these boundaries.

The guide below documents the exact workflow adjustments required to restore functionality.


Part 1: Allowing Remote Debugging in Windows

To allow WSL to communicate with Windows, we first need to start Chrome with remote debugging open, and then forward the internal Windows localhost port to the WSL virtual network adapter.

1. Launch Chrome with Debugging Profile

Run the following PowerShell script to open a fresh instance of Chrome with the correct debugger port:

Start-Process "chrome.exe" -ArgumentList "--remote-debugging-port=9222", "--user-data-dir=$env:TEMP\chrome-debug"

2. Create the Port Proxy Bridge

WSL sits on a different IP subnet than Windows localhost. We need to use netsh to bridge the WSL virtual adapter IP (e.g., 172.19.0.1) to the Windows localhost where Chrome is listening.

Run this in an Administrator PowerShell:

netsh interface portproxy add v4tov4 listenport=9222 listenaddress=172.19.0.1 connectport=9222 connectaddress=127.0.0.1

[!TIP] You can verify the port is open and listening by running: netstat -ano | findstr :9222


Part 2: Establishing the WSL Connection

We now need to ensure the WSL container correctly routes CDP traffic to the Windows Host.

1. Identify the Windows Host IP

Find your specific gateway / nameserver IP which points back to the Windows Host.

cat /etc/resolv.conf
# Look for the lines corresponding to your IP, for example:
# nameserver 172.19.0.1

[!NOTE] Validate the CDP connection to the host using curl: curl http://172.19.0.1:9222/json/version

2. Set Up a Local Listener with socat

While the 172.19.0.1:9222 address is accessible, Node.js and Bun's WebSocket libraries (ws) utilized by Puppeteer will strictly throw an Unexpected server response: 101 when attempting to upgrade the connection across a non-localhost boundary due to Host header origin security.

To trick the runtime into seeing this as a native local connection, use socat to relay the traffic locally:

socat TCP-LISTEN:9222,fork,bind=127.0.0.1 TCP:172.19.0.1:9222 &

Validate the local relay is working:

curl http://localhost:9222/json/version

(This should perfectly return the WebSocket URLs with localhost injected).


Part 3: Solving the Runtime Conflicts (Deno vs Bun)

Even with socat tricking the network, attempting to run chrome-devtools-mcp utilizing Bun (bunx) results in severe backend crashes (leading to client is closing: EOF). This is caused by underlying incompatibilities between Puppeteer / WebSocket libraries and Bun's Node compatibility layer when traversing Chrome targets.

If you prefer to avoid Node.js / npm entirely on your system, the most stable solution is to switch the execution runtime to Deno.

Update your MCP Configuration

Edit your mcp_config.json (typically located in ~/.gemini/antigravity/mcp_config.json) replacing the bunx array execution with deno, executing quietly (-q) via npm specifiers to prevent unformatted standard-output from crashing the JSON-RPC interface.

    "chrome-devtools": {
      "command": "/home/user/.deno/bin/deno",
      "args": [
        "run",
        "-A",
        "-q",
        "npm:chrome-devtools-mcp@latest",
        "--browserUrl=http://127.0.0.1:9222"
      ],
      "disabled": false
    }

[!IMPORTANT]

  • Point the --browserUrl strictly to the 127.0.0.1:9222 exposed by your socat process.
  • Ensure the command correctly targets your absolute deno binary path, as background spawned MCP servers may lack standard $PATH environments.
  • The -q (quiet) flag is critical to prevent Deno from printing NPM install/download warnings to standard output, which corrupts the structured JSON RPC protocol.

0 Comments

Add a comment