agent-browser: Browser Automation for AI Agents

Last update: 2026-09-11 11:02:01 +0800 +0800
Available translations: 日本語 / 中文(简体) / 中文(繁體)

agent-browser is an Apache-2.0 browser-automation CLI designed for AI agents. Instead of requiring an agent to generate a complete Playwright program, it exposes navigation, interaction, inspection, state, network, and observability operations as shell commands. A persistent native daemon retains the browser between those commands.

The project combines three ideas:

  1. A compact accessibility snapshot gives the model a structured view of the page without sending the complete DOM.
  2. Snapshot references identify elements in subsequent commands.
  3. A long-lived daemon separates browser lifetime from the lifetime of each CLI process.

Version 0.37.1 is current as of September 11, 2026. The project changes quickly, so version-sensitive behavior in this article links to the 0.37.1 source revision.

Why Browser Automation Needs an Agent-Oriented Interface #

Playwright and similar libraries expose precise browser APIs, but an LLM-driven process pays additional costs when it uses them directly:

  • Generated source code consumes context and needs a runtime.
  • A raw DOM contains scripts, styles, hidden nodes, and framework-generated structure that rarely contributes to the next action.
  • CSS selectors generated from one observation can become invalid after a render.
  • Separate scripts require explicit browser and context lifecycle management.

agent-browser changes the interface rather than the browser. An agent observes a compact tree, chooses an operation, executes one command, and observes again:

flowchart LR
    Goal[User Goal] --> Model[Agent]
    Model -->|open or snapshot| CLI[agent-browser CLI]
    CLI --> Daemon[Native Daemon]
    Daemon -->|CDP or WebDriver| Browser[Browser]
    Browser --> Daemon
    Daemon -->|Snapshot and Refs| Model
    Model -->|click @e2| CLI

The model still decides what to do, while the CLI provides a stable action vocabulary and manages browser state. According to the project overview, a typical text snapshot uses approximately 200–400 tokens, compared with 3,000–5,000 for a full DOM. Those numbers are project estimates rather than an independent benchmark, but the underlying reason is clear: the accessibility tree omits much of the implementation detail that an agent does not need.

Architecture #

Each invocation starts a small CLI client. The client parses arguments and communicates with a native Rust daemon, while the daemon owns or attaches to a browser and sends commands over the Chrome DevTools Protocol (CDP).

flowchart TB
    subgraph Commands[Short-Lived Processes]
        C1[open]
        C2[snapshot]
        C3[click]
    end

    Socket[Local IPC]
    Daemon[Persistent Rust Daemon]
    CDP[Chrome DevTools Protocol]
    Chrome[Chrome or Chromium]

    C1 --> Socket
    C2 --> Socket
    C3 --> Socket
    Socket --> Daemon
    Daemon --> CDP
    CDP --> Chrome

Persistence matters because a login, open tab, cookie jar, and in-memory application state survive between shell commands. The daemon starts automatically. By default, it saves configured restore state, closes a locally owned headless browser, and exits after one hour without commands or dashboard input. Headed browsers, Safari and iOS WebDriver sessions, and browsers attached through CDP are exempt from that default shutdown behavior. The timeout is configurable through --idle-timeout or AGENT_BROWSER_IDLE_TIMEOUT_MS.

Current releases use a native Rust implementation; the earlier Node.js and Playwright daemon has been removed. Chrome and Chromium are the primary targets because the native path speaks CDP directly. The project also provides:

  • a CDP-compatible Lightpanda engine, with no headed mode, extensions, or persistent profiles;
  • Safari in an iOS Simulator through Appium and XCUITest; and
  • cloud-browser providers for Browser Use, Browserbase, Browserless, Kernel, and AWS Bedrock AgentCore.

Different back ends do not have identical capabilities. For example, annotated screenshots operate on the CDP path but not on the Safari WebDriver path.

Installing and Running agent-browser #

The npm package installs a platform-specific native binary:

sh
npm install -g agent-browser
agent-browser install

agent-browser install finds a compatible existing browser or downloads Chrome for Testing. Linux hosts can request browser system dependencies as well:

sh
agent-browser install --with-deps

Other supported installation paths include npx, a project-local npm dependency, Homebrew on macOS, and Cargo. The installed daemon does not require Playwright. The npm distribution declares Node.js 24 as a requirement because its launcher selects the native binary, while the Homebrew-installed binary does not need a Node.js daemon. pnpm 11 and Rust are required when building the repository. The installation guide also documents agent-browser doctor, which checks browser discovery, configuration, daemon files, provider connectivity, and a scratch headless launch.

A minimal interaction sequence is:

sh
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser click @e2
agent-browser screenshot page.png
agent-browser close

The CLI includes more than 50 commands. Relevant groups include navigation, forms, keyboard and pointer input, tabs, frames, files, cookies, storage, network routing, HAR capture, screenshots, PDF generation, video recording, profiling, and diffing. agent-browser read <url> can fetch agent-readable content without starting Chrome, while agent-browser mcp exposes the command surface through an MCP stdio server.

Snapshots and Element References #

snapshot is the central abstraction. It serializes the accessibility tree and assigns references to elements:

text
@e1 [heading] "Documentation" [level=1]
@e2 [input type="search"] placeholder="Search"
@e3 [button] "Submit"

The agent can act without inventing a CSS selector:

sh
agent-browser fill @e2 "session persistence"
agent-browser click @e3

Several filters reduce context use:

OptionEffect
-i, --interactiveInclude interactive elements only
-c, --compactRemove empty structural elements
-d, --depthLimit tree depth
-s, --selectorRestrict the tree to a CSS selector
-u, --urlsInclude link destinations

References belong to the page state that produced them. Navigation and meaningful DOM changes invalidate them, so a reliable agent re-snapshots after each state transition:

sh
agent-browser click @e3
agent-browser wait --load networkidle
agent-browser snapshot -i

Waiting for networkidle is not correct for every application because analytics, streaming, and polling can keep network activity alive. Prefer an observable application condition when one exists:

sh
agent-browser wait "#account-dashboard"
agent-browser wait --url "**/account"

The snapshot documentation also describes one-level iframe expansion. Child references retain frame context, so a command can interact with an element in an accessible iframe without a separate frame switch. Cross-origin frames that prevent accessibility-tree access are omitted.

Accessibility does not encode every visual fact. Canvas content, unlabeled icons, overlapping elements, and layout defects require pixels. An annotated screenshot overlays labels such as [2] that correspond to @e2:

sh
agent-browser screenshot --annotate page.png

Snapshots should therefore drive semantic interaction, while screenshots provide visual evidence when semantics are insufficient.

Sessions, Profiles, and State #

Named sessions isolate browser instances:

sh
agent-browser --session buyer open https://shop.example
agent-browser --session admin open https://admin.example
agent-browser session list

Each locally managed session has separate cookies, storage, history, and authentication state. Sessions attached to the same existing Chrome through CDP are an exception because they share that Chrome instance and bind to different tabs. --pin-tab prevents a session from silently moving to another tab when its bound tab closes.

Three persistence mechanisms solve different problems:

MechanismPurpose
Named sessionIsolate concurrent browser instances
--profileImport a browser profile or use a persistent profile directory
--state or --restoreSave and reload cookies and web storage

A session name alone does not persist data across daemon shutdown. Combining --session <name> with --restore enables automatic state loading and periodic saving under ~/.agent-browser/sessions/.

State files contain authentication material and must not enter source control. Restore state can be encrypted with AES-256-GCM by setting a 64-character hexadecimal AGENT_BROWSER_ENCRYPTION_KEY. The sessions guide documents profile-copy behavior, autosave timing, expiration, and encryption.

Configuration and Deployment Back Ends #

Configuration is resolved from lowest to highest precedence:

  1. ~/.agent-browser/config.json;
  2. ./agent-browser.json;
  3. AGENT_BROWSER_* environment variables; and
  4. command-line flags.

The project publishes an official JSON Schema, so project configuration can be validated by an editor or CI job.

Local execution can launch a headless or headed Chrome. --executable-path selects a specific Chromium-family binary. --cdp instead attaches to a local port or a ws:// or wss:// endpoint:

sh
agent-browser --cdp 9222 snapshot
agent-browser --cdp "wss://browser.example/cdp?token=..." snapshot

Provider mode moves browser infrastructure to a supported service while preserving the same CLI:

sh
BROWSERBASE_API_KEY=... \
  agent-browser --provider browserbase open https://example.com

Remote execution is useful in CI and serverless environments, but the trust boundary changes. Provider credentials, browser-session retention, regional egress, and provider-side startup behavior become deployment concerns. A CDP debugging endpoint also grants broad control over its browser, so it must not be exposed to untrusted networks.

Security Requires Explicit Configuration #

All agent-browser security features are opt-in. Default execution does not restrict navigation, actions, or output. Production deployments should therefore define controls as part of the agent harness:

json
{
  "$schema": "https://agent-browser.dev/schema.json",
  "contentBoundaries": true,
  "maxOutput": 50000,
  "allowedDomains": [
    "app.example.com",
    "*.app.example.com",
    "cdn.example.net"
  ],
  "actionPolicy": "./agent-browser-policy.json"
}

A restrictive action policy can allow observation and ordinary navigation while denying code execution and file transfer:

json
{
  "default": "deny",
  "allow": [
    "navigate",
    "snapshot",
    "click",
    "scroll",
    "wait",
    "get"
  ]
}

The controls address separate threats:

  • Content boundaries wrap page-derived output with a random nonce and origin metadata, helping an orchestrator distinguish untrusted page text from tool framing.
  • Domain allowlists block disallowed navigation and subresources and disable WebRTC in supported Chromium sessions.
  • Action policies allow or deny categories such as eval, upload, download, network, and state.
  • Confirmations place selected categories behind orchestrator or interactive approval.
  • Output limits constrain context flooding from page-derived data.
  • The authentication vault encrypts saved credentials and keeps passwords out of normal daemon IPC and agent-visible output.

Content boundaries are defense in depth rather than a proof that a model will ignore prompt injection. Domain filtering is not an operating-system firewall, and WebSocket or EventSource interception is best-effort. Strong isolation therefore combines agent-browser policy with container restrictions, filesystem permissions, network egress policy, and narrowly scoped credentials.

The domain allowlist intentionally rejects several combinations, including pre-existing CDP attachment, profiles, restored state, and Safari/iOS back ends, because those modes can execute existing content before the daemon establishes containment. Required CDN, font, API, and identity-provider domains must also appear in the allowlist or the site will fail to load.

Choosing Between agent-browser and Playwright #

agent-browser and Playwright operate at different abstraction levels:

RequirementBetter-Fitting Interface
An AI agent must inspect and manipulate arbitrary pages through shell toolsagent-browser
A test suite needs assertions, fixtures, retries, parallel workers, and reportsPlaywright
A workflow needs compact observations and element refsagent-browser
Code needs Firefox, WebKit, and Chromium coveragePlaywright
An application needs typed browser logic with source-controlled selectorsPlaywright
An agent needs persistent command-by-command browser stateagent-browser

Playwright is an end-to-end testing framework and browser-automation library; agent-browser is a command interface for an agent loop. Playwright remains the better fit for deterministic test programs because its fixtures, assertions, trace tooling, and multi-engine coverage belong in code. agent-browser fits open-ended agent work because it minimizes the translation from observation to action.

Browser Use is another distinct layer. agent-browser can use Browser Use as a hosted-browser provider through --provider browseruse, but that integration does not make both projects feature-equivalent. Choose the provider integration when the desired interface is agent-browser commands backed by a remote browser; use Browser Use directly when its SDK and agent APIs are the required application surface.

Operational Guidance #

A reliable deployment follows several rules:

  1. Pin the agent-browser version because command behavior and back-end support continue to evolve.
  2. Re-snapshot after navigation or DOM mutation because element references describe a specific page state.
  3. Wait for an application-visible condition instead of assuming a fixed delay or universal networkidle.
  4. Separate sessions by task and principal, then avoid attaching isolated tasks to the same Chrome instance.
  5. Treat screenshots, downloads, videos, HAR files, profiles, and saved state as potentially sensitive artifacts.
  6. Enable content boundaries, output limits, action policy, and domain restrictions explicitly.
  7. Enforce filesystem and network isolation below the browser process because CLI-level policy does not replace an operating-system sandbox.

agent-browser does not make browser agents deterministic. Pages still change, authentication expires, accessibility metadata can be incomplete, and model decisions remain probabilistic. Its contribution is a narrower and more stateful interface: the browser becomes a persistent tool with compact observations, explicit references, and enforceable action categories rather than a collection of scripts generated from scratch.

References #

Comments

Read or comment on GitHub (sign-in required to comment)