← Blog

BLOG

Agent-Browser Install: Set Up the CLI and a Remote Runtime

Agent-browser install walkthrough: install the CLI, launch a hosted Chromium session, and connect Playwright over CDP without local browser binaries.

September 10, 20269 min readRemote Browser

# Agent-Browser Install: Set Up the CLI and a Remote Runtime

An agent-browser install is usually two separate jobs that people conflate: installing the CLI tool that an AI agent calls, and installing the browser that the CLI actually drives. The first is a package manager command. The second is where most setups break, because the browser has to live somewhere reachable, stay alive across agent turns, and expose a debugging protocol your code can attach to. This guide covers both paths, then shows the configuration that keeps them from drifting apart in production.

If you only need the CLI on your laptop for a quick test, the short version is npm install -g agent-browser and you are done. If you are running agents that need to survive restarts, hold login state, or run more than a handful of concurrent sessions, the browser half of the install matters more than the CLI half. That is the part worth getting right.

What "agent-browser" Refers To

The name is overloaded, so it helps to separate the layers before installing anything.

  • The CLI package. agent-browser on npm is a browser automation command-line tool aimed at AI agents. It wraps browser control behind a small set of commands an agent can invoke, and it is the thing you install with npm.
  • The browser it controls. The CLI does not ship a browser engine. It needs a Chromium instance to drive, either local or remote.
  • The runtime around that browser. Sessions, profiles, proxies, and lifecycle management. This is the layer that determines whether your agent works once or works every day.

Most installation guides stop at layer one. The failures show up at layer three.

Installing the CLI

The package is distributed through npm, so the install is standard:

npm install -g agent-browser
agent-browser --version

If you prefer not to install globally, use npx agent-browser and skip the global bin. For CI images, pin the version in your package.json or Dockerfile rather than tracking latest, since CLI argument surfaces change between minor releases.

A few practical notes from running this in containers:

  • Node version matters. Check the package's engines field before building a slim image. A mismatched Node version produces confusing runtime errors rather than a clean install failure.
  • Global installs need write access. In locked-down CI, install into the project instead and call the local binary.
  • The CLI is not the agent. It is a tool the agent calls. Your orchestration layer still owns retries, timeouts, and task decomposition.

Once the CLI resolves, the next question is what it connects to.

The Browser Half of the Install

If you point the CLI at a local browser, you inherit the full local browser problem: downloading engine binaries, matching driver versions, keeping the process alive between agent steps, and cleaning up orphaned processes when a run dies. Playwright's own install step is the canonical example:

npx playwright install chromium

That downloads a browser build into a cache directory. It works. It also means every machine that runs your agent needs that download, that disk space, and a compatible OS. Scale that to a fleet of workers and the install step becomes a build pipeline concern rather than a one-time setup.

The alternative is to install nothing locally and connect to a browser that already exists. Remote Browser runs hosted Chromium sessions and exposes them over CDP, so your local install is limited to the client library. You can read the connection model in the documentation before committing to either path.

Comparison: Local Browser Install vs Hosted Session

DimensionLocal installHosted Chromium session
Setup commandplaywright install per machineNone; connect to an existing endpoint
Version driftDriver and engine must match per hostManaged by the runtime
Session persistenceProcess-bound; dies with the workerSurvives worker restarts via profiles
ConcurrencyBounded by host CPU and memoryBounded by your plan; see pricing
DebuggingLocal headed mode or screenshotsLive viewer plus CDP
Proxy and network configPer-host environment setupConfigurable per session
CleanupYou reap orphaned processesRuntime handles session teardown
Best fitOne-off scripts, local devAgents, CI, multi-tenant workloads

The table is not an argument that local installs are wrong. For a single developer testing a script, local is faster. The trade-off flips the moment the browser needs to outlive the process that started it.

Connecting Playwright to a Hosted Browser

Playwright supports attaching to a remote Chromium instance over the Chrome DevTools Protocol. The relevant API is chromium.connectOverCDP, and it is the same call whether the browser is on your machine or in a data center. The Playwright CDP documentation is the authoritative reference for the method signature.

Here is a TypeScript example that connects to a hosted session, reuses the existing browser context, and drives a page:

import { chromium, type Browser, type BrowserContext } from "playwright";

const CDP_ENDPOINT = process.env.REMOTE_BROWSER_CDP_URL!;

async function runAgentTask(): Promise<void> {
  let browser: Browser | undefined;

  try {
    browser = await chromium.connectOverCDP(CDP_ENDPOINT, {
      timeout: 30_000,
    });

    // A hosted session usually arrives with a context already open.
    const contexts: BrowserContext[] = browser.contexts();
    const context = contexts.length > 0
      ? contexts[0]
      : await browser.newContext();

    const page = context.pages()[0] ?? (await context.newPage());

    await page.goto("https://example.com", {
      waitUntil: "domcontentloaded",
    });

    const title = await page.title();
    console.log(`Loaded: ${title}`);

    // Do not call browser.close() on a shared hosted session.
    // Disconnect instead so the session stays alive for the next step.
    await browser.close();
  } catch (error) {
    console.error("Agent task failed:", error);
    throw error;
  }
}

runAgentTask();

Two details in that snippet cause most production bugs.

Context reuse. When you connect over CDP, the browser may already have a context and a page. Creating a new context every run leaks state and can break sites that expect a consistent session. Check browser.contexts() first.

Close versus disconnect. browser.close() on a remote connection terminates the browser process. If your agent runs in multiple steps, that kills the session between steps. If you want the session to persist, disconnect the client without tearing down the browser. The exact semantics depend on your runtime, which is why the remote browser for AI agents post walks through the lifecycle in more detail.

Install-Time Configuration That Matters Later

The install is quick. The configuration decisions you make at install time are what you live with. Four of them are worth deciding deliberately.

Session lifetime

Decide up front whether a session is scoped to a single task or to a longer-lived agent. Task-scoped sessions are simpler and cheaper to reason about. Long-lived sessions need profile persistence and a plan for what happens when the browser crashes mid-task. If your agent logs into a site and then performs several actions over minutes, you want the session to outlive any single HTTP request.

Profile persistence

Persistent profiles let a session keep cookies, local storage, and login state across restarts. That is the difference between an agent that re-authenticates on every run and one that stays logged in. It also means you need a policy for profile isolation, because two agents sharing a profile will interfere with each other. Session isolation is the default expectation for multi-tenant workloads.

Network configuration

Proxy settings and other network-level browser options are configurable per session. If your workload depends on a specific egress region or a stable IP, set that at session creation rather than patching it later. Treat these as configuration, not as a guarantee about how any particular site will respond.

Debugging access

A live viewer is the difference between debugging an agent in minutes and debugging it by reading logs for an hour. Confirm before you build that you can watch a session in real time and attach CDP tooling when something goes wrong. The remote control browser post covers the debugging workflow.

Common Install Failures

These are the errors that show up repeatedly when teams move from a local script to a hosted runtime.

  • `connectOverCDP` times out. Usually a network path problem, not a Playwright problem. Verify the endpoint is reachable from the worker, including from inside containers and CI runners.
  • The browser disconnects mid-task. Often caused by calling browser.close() when you meant to disconnect, or by a session timeout shorter than the task.
  • Version mismatch errors. The client library and the remote browser need compatible protocol versions. Pin your Playwright version and check compatibility before upgrading.
  • Missing browser binaries. This only happens on the local path. If you see it after switching to a hosted session, you are still launching a local browser somewhere in your code.
  • State bleeding between runs. Two sessions sharing a profile, or a context that was never closed. Isolate profiles per agent or per task.

When to Install Locally and When Not To

A simple decision rule:

  • Install locally if you are prototyping, writing a one-off script, or need to inspect a page interactively on your own machine.
  • Use a hosted session if the browser needs to persist across process restarts, if you run more than a couple of concurrent agents, if you need consistent network configuration, or if you want to avoid maintaining browser binaries across a fleet.

The two are not exclusive. A common pattern is local development against a hosted session, so the code path in development matches production. That removes an entire class of "works on my machine" failures, because there is no local browser to differ from the remote one.

If you are still deciding between the two, the remote browser online guide covers what a hosted session actually gives you beyond the install convenience.

A Minimal Production Checklist

Before you call the install done, confirm each of these:

  1. The CLI or client library version is pinned, not floating.
  2. The CDP endpoint is injected via environment variable, not hardcoded.
  3. Your code checks for existing contexts before creating new ones.
  4. Session teardown is explicit and matches your intended lifetime.
  5. Profile isolation is defined per agent or per task.
  6. Network configuration is set at session creation.
  7. You have a way to watch a live session when a task fails.
  8. Timeouts are set on both the connection and the individual actions.

None of these are exotic. They are the difference between a demo and something you can leave running.

Summary

The agent-browser install itself is a single npm command. The part that determines whether your agent works in production is what that CLI connects to. Installing a local browser is fine for development, but it couples your agent's reliability to the machine it runs on. Connecting to a hosted Chromium session over CDP removes the binary management, keeps sessions alive across restarts, and gives you a live view when something breaks.

Start with the CLI, then decide where the browser lives. If you want to skip the local browser install entirely, the documentation covers session creation and CDP endpoints, and pricing has the current details on session limits and usage.