Use when testing web applications with Chrome DevTools MCP. Covers GUI Chrome setup and dev server configuration. Required reading before any browser automation.
Automates web app testing with Chrome DevTools Protocol. Use this when you need to start Chrome with remote debugging flags and a dev server before any browser automation.
/plugin marketplace add metasaver/claude-marketplace/plugin install core-claude-plugin@metasaver-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Automate testing of web applications using Chrome DevTools Protocol (CDP) with GUI Chrome browser.
/usr/bin/google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-debug-profile \
--no-first-run \
--no-default-browser-check \
"about:blank" &
sleep 3
curl -s http://127.0.0.1:9222/json/version
REQUIRED FLAGS:
--user-data-dir=/tmp/chrome-debug-profile - Remote debugging REQUIRES a non-default profile--remote-debugging-port=9222 - Standard CDP portRECOMMENDED: GUI mode (--headless=new has known issues). Always use GUI browser with flags specified.
pnpm exec vite --host 0.0.0.0
navigate_page(url: "http://localhost:PORT", type: "url")
take_snapshot()
# Kill existing Chrome sessions
pkill -f "chrome.*remote-debugging" || true
# Kill process on dev port if needed
fuser -k 3000/tcp || true
# 1. Start Chrome (GUI)
/usr/bin/google-chrome \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-debug-profile \
--no-first-run \
--no-default-browser-check \
"about:blank" &
sleep 3
curl -s http://127.0.0.1:9222/json/version
# 2. Start dev server
cd /path/to/app
pnpm exec vite --host 0.0.0.0 &
sleep 5
If chrome-devtools MCP shows "Not connected":
/mcp to reconnect| Symptom | Fix |
|---|---|
| "requires non-default data directory" | Add --user-data-dir=/tmp/chrome-debug-profile |
| "Not connected" from MCP | User runs /mcp to reconnect |
ERR_CONNECTION_REFUSED | Start dev server with --host 0.0.0.0 |
| Chrome won't start | pkill -f "chrome.*remote-debugging" |
EADDRINUSE on port 9222 | lsof -ti:9222 | xargs kill -9 then restart Chrome |
| Stale UIDs (elements not found) | Take fresh snapshot with take_snapshot() |
| MCP timeout errors | Verify Chrome responded to curl, user runs /mcp to restart |
| Display server issues (WSL/Linux headless) | Set DISPLAY=:0 or use native browser instead |
| Certificate warnings on localhost | Use http:// (not https://) for localhost testing |
| Tool | Purpose | Parameters |
|---|---|---|
list_pages | List open tabs with page IDs and URLs | (none) |
select_page | Switch active tab | page_id - from list_pages output |
new_page | Open new tab | (none) - defaults to about:blank |
navigate_page | Navigate to URL in active tab | url (required), timeout (optional, ms) |
close_page | Close tab/page | page_id - from list_pages output |
get_url | Get current page URL | (none) |
| Tool | Purpose | Notes |
|---|---|---|
take_snapshot | Get DOM tree with unique IDs (UIDs) | Returns page structure + element UIDs |
take_screenshot | Capture visual screenshot | Full page or viewport |
list_console_messages | Get JavaScript console logs | Includes errors, warnings, logs |
list_network_requests | Get network activity | Requests, responses, timing |
get_page_source | Get raw HTML source | Full document HTML |
| Tool | Purpose | Parameters |
|---|---|---|
click | Click element by UID | uid - from take_snapshot() output |
fill | Enter text in input | uid (target element), text (input value) |
hover | Hover over element | uid - from take_snapshot() output |
press_key | Send keyboard input | key - alphanumeric, or special (Return, Escape, Enter) |
wait | Wait for element/condition | timeout (ms), selector or uid |
What is a UID?
Every DOM element in a page snapshot receives a unique identifier (UID). UIDs are used to reference specific elements for interaction (click, fill, hover).
When UIDs become stale:
Best practice: Always run take_snapshot() before attempting interactions. This refreshes UIDs to match current page state.
Example workflow:
1. navigate_page(url: "http://localhost:3000")
2. take_snapshot() # Get fresh UIDs
3. click(uid: "button-123") # Use UID from snapshot
4. take_snapshot() # Refresh after action
5. fill(uid: "input-456", text: "search") # Use new UID
--user-data-dir flagcurl http://127.0.0.1:9222/json/version returns JSON--host 0.0.0.0--user-data-dir → Remote debugging REQUIRES --user-data-dir=/tmp/chrome-debug-profile to function properlytake_snapshot() after every navigation or DOM change to ensure element identifiers match current statelsof -ti:9222 | xargs kill -9 to clean up conflicting port 9222 instancesfuser -k 3000/tcp before starting new server to prevent port conflictssleep 3-5 after starting Chrome/server to ensure connection readiness/mcp to reconnect if tools fail silently--user-data-dir for reliable display and MCP connection--host 0.0.0.0 → Required for Docker/remote access to ensure dev server reachabilitySupported versions: Chrome 90+ (CDP Protocol v1.3+)
Check version:
/usr/bin/google-chrome --version
Known issues by version:
If version is too old:
# Option 1: Update Chrome
sudo apt-get update && sudo apt-get install google-chrome-stable
# Option 2: Use different installation
/snap/bin/chromium --version
/snap/bin/chromium --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug &
Symptoms:
curl http://127.0.0.1:9222/json/version returns valid JSONRoot Cause: In WSL2 environments, Chrome may technically start with debugging enabled but fail to establish proper GUI display or MCP connection. The CDP endpoint responds to curl but the MCP integration cannot connect.
What To Do:
Acknowledge the failure immediately:
Chrome DevTools automation failed. You can restart manually.
Instead:
Tell user to verify manually:
http://localhost:PORTIf MCP tools fail after Chrome appears to start:
Chrome DevTools automation failed.
HTTP verification shows servers are responding.
Please verify manually in your browser:
- http://localhost:3000 (main app)
- http://localhost:5173 (dev server)
Then continue with manual verification only.
This skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.