Browser Tools
VITA uses two browser tools with distinct roles. Route by task type β never use the deprecated CDP-shared-browser approach (the banned mcp__claude-in-chrome patterns).
Tool Routing (updated 2026-05-12)
| Task | Tool | Why |
|---|---|---|
| Local dev β localhost app servers, vita reports, in-app webview testing | agent-browser CLI |
Faster startup, easier sessions, single-shot snapshot/eval/screenshot |
| Web research / bot-evasion β x.com, news sites, anything that fingerprint-detects | camofox skill |
Camoufox in Docker, hardened fingerprint, noVNC handoff for auth |
Pick the right tool for the kind of target. Use proactively β when bio-zack mentions a link, when researching, when checking services. Don't ask, don't announce.
Note: Both tools share the same interaction model β drive the page by its accessibility tree, not pixels.
snapshotreturns the ARIA tree annotated with element refs; youclick/fill/pressagainst those refs. The one syntactic difference:agent-browserrefs carry an@prefix (@e5), camofox refs are bare (e5).
agent-browser (local dev)
agent-browser is a CLI wrapper around Chromium (installed on PATH) for local development tasks: checking running apps, taking screenshots of in-development UI, verifying behavior in the local stack.
Getting Started
# Full usage guide (preferred β always version-matched to the installed CLI)
agent-browser skills get core --full
# Quick help
agent-browser --help
Common Commands
# Open a URL
agent-browser --session dev open http://localhost:3000
# Snapshot (accessibility tree + @refs for interaction)
agent-browser --session dev snapshot
# Click, fill, press (refs use the @ prefix)
agent-browser --session dev click @e5
agent-browser --session dev fill @e3 "search query"
agent-browser --session dev press Enter
# Screenshot
agent-browser --session dev screenshot /tmp/shot.png
# Evaluate JavaScript
agent-browser --session dev eval "document.title"
Session Naming
Use descriptive --session names so concurrent agents don't clobber each other:
| Session | Purpose |
|---|---|
dev |
Local app server |
reports |
Vita reports UI |
webview |
In-app webview testing |
Bundled Skills
Beyond core, the CLI ships task-specific skill guides. Fetch any of them with agent-browser skills get <name> --full:
| Skill | Purpose |
|---|---|
core |
Core usage guide β read this first |
dogfood |
Systematically explore/test a web app to find bugs and UX issues |
electron |
Automate Electron desktop apps |
slack |
Drive Slack workspaces via the browser |
agentcore |
Run agent-browser on AWS Bedrock AgentCore cloud browsers |
vercel-sandbox |
Run agent-browser + Chrome inside Vercel Sandbox microVMs |
Run agent-browser skills list to see the current set.
camofox (web research / bot-evasion)
camofox runs Camoufox (a hardened Firefox build) in Docker with C++-level fingerprint spoofing, a virtual display, and noVNC for human handoff. It is standalone β no dependency on a running Chromium or window manager. Use it for anything that could fingerprint-detect: x.com, news sites, general web research, scraping.
- Binary:
~/.local/bin/camofox(thin shell entry point β.claude/skills/browser-camofox/cli.py) - Docker container: name
camofox, imagecamofox-browser; the CLI auto-starts it if it isn't running - HTTP API port: 9377
- noVNC (visual handoff) port: 6080
- Skill:
.claude/skills/browser-camofox/ - Cookie cache / state volume:
~/.local/share/camofox(mounted into the container at/data)
Basic Usage
-s <session> is required for every interactive subcommand β it scopes an isolated browser context (its own cookies) so concurrent agents don't clobber each other. Refs are bare (e1, e5), no @ prefix.
camofox -s research open https://example.com
camofox -s research snapshot # accessibility tree with [e1] refs
camofox -s research snapshot -i # interactive elements only
camofox -s research click e1 # click element by ref
camofox -s research fill e3 "search query"
camofox -s research press Enter
camofox -s research scroll down 500
camofox -s research resize 375 812 # resize viewport (e.g. mobile)
camofox -s research screenshot /tmp/shot.png
camofox -s research eval "document.title" # run JS in page context
camofox -s research links # extract all links
camofox -s research close # close session
Management subcommands do not take -s:
camofox handoff # print noVNC URL for human takeover
camofox sessions # list active sessions
camofox health # check server status
Tip:
evalruns arbitrary JavaScript in the page context β the escape hatch for anything the accessibility snapshot can't reach: iframes, shadow DOM, custom components, JSON-LD/meta extraction, computing element positions for coordinate clicks. Example:camofox -s s eval "document.querySelectorAll('iframe').length".
Sessions
- Each
-s <name>gets its own browser context with isolated cookies. - Sessions auto-expire after 30 minutes of inactivity.
- Multiple sessions can be open concurrently.
- Cookies persist within a session (log in once, browse with cookies) and survive container restarts via the
~/.local/share/camofoxvolume. resizerelaunches the browser at the new window size and clears all sessions.
Auth: Cookie Import (preferred)
When a site (x.com especially) shows a login wall, the fastest fix is importing cookies from a local browser β no manual login, and it survives container restarts. This is preferred over noVNC handoff.
# import fresh cookies from chromium, filtered to a domain
camofox import-cookies chromium --domain x.com
# load the cached cookies into a freshly-restarted container
camofox load-cookies --domain x.com
# import ALL cookies (no domain filter)
camofox import-cookies chromium
How it works: the CLI shells out to yt-dlp to extract Netscape-format cookies from the source browser's encrypted cookie DB, converts them to JSON, injects them into camofox via the authenticated /sessions/<user>/cookies API, and caches the merged set at ~/.local/share/camofox/cookies.json for reuse across restarts.
Supported source browsers: chromium, chrome, firefox, brave, edge, opera, safari. Requires yt-dlp (uv tool install yt-dlp).
Auth: noVNC Handoff (fallback)
When cookie import won't work (fresh CAPTCHA, 2FA, or the session isn't in a local browser):
- Navigate:
camofox -s research open https://site.com - Run
camofox handoffβ it prints the noVNC URL:http://localhost:6080/vnc.html?autoconnect=true - The human opens that URL, logs in / solves the CAPTCHA in the live browser.
- Continue automation in the same session β cookies are preserved.
Health & Container
docker ps | grep camofox # is the container up?
curl -s http://localhost:9377/health # API health (cli auto-starts on miss)
docker start camofox # manual start
docker stop camofox # stop
X/Twitter Automation
VITA includes specialized X/Twitter automation (scripts/browser/x.py) that drives camofox via accessibility snapshots and link extraction. It scrapes by collecting /status/ links across scroll passes, and posts by locating the compose textbox / action buttons by ARIA label.
# Scrape bookmarks (saves to data/x/bookmarks.json)
uv run python scripts/browser/x.py bookmarks
# Scrape home feed (saves to data/x/feed.json)
uv run python scripts/browser/x.py feed
# Search tweets
uv run python scripts/browser/x.py search "topic"
# Post, reply, quote
uv run python scripts/browser/x.py post "Hello world!"
uv run python scripts/browser/x.py reply <tweet-url> "Great point"
uv run python scripts/browser/x.py quote <tweet-url> "Adding context"
The X class also exposes like, retweet, and a "Following" feed view as Python methods. On a login wall, x.py auto-runs camofox import-cookies chromium -d x.com and retries once before raising and suggesting camofox handoff.
Data files:
| File | Purpose |
|---|---|
data/x/bookmarks.json |
Last scraped bookmarks (synced_at, count, tweets[]) |
data/x/feed.json |
Last scraped feed (same shape) |
Browser Session Logging
Browser actions are appended as structured JSONL so activity is observable in the web UI. The CLI records open/click/fill/close/navigate events; the API surfaces them grouped by session+date.
| Piece | Location |
|---|---|
| Log writer/reader | scripts/browser/log.py (log_action, read_log, get_sessions_summary) |
| Log file | data/browser/sessions.jsonl |
| API router | api/src/routers/browser_sessions.py |
API endpoints (served on the API at port 33800):
| Endpoint | Returns |
|---|---|
GET /api/v1/browser/sessions |
Session summaries grouped by session+date (first/last URL, action breakdown, duration, distinct URLs) |
GET /api/v1/browser/sessions/log |
Raw action log entries (filter by session, since; limit 1β2000) |
Each log entry records a UTC ts, the session name, the action, and (where relevant) url / url_before / url_after and an element {role, name} dict. Writes take an exclusive flock so concurrent agents don't interleave lines.
Integration with VITA
| System | Tool | Usage |
|---|---|---|
/sleep |
camofox | Browse X feed, discover trending topics |
/sync-x |
camofox | Scrape bookmarks and feed (routes x.com through the camofox skill; mcp__claude-in-chrome banned) |
/x-content-gen |
camofox | Research engagement targets |
/post-x |
camofox | Post approved drafts |
| Local dev verification | agent-browser | Check running apps, screenshot UI |
| General web research | camofox | On-demand lookups, news, articles |
File Locations
| Path | Purpose |
|---|---|
.claude/skills/browser-camofox/cli.py |
camofox CLI wrapper |
.claude/skills/browser-camofox/SKILL.md |
camofox command reference |
~/.local/bin/camofox |
camofox shell entry point |
~/.local/share/camofox/cookies.json |
Cached cookies (survives container restarts) |
scripts/browser/x.py |
X/Twitter automation (X class + CLI) |
scripts/browser/camofox.py |
Async CamofoxSession Python wrapper used by x.py |
scripts/browser/log.py |
Browser action log read/write |
api/src/routers/browser_sessions.py |
Browser session log API |
data/x/bookmarks.json, data/x/feed.json |
Scraped X data |
data/browser/sessions.jsonl |
Browser action log |
Where to go next
- Feed β how scraped X content flows into the discovery feed
- Research β multi-source research harness
- Architecture β the API that serves the session-log endpoints