Setting Up a Remote Browser Debugging Endpoint on Windows
Categories:
This article explains how to run Chrome on a Windows host and expose a remote debugging endpoint via CDP for LAN clients or MCP to connect. The core of the solution is that Chrome only listens on 127.0.0.1, which is then mapped to a LAN address via portproxy, and further restricted by firewall rules for remote sources.
Topology and Flow
The diagram below illustrates the port flow within the Windows host and how clients access it over the LAN.
flowchart TB
subgraph Windows
A[Chrome DevTools 127.0.0.1:9222] --> B[portproxy 192.168.31.2:9222]
B --> C[Windows Firewall]
end
D[Linux Client] -->|CDP| B
classDef local fill:#2c3e50,stroke:#ecf0f1,stroke-width:2px,color:#ecf0f1
classDef proxy fill:#3498db,stroke:#2980b9,stroke-width:2px,color:#fff
classDef firewall fill:#f39c12,stroke:#d35400,stroke-width:2px,color:#fff
classDef client fill:#27ae60,stroke:#229954,stroke-width:2px,color:#fff
class A local
class B proxy
class C firewall
class D clientLaunching Chrome
It’s recommended to use an isolated user data directory and explicitly specify the remote debugging address, so Chrome only exposes the debugging port locally. The example below uses port 9222; adjust according to your actual setup.
& "C:\Program Files\Google\Chrome\Application\chrome.exe" `
--remote-debugging-address=127.0.0.1 `
--remote-debugging-port=9222 `
--user-data-dir="$env:TEMP\chrome-profile-mcp"
Configuring Port Forwarding
Use portproxy to map the local 127.0.0.1:9222 to the Windows LAN address 192.168.31.2:9222, enabling LAN clients to access it.
netsh interface portproxy add v4tov4 `
listenaddress=192.168.31.2 listenport=9222 `
connectaddress=127.0.0.1 connectport=9222 `
protocol=tcp
Confirm the rule is active by checking the current forwarding configuration.
netsh interface portproxy show v4tov4
Configuring the Firewall
To limit the exposure surface, restrict access to the port to only specified client IPs. The example below allows connections from 192.168.31.162.
New-NetFirewallRule `
-DisplayName "Allow CDP 9222 from Linux" `
-Direction Inbound `
-Action Allow `
-Protocol TCP `
-LocalPort 9222 `
-RemoteAddress 192.168.31.162
Verifying the Connection
When both the local and LAN addresses return /json/version, the connection is ready. This step also helps quickly identify whether the issue lies with Chrome, portproxy, or the firewall.
curl http://127.0.0.1:9222/json/version
curl http://192.168.31.2:9222/json/version
The diagram below illustrates the forwarding process of the verification request across components.
sequenceDiagram
participant Client as Client
participant Proxy as Portproxy
participant Chrome as Chrome
Client->>Proxy: HTTP /json/version
Proxy->>Chrome: 127.0.0.1:9222
Chrome-->>Proxy: JSON
Proxy-->>Client: JSONIntegrating with MCP
After exposing the port, MCP only needs to point to the LAN address. The example below connects chrome-devtools-mcp directly to 192.168.31.2:9222.
{
"chrome-devtools": {
"command": "npx",
"args": [
"-y",
"chrome-devtools-mcp@latest",
"--browser-url=http://192.168.31.2:9222"
]
}
}
Cleanup and Recovery
Portproxy rules are persistent. If no longer needed, remove the mapping and firewall rules to avoid accidentally exposing the debugging port.
netsh interface portproxy delete v4tov4 listenaddress=192.168.31.2 listenport=9222 protocol=tcp
If you change the port or IP, update the Chrome arguments, portproxy rules, firewall rules, and MCP configuration accordingly to avoid connection inconsistencies.
Remote debugging ports provide full browser control. They should never be exposed to the public internet and should not be left open in production environments. If cross-network usage is required, prioritize VPN or zero-trust tunnels, and maintain minimal privileges and exposure.