A fast, zero-configuration CLI for controlling Chrome via the DevTools Protocol. Built for coding agents — no MCP server, no setup, just shell commands.
chrome-devtools-cli navigate https://example.com
chrome-devtools-cli snapshot
chrome-devtools-cli screenshot --file /tmp/shot.png
chrome-devtools-cli closeChrome launches automatically on first use. Every command outputs JSON.
Download the latest release and place it on your PATH:
mkdir -p ~/.local/bin
cp chrome-devtools-cli ~/.local/bin/chrome-devtools-cli
chmod +x ~/.local/bin/chrome-devtools-cli
# Add to PATH if not already there (add to ~/.zshrc or ~/.bashrc)
export PATH="$HOME/.local/bin:$PATH"Requires Rust.
git clone https://github.com/your-org/chrome-devtools-cli
cd chrome-devtools-cli
cargo build --release
cp target/release/chrome-devtools-cli ~/.local/bin/chrome-devtools-cli- Google Chrome (or Chromium) installed
- macOS or Linux
- No other dependencies — single static binary
Chrome is found automatically at standard install locations. Override with CHROME_PATH=/path/to/chrome.
chrome-devtools-cli [--headed] <COMMAND>
--headed opens a visible browser window. Default is headless (no window).
Chrome is auto-launched on first command and reused across subsequent calls. Run chrome-devtools-cli close to shut it down.
chrome-devtools-cli navigate <url>
# {"url": "https://example.com/", "title": "Example Domain"}
chrome-devtools-cli back
chrome-devtools-cli forward
chrome-devtools-cli reload# Accessibility tree — best for understanding page structure
chrome-devtools-cli snapshot
# Full-page screenshot saved to file
chrome-devtools-cli screenshot --file /tmp/page.png
# Viewport screenshot (current scroll position)
chrome-devtools-cli screenshot --file /tmp/view.png
# Element screenshot
chrome-devtools-cli screenshot --file /tmp/btn.png --selector "#submit"
# Full scrollable page
chrome-devtools-cli screenshot --file /tmp/full.png --full-page
# Screenshot as base64 JSON (no --file)
chrome-devtools-cli screenshotclick and fill have a built-in 5-second wait — they retry until the selector exists before acting.
# Click an element
chrome-devtools-cli click "#submit"
chrome-devtools-cli click "text=Sign in"
chrome-devtools-cli click "aria=Close dialog"
# Fill an input
chrome-devtools-cli fill "#email" "user@example.com"
chrome-devtools-cli fill "input[name=search]" "query"
# Hover over an element
chrome-devtools-cli hover ".dropdown-trigger"
# Press a key
chrome-devtools-cli press-key "Enter"
chrome-devtools-cli press-key "Tab"
chrome-devtools-cli press-key "Control+a"
chrome-devtools-cli press-key "Escape"CSS selectors are used by default. Two additional prefixes are supported:
| Prefix | Example | Matches |
|---|---|---|
| (none) | #submit |
CSS selector |
text= |
text=Sign in |
Element containing exact text |
aria= |
aria=Close dialog |
Element with matching aria-label |
chrome-devtools-cli eval "document.title"
# {"result": "Example Domain"}
chrome-devtools-cli eval "document.querySelectorAll('h2').length"
# {"result": 4}
chrome-devtools-cli eval "JSON.stringify([...document.querySelectorAll('a')].map(a => a.href))"# Wait for text to appear on the page (default 30s timeout)
chrome-devtools-cli wait-for "Welcome back"
# Custom timeout (milliseconds)
chrome-devtools-cli wait-for "Dashboard" --timeout 10000chrome-devtools-cli cookie list
chrome-devtools-cli cookie list --domain example.com
chrome-devtools-cli cookie set session_id abc123 --domain example.com
chrome-devtools-cli cookie set token xyz --domain example.com --path /api
chrome-devtools-cli cookie delete session_id# Mobile
chrome-devtools-cli viewport 375 812
# Desktop
chrome-devtools-cli viewport 1440 900
# With device scale factor
chrome-devtools-cli viewport 375 812 --scale 2# Accept an alert/confirm
chrome-devtools-cli dialog accept
# Enter text into a prompt dialog
chrome-devtools-cli dialog accept --text "my input"
# Dismiss a dialog
chrome-devtools-cli dialog dismisschrome-devtools-cli upload "input[type=file]" /path/to/file.pdf# Shut down Chrome
chrome-devtools-cli closeAll commands print JSON to stdout.
Success — exit code 0:
{"title": "Example Domain", "url": "https://example.com/"}Error — exit code 1:
{"error": "No element matching '#submit' found after 5000ms", "code": "ELEMENT_NOT_FOUND"}| Code | Meaning |
|---|---|
ELEMENT_NOT_FOUND |
Selector matched nothing after implicit wait |
ELEMENT_NOT_INTERACTABLE |
Element exists but is disabled or hidden |
MULTIPLE_ELEMENTS_FOUND |
Selector matched more than one element — use a more specific selector |
NAVIGATION_TIMEOUT |
Page took too long to load |
DIALOG_BLOCKING |
An unhandled dialog is blocking the page — run dialog accept or dialog dismiss |
EXECUTION_ERROR |
JavaScript eval threw an exception |
SESSION_DEAD |
Chrome is not running or the debug port is unreachable |
TIMEOUT |
Wait condition not met within timeout |
Add the following to your agent configuration file so the agent knows chrome-devtools-cli is available and how to use it.
Add to your project's CLAUDE.md or your global ~/.claude/CLAUDE.md:
## Browser Automation
`chrome-devtools-cli` is installed for all browser and web tasks. Use it instead of asking for MCP setup.
Chrome auto-launches headless on first command. Add `--headed` for a visible window.
- `chrome-devtools-cli navigate <url>` — go to a URL
- `chrome-devtools-cli snapshot` — read page content as text (use this before clicking)
- `chrome-devtools-cli screenshot --file /tmp/shot.png` — capture the page visually
- `chrome-devtools-cli click <selector>` — click an element (5s implicit wait)
- `chrome-devtools-cli fill <selector> <value>` — type into an input (5s implicit wait)
- `chrome-devtools-cli eval "<js>"` — run JavaScript, returns JSON
- `chrome-devtools-cli wait-for "<text>"` — wait for text to appear on the page
- `chrome-devtools-cli cookie list` — list cookies for the current page
- `chrome-devtools-cli viewport <width> <height>` — set viewport size
- `chrome-devtools-cli close` — shut down Chrome
Selectors: CSS by default. `text=Sign in` matches by text. `aria=Submit` matches by aria-label.
All commands output JSON. Exit 0 = success, exit 1 = error with `code` field.Add to your project's AGENTS.md:
## Browser Automation
`chrome-devtools-cli` is available as a shell command for controlling Chrome.
Chrome launches automatically — no setup required.
### When to use
Use `chrome-devtools-cli` whenever you need to: visit a URL, read a web page, take a screenshot,
fill forms, click buttons, run JavaScript in a browser, or inspect cookies.
### Common patterns
Navigate and read:
```bash
chrome-devtools-cli navigate https://example.com
chrome-devtools-cli snapshot # read page as text
chrome-devtools-cli screenshot --file /tmp/shot.pngForm interaction:
chrome-devtools-cli fill "#email" "user@example.com"
chrome-devtools-cli fill "#password" "secret"
chrome-devtools-cli click "button[type=submit]"
chrome-devtools-cli wait-for "Welcome"Extract data:
chrome-devtools-cli eval "JSON.stringify([...document.querySelectorAll('h2')].map(h => h.innerText))"Visible browser (for debugging):
chrome-devtools-cli navigate https://example.com --headedCleanup:
chrome-devtools-cli closeAll commands output JSON to stdout. Check exit code: 0 = success, 1 = error.
On error, stdout contains {"error": "...", "code": "ERROR_CODE"}.
---
## Example agent workflow
A complete login and data extraction flow:
```bash
chrome-devtools-cli navigate https://app.example.com/login
chrome-devtools-cli fill "#email" "user@example.com"
chrome-devtools-cli fill "#password" "hunter2"
chrome-devtools-cli click "button[type=submit]"
chrome-devtools-cli wait-for "Dashboard"
chrome-devtools-cli screenshot --file /tmp/dashboard.png
chrome-devtools-cli eval "document.querySelector('.user-name').innerText"
chrome-devtools-cli close
- Warm command latency: 11–44ms (Chrome already running)
- Cold start: ~2s (Chrome launch on first command)
- Binary size: 2.1MB
MIT