|
| 1 | +--- |
| 2 | +authors: |
| 3 | +- copdips |
| 4 | +categories: |
| 5 | +- ai-coding |
| 6 | +- vscode |
| 7 | +- mcp |
| 8 | +- frontend |
| 9 | +- debug |
| 10 | +comments: true |
| 11 | +date: |
| 12 | + created: 2025-11-13 |
| 13 | +--- |
| 14 | + |
| 15 | +# Google Chrome DevTools MCP |
| 16 | + |
| 17 | +[Chrome DevTools MCP](https://github.com/ChromeDevTools/chrome-devtools-mcp?tab=readme-ov-file#chrome-devtools-mcp) (Model Context Protocol) allows you to interact with Google Chrome programmatically through AI coding agents like Claude Code, Copilot, Codex, etc. This enables automated testing, debugging, and inspection of web applications directly from the command line. |
| 18 | + |
| 19 | +<!-- more --> |
| 20 | + |
| 21 | +## Option 1 - Use Chrome installed on Windows |
| 22 | + |
| 23 | +### Start Chrome in debug mode in Windows machine |
| 24 | + |
| 25 | +```powershell |
| 26 | +& "C:\Program Files\Google\Chrome\Application\chrome.exe" ` |
| 27 | + --remote-debugging-address=0.0.0.0 ` |
| 28 | + --remote-debugging-port=9222 ` |
| 29 | + --user-data-dir=c:/temp/chrome-debug-profile ` |
| 30 | + --no-first-run ` |
| 31 | + --no-default-browser-check ` |
| 32 | + --disable-extensions |
| 33 | +
|
| 34 | +# check if Chrome is listening on port 9222 |
| 35 | +netstat -an | findstr "9222" |
| 36 | +
|
| 37 | +curl http://localhost:9222/json/version |
| 38 | +``` |
| 39 | + |
| 40 | +### Set reverse port forwarding from WSL to Windows |
| 41 | + |
| 42 | +Open an elevated admin Powershell: |
| 43 | + |
| 44 | +1. Identify the WSL interface IP address: |
| 45 | + |
| 46 | + ```powershell |
| 47 | + # https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/131#issuecomment-3447890859 |
| 48 | +
|
| 49 | + Get-NetIPAddress -AddressFamily IPv4 ` |
| 50 | + | Where-Object { $_.InterfaceAlias -like "vEthernet (WSL*)" } ` |
| 51 | + | Select-Object IPAddress |
| 52 | +
|
| 53 | +
|
| 54 | + # or from `ipconfig` then search for WSL part |
| 55 | + ``` |
| 56 | +
|
| 57 | +2. Set up port forwarding from Windows port 9222 to WSL port 9223: |
| 58 | +
|
| 59 | + ```powershell |
| 60 | + netsh interface portproxy add v4tov4 ` |
| 61 | + listenaddress=<WSL_IP_ADDRESS> ` |
| 62 | + listenport=9223 ` |
| 63 | + connectaddress=127.0.0.1 ` |
| 64 | + connectport=9222 |
| 65 | + ``` |
| 66 | +
|
| 67 | +3. Verify the port proxy is set up: |
| 68 | +
|
| 69 | + ```powershell |
| 70 | + netsh interface portproxy show all |
| 71 | + ``` |
| 72 | +
|
| 73 | +4. Open firewall for port 9223: |
| 74 | +
|
| 75 | + ```powershell |
| 76 | + New-NetFirewallRule -DisplayName "WSL Chrome DevTools Debug proxy" ` |
| 77 | + -Direction Inbound ` |
| 78 | + -LocalPort 9223 ` |
| 79 | + -Protocol TCP ` |
| 80 | + -Action Allow |
| 81 | + ``` |
| 82 | +
|
| 83 | +### Setup Chrome DevTools MCP in WSL/Linux |
| 84 | +
|
| 85 | +1. Node.js v22+ and npm installed |
| 86 | +2. Verify the port forwarding is working by running: |
| 87 | +
|
| 88 | + ```bash |
| 89 | + curl http://<WSL_IP_ADDRESS>:9223/json/version |
| 90 | + ``` |
| 91 | +
|
| 92 | + !!! note "Get WSL IP Address" |
| 93 | + Check [set-reverse-port-forwarding-from-wsl-to-windows](#set-reverse-port-forwarding-from-wsl-to-windows) for how to get `<WSL_IP_ADDRESS>`. |
| 94 | +
|
| 95 | +3. Use `http://<WSL_IP_ADDRESS>:9223` as the Chrome DevTools endpoint in WSL/Linux. |
| 96 | +
|
| 97 | + ```json title="file ~/.claude.json" |
| 98 | + "chrome-devtools": { |
| 99 | + "command": "npx", |
| 100 | + "args": [ |
| 101 | + "-y", |
| 102 | + "chrome-devtools-mcp@latest", |
| 103 | + "--browserUrl", |
| 104 | + "http://<WSL_IP_ADDRESS>:9223" |
| 105 | + ], |
| 106 | + "env": {} |
| 107 | + } |
| 108 | + ``` |
| 109 | +
|
| 110 | +### Use Chrome DevTools MCP Server with Claude Code |
| 111 | +
|
| 112 | +The MCP server is already installed if you're using Claude Code. Verify it: |
| 113 | +
|
| 114 | +```bash |
| 115 | +claude mcp list |
| 116 | +
|
| 117 | +# You should see (172.27.0.1 is my WSL host IP): |
| 118 | +# chrome-devtools: npx -y chrome-devtools-mcp@latest --browserUrl http://172.27.0.1:9223 - ✓ Connected |
| 119 | +``` |
| 120 | + |
| 121 | +If not, you can add it: |
| 122 | + |
| 123 | +```bash |
| 124 | +# use default stdio MCP transport |
| 125 | +claude mcp add chrome-devtools -- |
| 126 | + npx \ |
| 127 | + -y \ |
| 128 | + chrome-devtools-mcp@latest \ |
| 129 | + --browserUrl http://<WSL_IP_ADDRESS>:9223 |
| 130 | +``` |
| 131 | + |
| 132 | +There're [three types of MCP transports](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports): |
| 133 | + |
| 134 | +```bash |
| 135 | +$ claude --version |
| 136 | +2.0.27 (Claude Code) |
| 137 | + |
| 138 | +$ claude mcp add -h | grep transport |
| 139 | + claude mcp add --transport http sentry https://mcp.sentry.dev/mcp |
| 140 | + claude mcp add --transport sse asana https://mcp.asana.com/sse |
| 141 | + claude mcp add --transport stdio airtable --env AIRTABLE_API_KEY=YOUR_KEY -- npx -y airtable-mcp-server |
| 142 | + -t, --transport <transport> Transport type (stdio, sse, http). Defaults to stdio if not specified. |
| 143 | +``` |
| 144 | +
|
| 145 | +1. **stdio**: The default Claude to MCP is using `stdio` MCP transport. Which is for our use case, as From Claude's perspective, it just spawns a local `npx` command inside WSL as a subprocess and communicates through stdin/stdout. The MCP itself then uses HTTP to talk to remote Chrome started in Windows, but that's internal to the MCP, not part of the MCP transport type. |
| 146 | +2. **http**: Claude talks to a remote MCP over HTTP endpoints, you give it a base URL. The server must implement MCP protocol over plain HTTP requests. |
| 147 | +3. **sse** (Server-Sent Events): Claude opens a long-lived SSE channel to a remote MCP (useful for push events, live updates, or long-running tasks). Often used by cloud MCPs (e.g. `claude-mcp-github`, `claude-mcp-google`). |
| 148 | +
|
| 149 | +!!! note "In newer MCP spec, `https` and `sse` transports has been unified into `Streamable HTTP`" |
| 150 | +
|
| 151 | +## Option 2 - Use Chrome installed by apt in WSL |
| 152 | +
|
| 153 | +### Install Google Chrome in WSL |
| 154 | +
|
| 155 | +<https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps#install-google-chrome-for-linux> |
| 156 | +
|
| 157 | +```bash |
| 158 | +wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add - |
| 159 | +
|
| 160 | +sudo sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' |
| 161 | +
|
| 162 | +sudo apt update |
| 163 | +
|
| 164 | +sudo apt install google-chrome-stable |
| 165 | +
|
| 166 | +google-chrome --version |
| 167 | +
|
| 168 | +# Expected output: |
| 169 | +Google Chrome 141.0.7390.122 |
| 170 | +``` |
| 171 | +
|
| 172 | +### Start Chrome in WSL with Remote Debugging |
| 173 | +
|
| 174 | +Chrome must be started with special flags to enable remote debugging: |
| 175 | +
|
| 176 | +```bash |
| 177 | +# Create a directory for Chrome debug profile |
| 178 | +mkdir -p /tmp/chrome-debug-profile |
| 179 | +
|
| 180 | +# Start Chrome with remote debugging enabled |
| 181 | +google-chrome \ |
| 182 | + --remote-debugging-port=9222 \ |
| 183 | + --user-data-dir=/tmp/chrome-debug-profile \ |
| 184 | + --no-sandbox \ |
| 185 | + > /tmp/chrome.log 2>&1 & |
| 186 | +``` |
| 187 | +
|
| 188 | +**Important flags explained:** |
| 189 | +
|
| 190 | +- `--remote-debugging-port=9222` - Enables Chrome DevTools Protocol on port 9222 |
| 191 | +- `--user-data-dir=/tmp/chrome-debug-profile` - Required for remote debugging; uses separate profile |
| 192 | +- `--no-sandbox` - Needed in WSL environment (Chrome can't use sandboxing in WSL) |
| 193 | +- `> /tmp/chrome.log 2>&1 &` - Runs in background and logs output |
| 194 | +
|
| 195 | +### Configure Chrome DevTools MCP |
| 196 | +
|
| 197 | +```json title="file ~/.claude.json" |
| 198 | +"chrome-devtools": { |
| 199 | + "command": "npx", |
| 200 | + "args": [ |
| 201 | + "-y", |
| 202 | + "chrome-devtools-mcp@latest", |
| 203 | + "--browserUrl", |
| 204 | + "http://localhost:9222" |
| 205 | + ], |
| 206 | + "env": {} |
| 207 | +} |
| 208 | +``` |
| 209 | +
|
| 210 | +### Verify Chrome Debugging is Working |
| 211 | +
|
| 212 | +Check that Chrome is listening on port 9222: |
| 213 | +
|
| 214 | +```bash |
| 215 | +ss -tuln | grep 9222 |
| 216 | +``` |
| 217 | +
|
| 218 | +Test the debugging API: |
| 219 | +
|
| 220 | +```bash |
| 221 | +# Get Chrome version |
| 222 | +curl -s http://localhost:9222/json/version |
| 223 | +
|
| 224 | +# List all pages |
| 225 | +curl -s http://localhost:9222/json/list |
| 226 | +``` |
| 227 | +
|
| 228 | +### Test MCP Connection |
| 229 | +
|
| 230 | +List open pages: |
| 231 | +
|
| 232 | +```bash |
| 233 | +# In Claude Code, this tool will be available |
| 234 | +mcp__chrome-devtools__list_pages |
| 235 | +``` |
| 236 | +
|
| 237 | +### Troubleshooting |
| 238 | +
|
| 239 | +#### Stopping Chrome |
| 240 | +
|
| 241 | +```bash |
| 242 | +# Kill Chrome processes |
| 243 | +pkill -f 'chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug-profile --no-sandbox' |
| 244 | +
|
| 245 | +# Or kill specific PID |
| 246 | +ps faux | grep 'chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug-profile --no-sandbox' |
| 247 | +kill <PID> |
| 248 | +``` |
| 249 | +
|
| 250 | +#### Check Chrome logs |
| 251 | +
|
| 252 | +```bash |
| 253 | +tail -f /tmp/chrome.log |
| 254 | +``` |
| 255 | +
|
| 256 | +## Option 3 - Use Chromium installed by npx puppeteer/browsers in WSL |
| 257 | +
|
| 258 | +Ref: https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/281#issuecomment-3417556091 |
| 259 | +
|
| 260 | +### Install Chromium using Puppeteer Browsers |
| 261 | +
|
| 262 | +```bash |
| 263 | +npx -y @puppeteer/browsers install chrome@stable --path ~/chrome |
| 264 | +
|
| 265 | +# note the chrome installation path or use find ~/chrome -name chrome -type f |
| 266 | +``` |
| 267 | +
|
| 268 | +### Configure Chrome DevTools MCP for option 3 |
| 269 | +
|
| 270 | +```json title="file ~/.claude.json" |
| 271 | +"chrome-devtools": { |
| 272 | + "type": "stdio", |
| 273 | + "command": "npx", |
| 274 | + "args": [ |
| 275 | + "chrome-devtools-mcp@latest", |
| 276 | + "--executablePath", |
| 277 | + "{chrome path from above, or use find ~/chrome -name chrome -type f to find the path}", |
| 278 | + "--no-sandbox", |
| 279 | + "--disable-setuid-sandbox" |
| 280 | + ], |
| 281 | + "env": {} |
| 282 | +} |
| 283 | +``` |
| 284 | +
|
| 285 | +### Test MCP Connection for option 3 |
| 286 | +
|
| 287 | +Don't need to start Chrome separately, MCP will launch it. |
0 commit comments