| name | chrome-devtools-axi-browser-automation |
| description | Agent-ergonomic browser automation with token-efficient accessibility tree snapshots and combined operations |
| triggers | ["automate browser interactions","control Chrome headlessly","capture accessibility tree","take screenshot of webpage","fill form fields automatically","navigate and interact with pages","test web application behavior","run Lighthouse performance audit"] |
chrome-devtools-axi Browser Automation
Skill by ara.so — Devtools Skills collection.
Overview
chrome-devtools-axi is an AXI-compliant CLI wrapper around chrome-devtools-mcp that provides token-efficient browser automation. It uses TOON-encoded output to reduce token usage by ~40% compared to raw JSON, combines operations (navigate + snapshot + suggestions in one command), and includes contextual next-step hints in every response.
Key features:
- Accessibility tree snapshots with
uid= refs for precise element targeting
- Generation-based staleness detection prevents silent no-ops when page state changes
- Persistent bridge process keeps Chrome session alive across commands
- Combined operations reduce round-trips for agents
Installation
For agents to install automatically:
npx -y chrome-devtools-axi
For manual installation:
npm install -g chrome-devtools-axi
Tell your agent:
Execute `npx -y chrome-devtools-axi` to get browser automation tools.
Architecture
The CLI communicates with a persistent bridge server (localhost:9224 by default) that maintains an MCP session with Chrome via DevTools Protocol. The bridge auto-starts on first command and writes state to ~/.chrome-devtools-axi/.
Core Commands
Navigation and Snapshot
chrome-devtools-axi open https://example.com
chrome-devtools-axi snapshot
chrome-devtools-axi back
chrome-devtools-axi scroll down
chrome-devtools-axi scroll top
chrome-devtools-axi wait 2000
chrome-devtools-axi wait "Welcome"
Element Interaction
Elements in snapshots are marked with uid=g<generation>:<id> refs. Always use refs exactly as printed:
chrome-devtools-axi click @g1:1
chrome-devtools-axi fill @g2:5 "user@example.com"
chrome-devtools-axi fillform @g2:5=john @g2:6=doe @g2:7=john@example.com
chrome-devtools-axi type "search query"
chrome-devtools-axi press Enter
chrome-devtools-axi press Tab
chrome-devtools-axi hover @g1:3
chrome-devtools-axi drag @g1:4 @g1:8
chrome-devtools-axi upload @g1:2 /path/to/file.pdf
chrome-devtools-axi dialog accept
chrome-devtools-axi dialog dismiss
Screenshots
chrome-devtools-axi screenshot output.png
chrome-devtools-axi screenshot element.png --uid @g1:5
chrome-devtools-axi screenshot full.png --full-page
chrome-devtools-axi screenshot output.jpg --format jpeg
JavaScript Evaluation
chrome-devtools-axi eval "document.title"
chrome-devtools-axi eval "() => document.querySelectorAll('a').length"
chrome-devtools-axi eval "() => {
const rows = [...document.querySelectorAll('tr')];
return rows.map(row => row.textContent.trim());
}"
Multi-Step Scripts
cat << 'EOF' | chrome-devtools-axi run
open https://example.com
wait "Example Domain"
click @g1:1
snapshot
EOF
Page Management
chrome-devtools-axi pages
chrome-devtools-axi newpage https://google.com
chrome-devtools-axi newpage https://github.com --background
chrome-devtools-axi selectpage <id>
chrome-devtools-axi closepage <id>
chrome-devtools-axi resize 1920 1080
Device Emulation
chrome-devtools-axi emulate --viewport "390x844x3,mobile"
chrome-devtools-axi emulate --color-scheme dark
chrome-devtools-axi emulate --network "Slow 3G"
chrome-devtools-axi emulate --cpu 4
chrome-devtools-axi emulate --geolocation "37.7749x-122.4194"
chrome-devtools-axi emulate --user-agent "CustomBot/1.0"
chrome-devtools-axi emulate --viewport "390x844x3,mobile" --color-scheme dark --network "Fast 3G"
DevTools Debugging
Console Messages
chrome-devtools-axi console
chrome-devtools-axi console --type error
chrome-devtools-axi console --type warn
chrome-devtools-axi console --limit 10 --page 2
chrome-devtools-axi console-get <id>
Available types: log, debug, info, error, warn, dir, dirxml, table, trace, clear, assert, all
Network Requests
chrome-devtools-axi network
chrome-devtools-axi network --type xhr
chrome-devtools-axi network --type fetch
chrome-devtools-axi network-get <id>
chrome-devtools-axi network-get <id> --response-file response.json
chrome-devtools-axi network-get <id> --request-file request.json
Available types: document, stylesheet, image, media, font, script, xhr, fetch, websocket, manifest, other, all
Performance
Lighthouse Audits
chrome-devtools-axi lighthouse
chrome-devtools-axi lighthouse --device mobile
chrome-devtools-axi lighthouse --mode snapshot
chrome-devtools-axi lighthouse --output-dir ./reports
Performance Tracing
chrome-devtools-axi perf-start
chrome-devtools-axi perf-start --no-reload
chrome-devtools-axi perf-stop --file trace.json
chrome-devtools-axi perf-insight lcp "Largest Contentful Paint"
Heap Snapshots
chrome-devtools-axi heap memory.heapsnapshot
Configuration
Environment Variables
export CHROME_DEVTOOLS_AXI_PORT=9225
export CHROME_DEVTOOLS_AXI_BROWSER_URL=http://127.0.0.1:9222
export CHROME_DEVTOOLS_AXI_BROWSER_URL=wss://cluster.example/launch
export CHROME_DEVTOOLS_AXI_WS_HEADERS='{"Authorization":"Bearer token"}'
export CHROME_DEVTOOLS_AXI_DISABLE_HOOKS=1
State Files
State stored in ~/.chrome-devtools-axi/:
bridge.pid — Running bridge PID and port
snapshot-generation — Staleness detection counter
Common Patterns
Login Flow
chrome-devtools-axi open https://app.example.com/login
chrome-devtools-axi fillform @g1:1=user@example.com @g1:2=password
chrome-devtools-axi click @g1:3
chrome-devtools-axi wait "Dashboard"
chrome-devtools-axi snapshot
Form Scraping
chrome-devtools-axi eval "() => {
const form = document.querySelector('form');
const data = new FormData(form);
return Object.fromEntries(data.entries());
}"
Multi-Page Workflow
import { execSync } from 'child_process';
function runCommand(cmd: string): string {
return execSync(`chrome-devtools-axi ${cmd}`, { encoding: 'utf-8' });
}
runCommand('open https://example.com');
const title = runCommand('eval "document.title"');
runCommand('screenshot page.png');
runCommand('fill @g1:1 "search term"');
runCommand('press Enter');
runCommand('wait 2000');
const results = runCommand('eval "() => [...document.querySelectorAll(\'.result\')].map(el => el.textContent)"');
Handling Dynamic Content
chrome-devtools-axi open https://spa.example.com
chrome-devtools-axi wait "Loading complete"
chrome-devtools-axi snapshot
chrome-devtools-axi click @g2:5
Testing Responsive Design
chrome-devtools-axi emulate --viewport "390x844x3,mobile"
chrome-devtools-axi open https://example.com
chrome-devtools-axi screenshot mobile.png
chrome-devtools-axi resize 1920 1080
chrome-devtools-axi snapshot
chrome-devtools-axi screenshot desktop.png
Understanding Refs and Staleness
Refs use a generation prefix (g<N>:) that increments with each snapshot. If you capture a snapshot at generation 1, get ref @g1:5, then the page re-renders and moves to generation 2, attempting to use @g1:5 will fail with STALE_REF error.
Agent pattern:
- Capture snapshot
- Extract refs
- Attempt action with ref
- If
STALE_REF error, re-snapshot and retry with new ref
chrome-devtools-axi snapshot
chrome-devtools-axi click @g1:1
chrome-devtools-axi snapshot
chrome-devtools-axi click @g2:3
Troubleshooting
Bridge Not Starting
chrome-devtools-axi stop
chrome-devtools-axi start
Port Conflicts
export CHROME_DEVTOOLS_AXI_PORT=9999
chrome-devtools-axi open https://example.com
Stale Refs
Always use refs exactly as printed in snapshot output. If you get STALE_REF, capture a new snapshot.
Element Not Found
If uid is valid but element doesn't respond:
- Check if element is visible (scroll into view)
- Wait for page to finish loading
- Use
chrome-devtools-axi wait before interaction
Full Output Needed
chrome-devtools-axi snapshot --full
chrome-devtools-axi console --full
Debugging JavaScript Eval
chrome-devtools-axi console --type error
chrome-devtools-axi eval "2 + 2"
chrome-devtools-axi eval "() => { console.log('debug'); return 42; }"
Example: E2E Testing Workflow
#!/bin/bash
chrome-devtools-axi stop
chrome-devtools-axi start
chrome-devtools-axi open https://app.example.com
chrome-devtools-axi fillform @g1:1=$USER_EMAIL @g1:2=$USER_PASSWORD
chrome-devtools-axi click @g1:3
chrome-devtools-axi wait "Dashboard"
chrome-devtools-axi screenshot baseline.png
chrome-devtools-axi click @g2:10
chrome-devtools-axi wait "Feature Page"
chrome-devtools-axi fill @g3:5 "test data"
chrome-devtools-axi click @g3:6
chrome-devtools-axi wait "Success"
chrome-devtools-axi snapshot --full > result.txt
chrome-devtools-axi lighthouse --output-dir ./reports
chrome-devtools-axi stop
Best Practices for Agents
- Always re-snapshot after page changes — Don't reuse refs across navigation or mutations
- Use combined operations —
open gives snapshot automatically, reducing round-trips
- Check help hints — Every response includes suggested next steps
- Use
--full sparingly — Default truncation saves tokens; only expand when needed
- Prefer
fillform over multiple fill — Batch form operations when possible
- Wait strategically — Use
wait <text> instead of arbitrary timeouts when possible
- Leverage eval for extraction — JavaScript eval is more efficient than scraping via snapshots