About web-browser
web-browser is a skill with minimal CDP tools for agents to explore websites collaboratively. It provides Chrome control for navigation, JavaScript evaluation, screenshots, device emulation, and browser logs.
Key features
- 01Headless and visible Chrome launch
- 02Navigate tabs and pages
- 03Evaluate JavaScript in the active tab
- 04Capture viewport or full-page screenshots
- 05Emulate mobile devices
- 06Collect console, error, and network logs
Use cases
- 01Inspect page content and links
- 02Check a site in a mobile viewport
- 03Capture screenshots and review browser errors
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ mitsuhiko/ agent-stuff --skill web-browserAfter installing, type/web-browserin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
scripts/browser-processes.jsbrowser-processes.test.jscdp.jsdevices.jsdismiss-cookies.jsemulate.jsemulation-state.jseval.jslogs-tail.jsnav.jsnet-summary.jspackage-lock.jsonpackage.jsonpick.jsscreenshot.jsstart.jsstop.jswatch.jsDetails
From the project READMEWeb Browser Skill
Minimal CDP tools for collaborative site exploration.
Start Chrome (Prefer Headless)
./scripts/start.js --headless # Recommended: isolated reusable profile
./scripts/start.js --headless --profile # Headless with a copy of your profile
./scripts/start.js # Visible browser window when needed
./scripts/start.js --headless --reset-profile # Clear cached profile before launch
Starts Chrome with remote debugging (default port :9222). Agents should use --headless by default because it is less disruptive and supports navigation, evaluation, screenshots, emulation, and logging. User extensions are disabled for headless launches; a copied profile still provides its cookies and other browser state, but extension-based features are unavailable. Headed launches continue to load extensions normally. Use headed mode only when a person needs to see or interact with the browser, such as for pick.js, manual authentication, or debugging a headless-specific difference.
The start script only reuses a running browser when its profile and launch settings match. Stop the running skill browser before switching between headless and headed mode. Changing the debugging port does not isolate the profile: startup refuses to modify a profile already used on another port and preserves Chrome's profile locks.
Profile behavior:
- Default mode uses:
~/.cache/agent-web/browser/fresh-profile --profilemode uses:~/.cache/agent-web/browser/profile-copy- The skill does not attach to your live Chrome profile directly
- If
:9222is already used by an unknown instance, start will fail instead of reusing it
If Chrome is installed in a non-standard location, set:
BROWSER_BIN=/path/to/chrome ./scripts/start.js --headless
Optional debug endpoint override:
BROWSER_DEBUG_PORT=9333 ./scripts/start.js --headless
Stop Chrome
./scripts/stop.js # Stop skill Chrome on :9222
BROWSER_DEBUG_PORT=9333 ./scripts/stop.js # Stop skill Chrome on :9333
./scripts/stop.js --all # Stop all skill Chrome instances
Works for headless and headed browsers. Only processes using the skill's cached profiles are stopped, not your regular Chrome. Shutdown preserves cookies and other cached state; it never force-kills Chrome. Stop before using --reset-profile.
To switch to a visible browser:
./scripts/stop.js
./scripts/start.js
Navigate
./scripts/nav.js https://example.com
./scripts/nav.js https://example.com --new
Navigate current tab or open new tab.
Device Emulation (Mobile)
./scripts/emulate.js --list
./scripts/emulate.js iphone-14
./scripts/emulate.js pixel-7 --landscape
./scripts/emulate.js --reset
Set an active device emulation preference (viewport, DPR, touch, UA) for browser skill commands. Use --reset to clear.
Commands like nav.js, eval.js, pick.js, dismiss-cookies.js, and screenshot.js automatically apply the active preference.
Evaluate JavaScript
./scripts/eval.js 'document.title'
./scripts/eval.js 'document.querySelectorAll("a").length'
./scripts/eval.js 'document.querySelector("button")?.click(); "clicked"'
./scripts/eval.js 'await Promise.resolve(document.title)'
./scripts/eval.js 'JSON.stringify(Array.from(document.querySelectorAll("a")).map(a => ({ text: a.textContent.trim(), href: a.href })).filter(link => !link.href.startsWith("https://")))'
Execute JavaScript in the active tab. Input can be an expression or statement list; the console-style completion value is printed and promises/top-level await are awaited. Be careful with string escaping, best to use single quotes.
Screenshot
./scripts/screenshot.js
./scripts/screenshot.js --full-page
./scripts/screenshot.js --device iphone-14
./scripts/screenshot.js --device pixel-7 --full-page
Takes a screenshot and returns a temp file path.
- Default: current viewport
--full-page: captures full document height--device <preset>: temporary mobile emulation for that screenshot only
Pick Elements
./scripts/pick.js "Click the submit button"
Interactive element picker. Click to select, Cmd/Ctrl+Click for multi-select, Enter to finish. This requires headed Chrome; launch start.js without --headless.
Dismiss Cookie Dialogs
./scripts/dismiss-cookies.js # Accept cookies
./scripts/dismiss-cookies.js --reject # Reject cookies (where possible)
Automatically dismisses EU cookie consent dialogs.
Run after navigating to a page:
./scripts/nav.js https://example.com && ./scripts/dismiss-cookies.js
Quick Mobile Debug Flow
./scripts/start.js --headless
./scripts/nav.js https://example.com
./scripts/emulate.js iphone-14
./scripts/nav.js https://example.com # reload with mobile UA
./scripts/dismiss-cookies.js
./scripts/screenshot.js --full-page
Background Logging (Console + Errors + Network)
Automatically started by start.js and writes JSONL logs to:
~/.cache/agent-web/logs/YYYY-MM-DD/<targetId>.jsonl
Manually start:
./scripts/watch.js
Tail latest log:
./scripts/logs-tail.js # dump current log and exit
./scripts/logs-tail.js --follow # keep following
Summarize network responses:
./scripts/net-summary.js