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:
- A compact accessibility snapshot gives the model a structured view of the page without sending the complete DOM.
- Snapshot references identify elements in subsequent commands.
- 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:
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).
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:
npm install -g agent-browser
agent-browser installagent-browser install finds a compatible existing browser or downloads
Chrome for Testing. Linux hosts can request browser system dependencies as
well:
agent-browser install --with-depsOther 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:
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser click @e2
agent-browser screenshot page.png
agent-browser closeThe 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:
@e1 [heading] "Documentation" [level=1]
@e2 [input type="search"] placeholder="Search"
@e3 [button] "Submit"The agent can act without inventing a CSS selector:
agent-browser fill @e2 "session persistence"
agent-browser click @e3Several filters reduce context use:
| Option | Effect |
|---|---|
-i, --interactive | Include interactive elements only |
-c, --compact | Remove empty structural elements |
-d, --depth | Limit tree depth |
-s, --selector | Restrict the tree to a CSS selector |
-u, --urls | Include 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:
agent-browser click @e3
agent-browser wait --load networkidle
agent-browser snapshot -iWaiting 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:
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:
agent-browser screenshot --annotate page.pngSnapshots should therefore drive semantic interaction, while screenshots provide visual evidence when semantics are insufficient.
Sessions, Profiles, and State #
Named sessions isolate browser instances:
agent-browser --session buyer open https://shop.example
agent-browser --session admin open https://admin.example
agent-browser session listEach 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:
| Mechanism | Purpose |
|---|---|
| Named session | Isolate concurrent browser instances |
--profile | Import a browser profile or use a persistent profile directory |
--state or --restore | Save 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:
~/.agent-browser/config.json;./agent-browser.json;AGENT_BROWSER_*environment variables; and- 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:
agent-browser --cdp 9222 snapshot
agent-browser --cdp "wss://browser.example/cdp?token=..." snapshotProvider mode moves browser infrastructure to a supported service while preserving the same CLI:
BROWSERBASE_API_KEY=... \
agent-browser --provider browserbase open https://example.comRemote 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:
{
"$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:
{
"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, andstate. - 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:
| Requirement | Better-Fitting Interface |
|---|---|
| An AI agent must inspect and manipulate arbitrary pages through shell tools | agent-browser |
| A test suite needs assertions, fixtures, retries, parallel workers, and reports | Playwright |
| A workflow needs compact observations and element refs | agent-browser |
| Code needs Firefox, WebKit, and Chromium coverage | Playwright |
| An application needs typed browser logic with source-controlled selectors | Playwright |
| An agent needs persistent command-by-command browser state | agent-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:
- Pin the agent-browser version because command behavior and back-end support continue to evolve.
- Re-snapshot after navigation or DOM mutation because element references describe a specific page state.
- Wait for an application-visible condition instead of assuming a fixed
delay or universal
networkidle. - Separate sessions by task and principal, then avoid attaching isolated tasks to the same Chrome instance.
- Treat screenshots, downloads, videos, HAR files, profiles, and saved state as potentially sensitive artifacts.
- Enable content boundaries, output limits, action policy, and domain restrictions explicitly.
- 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.
Comments
Read or comment on GitHub (sign-in required to comment)