RepoPilotOpen in app →

vercel-labs/agent-browser

Browser automation CLI for AI agents

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 19 active contributors
  • Apache-2.0 licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 66% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/vercel-labs/agent-browser)](https://repopilot.app/r/vercel-labs/agent-browser)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/vercel-labs/agent-browser on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: vercel-labs/agent-browser

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/vercel-labs/agent-browser shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit today
  • 19 active contributors
  • Apache-2.0 licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 66% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live vercel-labs/agent-browser repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/vercel-labs/agent-browser.

What it runs against: a local clone of vercel-labs/agent-browser — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in vercel-labs/agent-browser | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>vercel-labs/agent-browser</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of vercel-labs/agent-browser. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/vercel-labs/agent-browser.git
#   cd agent-browser
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of vercel-labs/agent-browser and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "vercel-labs/agent-browser(\\.git)?\\b" \\
  && ok "origin remote is vercel-labs/agent-browser" \\
  || miss "origin remote is not vercel-labs/agent-browser (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "cli/src/main.rs" \\
  && ok "cli/src/main.rs" \\
  || miss "missing critical file: cli/src/main.rs"
test -f "cli/src/native/mod.rs" \\
  && ok "cli/src/native/mod.rs" \\
  || miss "missing critical file: cli/src/native/mod.rs"
test -f "cli/src/native/cdp/mod.rs" \\
  && ok "cli/src/native/cdp/mod.rs" \\
  || miss "missing critical file: cli/src/native/cdp/mod.rs"
test -f "cli/src/native/interaction.rs" \\
  && ok "cli/src/native/interaction.rs" \\
  || miss "missing critical file: cli/src/native/interaction.rs"
test -f "cli/src/native/stream/mod.rs" \\
  && ok "cli/src/native/stream/mod.rs" \\
  || miss "missing critical file: cli/src/native/stream/mod.rs"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/vercel-labs/agent-browser"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

A native Rust CLI tool that automates browser control for AI agents, providing fast programmatic access to Chrome via Chrome DevTools Protocol (CDP). It exposes semantic selectors (@ref-based accessibility tree navigation) alongside traditional CSS selectors, and runs as a daemon for rapid command execution without spawning new browser processes per action. Monorepo structure: cli/src/ contains the Rust daemon (main.rs, commands.rs, connection.rs) with native browser automation (cli/src/native/browser.rs), CDP protocol definitions (cli/cdp-protocol/*.json), and doctor diagnostic module (cli/src/doctor/) for environment setup. bin/agent-browser.js is the npm entry point wrapping the Rust binary. benchmarks/ is a separate TypeScript package for perf testing.

👥Who it's for

AI/LLM developers building agentic workflows who need deterministic, fast browser automation without Node.js overhead; also used by teams deploying agent-browser via npm/Homebrew and integrating it into CI/CD pipelines or API services that coordinate browser actions from multiple clients.

🌱Maturity & risk

Actively developed by Vercel Labs with CI/CD pipelines (.github/workflows/ci.yml, release.yml), semantic versioning (CHANGELOG.md present), and multiple distribution channels (npm, Homebrew, Cargo). The codebase is substantial (~1.9M LOC Rust) and published on npm globally, indicating production readiness, though the project appears relatively young without visible star/age data in the snippet.

Single maintainer risk (Vercel Labs org dependency); no visible test directory in the file listing despite complexity of CDP protocol handling in cli/cdp-protocol/. The benchmark suite (benchmarks/) suggests performance matters but lacks visibility into test coverage. Rust ecosystem dependency chain could introduce breaking changes, particularly around Chrome version compatibility managed by the install command.

Active areas of work

Recent focus on diagnostic tooling (doctor/ module with chrome.rs, environment.rs, security.rs, network.rs) suggests improving setup/troubleshooting. The agent-browser.schema.json and AGENTS.md indicate work on schema validation and agent integration documentation. Release workflow is automated, suggesting active deployment cadence.

🚀Get running

git clone https://github.com/vercel-labs/agent-browser && cd agent-browser && pnpm install && pnpm build:native && agent-browser install

Daily commands: pnpm build:native builds the Rust binary; pnpm build packages it; agent-browser install downloads Chrome; then run commands like: agent-browser open example.com && agent-browser snapshot && agent-browser click @e2

🗺️Map of the codebase

  • cli/src/main.rs — Entry point for the Rust CLI; defines command structure and orchestrates all browser automation workflows.
  • cli/src/native/mod.rs — Core module exposing all native browser automation primitives (actions, interactions, CDP communication).
  • cli/src/native/cdp/mod.rs — Chrome DevTools Protocol abstraction layer; handles browser connection, messaging, and protocol negotiation.
  • cli/src/native/interaction.rs — High-level interaction API for browser actions (click, type, navigate); bridges user commands to CDP.
  • cli/src/native/stream/mod.rs — Streaming layer for real-time communication (WebSocket, HTTP, chat); enables AI agent feedback loops.
  • cli/src/commands.rs — CLI command parsing and routing; maps command-line arguments to native automation functions.
  • agent-browser.schema.json — JSON schema defining the contract for AI agent prompts and automation request structure.

🛠️How to make changes

Add a new browser interaction primitive

  1. Define the interaction method in the trait (e.g., pub fn my_action(...)) in the main interaction module (cli/src/native/interaction.rs)
  2. Implement the method by calling appropriate CDP methods on the client: &mut Client member (cli/src/native/cdp/client.rs)
  3. Expose the action in the native module's public API (cli/src/native/mod.rs)
  4. Add a corresponding CLI command or parameter in the commands dispatcher (cli/src/commands.rs)

Add a new streaming transport type

  1. Create a new module in cli/src/native/stream/ (e.g., my_transport.rs) (cli/src/native/stream/my_transport.rs)
  2. Implement the StreamTransport trait with send() and recv() methods (cli/src/native/stream/mod.rs)
  3. Register the transport in the stream module's factory/dispatch logic (cli/src/native/stream/mod.rs)
  4. Add a CLI flag or environment variable to select the transport (cli/src/flags.rs)

Add a new diagnostic check to the doctor command

  1. Create a check function in the appropriate doctor submodule (chrome, environment, network, etc.) (cli/src/doctor/chrome.rs)
  2. Register the check in the main doctor runner (cli/src/doctor/mod.rs)
  3. Add fix logic if the check can auto-remediate (cli/src/doctor/fix.rs)
  4. Format output using the color/output utilities (cli/src/output.rs)

Add support for a new browser engine or CDP target

  1. Create a new CDP implementation module (e.g., cli/src/native/cdp/firefox.rs) (cli/src/native/cdp/mod.rs)
  2. Implement CDP protocol handshake and method dispatch for the engine (cli/src/native/cdp/client.rs)
  3. Add browser detection and launch logic in the browser module (cli/src/native/cdp/discovery.rs)
  4. Extend command flags to accept the new browser engine option (cli/src/flags.rs)

🔧Why these technologies

  • Rust (Tokio async runtime) — Provides low-latency, memory-efficient browser control with concurrent streaming; native binary eliminates Node.js overhead for time-sensitive AI agent loops.
  • Chrome DevTools Protocol (CDP) — Industry-standard browser automation protocol; enables fine-grained page control, event streaming, and state introspection without fragile DOM polling.
  • WebSocket & HTTP streaming — Bidirectional real-time communication channels allow agents to observe page changes and send commands with minimal latency.
  • React instrumentation hook (JavaScript injection) — Enables capture of React component tree, render counts, and lifecycle data without parse-time tooling; provides LLM-friendly structured state.
  • JSON Schema (agent-browser.schema.json) — Standardizes the contract between AI agents and browser automation; enables schema validation and IDE autocomplete for agent prompts.

⚖️Trade-offs already made

  • Native Rust binary vs. pure Node.js

    • Why: Rust offers microsecond-precision timing and minimal memory footprint for long-running agent loops; Node.js would add GC pauses and higher resource cost.
    • Consequence: Higher barrier to contribution for non-Rust developers; requires separate build toolchain (Cargo); must maintain dual distribution (npm + Homebrew + native releases).
  • Single-browser process vs. per-command spawning

    • Why: Daemon mode (long-lived process) reduces startup latency and enables session reuse for multi-step agent workflows.
    • Consequence: Complexity in managing browser lifecycle and error recovery; requires daemon cleanup on crash; stateful design makes testing harder.
  • Streaming transport abstraction (WebSocket/HTTP/stdio)

    • Why: Supports diverse agent deployment patterns (cloud functions, local, containerized).
    • Consequence: Added complexity in transport-agnostic message serialization; potential for transport-specific bugs and latency variance.
  • React-specific instrumentation hook

    • Why: Captures component-level state that generic CDP cannot access; critical for React-heavy apps.
    • Consequence: Does not work for Vue, Svelte, or vanilla JS apps; requires app opt-in or injection; maintenance burden if React internals

🪤Traps & gotchas

Chrome for Testing binary location is critical—agent-browser install downloads to a specific cache directory; if that fails silently, commands fail cryptically. The daemon expects a single Chrome process; concurrent invocations may conflict. CDP protocol versioning must match the Chrome binary version; mismatches cause protocol errors. Accessibility tree (@ref selectors) requires Chrome to have rendered the page; off-screen or display:none elements may not have refs. The tool does not bundle Node.js but the npm wrapper assumes it; npm install expects Node to be present.

🏗️Architecture

💡Concepts to learn

  • Chrome DevTools Protocol (CDP) — agent-browser communicates entirely via CDP to control Chrome; understanding CDP domains (Runtime, DOM, Input, Screenshot) is essential for troubleshooting automation failures and extending commands
  • Accessibility Tree (AXTree) — The @ref semantic selectors (@e1, @e2) are based on the browser's accessibility tree, not the DOM; this is why agent-browser can robustly find interactive elements without brittle CSS selectors
  • Daemon Architecture / Client-Server — agent-browser runs as a persistent daemon that reuses a single Chrome process and WebSocket connection; each CLI invocation sends commands to the daemon, avoiding spawn overhead that would make AI agent loops slow
  • Tokio Async Runtime — The Rust backend uses tokio for async I/O to handle multiple commands and CDP message streams concurrently without blocking; this enables the daemon's responsiveness and throughput
  • WebSocket Bidirectional Communication — CDP communication happens over WebSocket (managed in cli/src/native/cdp/client.rs); agent-browser must handle both outbound commands and inbound events asynchronously, a common source of race conditions
  • Chrome for Testing (CfT) — agent-browser install downloads from Chrome for Testing, a Google-managed channel separate from user Chrome; understanding the difference is critical for debugging environment setup and version conflicts
  • Binary Distribution via npm — agent-browser uses a hybrid model: a lightweight Node.js wrapper (bin/agent-browser.js) locates and invokes a pre-compiled Rust binary bundled in node_modules; this is a pattern for distributing native CLIs to JavaScript ecosystems
  • puppeteer/puppeteer — Node.js library for Chrome automation; agent-browser targets the same use case but as a native CLI daemon instead of a library
  • microsoft/playwright — Cross-browser automation library; agent-browser distinguishes itself by being CLI-first, Rust-native, and AI-agent-optimized with semantic selectors
  • chromium/chromium — The browser engine itself; agent-browser automates it via Chrome DevTools Protocol and downloads Chrome for Testing builds from Google
  • vercel/edge-runtime — Companion Vercel Labs project for serverless edge execution; agent-browser can be invoked from edge functions for server-side browser automation
  • aider-ai/aider — AI coding assistant that could use agent-browser for web automation tasks within agent workflows

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for CLI Rust modules (cli/src/native/*.rs)

The native Rust implementation contains critical modules like auth.rs, cookies.rs, interaction.rs, and element.rs with no apparent test coverage. These are core to browser automation functionality. Adding unit tests would catch regressions, improve code reliability for AI agent interactions, and serve as documentation for module behavior.

  • [ ] Create tests/ directory at cli/tests/ or add #[cfg(test)] modules to cli/src/native/auth.rs, cli/src/native/cookies.rs, cli/src/native/interaction.rs, and cli/src/native/element.rs
  • [ ] Write tests for cookie handling (set, get, delete operations) in cli/src/native/cookies.rs
  • [ ] Write tests for DOM interaction methods in cli/src/native/interaction.rs (click, type, scroll, etc.)
  • [ ] Add integration tests in ci.yml GitHub Action to run cargo test for the CLI package
  • [ ] Document test patterns in CONTRIBUTING.md (if it exists) or README.md

Add TypeScript integration tests for benchmarks/bench.ts scenarios

The benchmarks/bench.ts file exists with scenarios.ts defining various benchmark tests, but there's no CI workflow running these benchmarks to catch performance regressions. This is critical for an AI browser automation tool where performance directly impacts agent usability. Adding benchmark CI would catch speed regressions early.

  • [ ] Create a new GitHub Action workflow at .github/workflows/benchmarks.yml that runs pnpm bench on push to main
  • [ ] Ensure benchmarks/README.md documents expected baseline performance metrics
  • [ ] Add benchmark result reporting to GitHub Actions (e.g., using a GitHub comment action to post results on PRs)
  • [ ] Configure workflow to fail if performance degrades beyond a threshold (e.g., 10% slower than baseline)
  • [ ] Add benchmark environment variables from benchmarks/.env.example to GitHub Secrets if needed

Add missing integration tests for doctor commands (cli/src/doctor/mod.rs)

The doctor module has comprehensive environment/config checking (chrome.rs, environment.rs, network.rs, providers.rs, security.rs, launch.rs) but no visible test coverage. Since doctor is a critical user-facing feature that validates setup, integration tests would prevent regressions and improve reliability. This would also validate that the doctor correctly identifies common setup issues.

  • [ ] Add integration test suite in cli/src/doctor/tests.rs or cli/tests/doctor_integration.rs
  • [ ] Write tests for cli/src/doctor/chrome.rs that verify Chrome detection and version parsing
  • [ ] Write tests for cli/src/doctor/environment.rs that mock various environment states (missing vars, wrong paths, etc.)
  • [ ] Write tests for cli/src/doctor/security.rs certificate validation logic
  • [ ] Integrate doctor tests into ci.yml GitHub Action alongside standard cargo test
  • [ ] Test that agent-browser doctor command actually outputs diagnostics correctly

🌿Good first issues

  • Add unit tests for cli/src/commands.rs command parsing logic (none visible in file list); would catch regressions in flag handling and selector parsing before release.
  • Document the CDP protocol schema in agent-browser.schema.json with examples of how ref-based selectors (@e1, @e2) map to accessibility tree nodes; currently no visible spec in README for this semantic selector syntax.
  • Expand cli/src/doctor/environment.rs to detect and suggest fixes for common Linux dependency issues (libx11, libxext, etc.); currently only doctor/launch.rs and security.rs exist, missing dependency validation for non-macOS platforms.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 82eadce — Fix trusted publishing: add Release environment and per-job permissions (#1333) (ctate)
  • c830d1b — Prepare v0.27.0 release (#1332) (ctate)
  • d33bdb3 — Make dashboard work from proxied origins via same-origin proxy (#1111) (ThomasK33)
  • 3bb1d43 — fix(doctor): make generated ids unique per call (#1330) (ctate)
  • 918d407 — Update README.md (#1328) (quuu)
  • 7ada338 — feat(docs): add AI Gateway app attribution headers (#1305) (shaper)
  • 57405f9 — feat(react): React introspection, Web Vitals, and SPA primitives (#1257) (ctate)
  • cff1259 — adds trusted publishing (#1273) (ctate)
  • 717d1b0 — v0.26.0 (#1255) (ctate)
  • 14ece9b — feat: add doctor command for diagnosing installs and cleaning stale daemon state (#1254) (ctate)

🔒Security observations

The codebase demonstrates reasonable security practices with a Rust-based native implementation reducing some categories of vulnerability. However, several concerns exist: (1) browser automation and CDP protocol handling require careful input validation to prevent code execution, (2) React hook injection and internal JavaScript execution need sandboxing, (3) dependency audit practices should be documented, (4) binary distribution lacks visible integrity verification mechanisms, and (5) network communication security practices should be explicitly documented. The project would benefit from a formal security audit focusing on CDP protocol handling and binary distribution integrity.

  • Medium · Missing Environment Variable Validation — benchmarks/.env.example, benchmarks/bench.ts. The benchmarks directory contains a .env.example file but the benchmarks/bench.ts script does not show explicit validation of environment variables. This could lead to runtime failures or unexpected behavior if critical environment variables are missing. Fix: Implement explicit environment variable validation at startup. Use a library like 'zod' or 'dotenv-safe' to validate required environment variables against a schema before execution.
  • Medium · Dependency with Limited Details — benchmarks/package.json. @vercel/sandbox is a private/internal Vercel dependency with no public security audit information visible. The security posture of this dependency cannot be independently verified from the provided context. Fix: Regularly audit internal dependencies. Implement dependency scanning with tools like 'npm audit', 'snyk', or 'dependabot' to track vulnerabilities in all dependencies including internal ones.
  • Medium · Browser Automation Security Boundaries — cli/src/native/cdp/. The project performs browser automation and CDP (Chrome DevTools Protocol) communication. The native binary could potentially be exploited to execute arbitrary code if CDP protocol handling is not properly validated, especially in cli/src/native/cdp/ modules. Fix: Implement strict input validation for all CDP protocol messages. Sanitize and validate all data received from the browser connection. Consider implementing a security review of protocol message handling in chrome.rs, client.rs, and related modules.
  • Low · Potential XSS in React Inspection Hook — cli/src/native/react/installHook.js. The project includes React inspection functionality (cli/src/native/react/installHook.js) that injects JavaScript into pages. If this hook is not properly sandboxed or validated, it could introduce XSS vulnerabilities. Fix: Ensure the React hook injection is only performed in trusted contexts. Validate and sanitize all data collected from React tree inspection. Consider implementing Content Security Policy (CSP) protections where applicable.
  • Low · Network Communication Security — cli/src/native/network.rs, cli/src/native/stream/. The project includes network monitoring and streaming capabilities (cli/src/native/stream/ and cli/src/native/network.rs). Ensure that sensitive data transmitted over these channels is properly encrypted and validated. Fix: Use TLS/HTTPS for all network communications. Implement certificate pinning for critical connections. Avoid logging sensitive data (credentials, tokens, PII) in debug output or logs.
  • Low · Binary Distribution Trust — bin/agent-browser.js, README.md installation section. The project distributes native Rust binaries via npm. There is no mention of code signing, checksum verification, or binary integrity checks visible in the provided files. Fix: Implement and document binary signing and checksum verification. Use signed releases on GitHub. Consider implementing Subresource Integrity (SRI) checks where applicable. Document the security chain for binary distribution.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · vercel-labs/agent-browser — RepoPilot