← Blog

BLOG

Items Agent-Browser: CLI, Schema, and Runtime Items

Items agent-browser explained: what the CLI exposes, how the schema maps to runtime items, and how to run it against hosted Chromium.

October 11, 20269 min readRemote Browser

# Items Agent-Browser: CLI, Schema, and Runtime Items

The items agent-browser exposes are the discrete units of work the CLI and its schema hand to a browser: a navigation, a click, a text extraction, a screenshot, a wait condition. If you have run agent-browser from the command line, you have already met the concept of *items*. Understanding those items matters because they are the contract between your agent's plan and the browser that executes it. This guide covers what the items are, how the schema describes them, and how to run the same items against a hosted Chromium runtime instead of a local Chrome binary.

Remote Browser is a browser API and runtime for AI agents and browser-use workflows. It provides hosted Chromium sessions, CDP access, Playwright/Puppeteer/Selenium compatibility, a live viewer, persistent profiles, configurable browser settings, session isolation, and usage controls. The items model below is what you wire into that runtime.

What "items" means in agent-browser

The agent-browser CLI is a browser automation tool built for AI agents. Rather than exposing a full programming API, it accepts a sequence of commands — the items — and executes them against a browser session. Each item is a small, typed instruction. A typical run looks like a list of items: open a URL, snapshot the page, click a ref, type into a field, read a value, take a screenshot.

The reason this matters is that agent loops are naturally item-shaped. A language model produces a plan, the plan decomposes into steps, and each step maps to one browser action. If your runtime forces you to write imperative Playwright code for every step, you lose the ability to inspect, log, and replay the plan. If your runtime accepts items, you get a structured trace for free.

The items agent-browser defines fall into a few families:

  • Navigation items — open a URL, go back, reload, wait for a load state.
  • Observation items — snapshot the accessibility tree, read the DOM, get the current URL, list interactive elements.
  • Interaction items — click, type, select, hover, press a key, scroll.
  • Extraction items — read text, read an attribute, evaluate a small script, capture a screenshot.
  • Control items — set a timeout, switch tabs, close the session.

Each family has a schema entry. The schema is what makes the CLI usable from an agent: the model can be told "here are the valid items and their arguments," and it can emit a plan that the CLI validates before execution.

The agent-browser schema

The schema is the machine-readable description of every item the CLI accepts. It serves three purposes:

  1. Validation. Before an item runs, the CLI checks that the arguments match the schema. A malformed click item fails fast instead of producing a confusing browser error.
  2. Prompting. The schema can be embedded in an agent's system prompt so the model knows exactly which items exist and what arguments they take. This is far more reliable than asking a model to write free-form Playwright.
  3. Portability. Because items are declarative, the same item list can be executed by different backends — a local Chrome, a CI runner, or a hosted Chromium session.

A simplified schema entry for a click item looks like this:

{
  "name": "click",
  "description": "Click an element identified by a ref from the latest snapshot",
  "parameters": {
    "ref": { "type": "string", "required": true },
    "button": { "type": "string", "enum": ["left", "right", "middle"], "default": "left" },
    "timeout_ms": { "type": "integer", "default": 5000 }
  }
}

The ref argument is the important one. It points at an element from the most recent snapshot, not a CSS selector. This is deliberate: refs are stable within a snapshot, they survive minor DOM churn, and they are cheap for a model to reference. Selectors are brittle and verbose; refs are neither.

If you are building your own agent loop, treat the schema as the source of truth. Generate your tool definitions from it rather than hand-writing them, and you will avoid drift between what the model thinks it can do and what the CLI actually accepts.

Running items against a hosted runtime

The default agent-browser setup launches a local Chromium. That works for development, but it breaks down in production for familiar reasons: local Chrome is a single point of failure, it does not scale horizontally, and it cannot be shared across workers. The fix is to point the CLI at a remote browser over CDP.

Remote Browser exposes a CDP endpoint per session. You connect, and the same items execute against hosted Chromium. The connection is standard — see the Chrome DevTools Protocol documentation for the underlying protocol — so anything that speaks CDP works.

Here is a TypeScript example using Playwright's connectOverCDP to drive a hosted session. The items are the same; only the transport changes.

import { chromium } from "playwright";

type Item =
  | { type: "open"; url: string }
  | { type: "snapshot" }
  | { type: "click"; ref: string }
  | { type: "type"; ref: string; text: string }
  | { type: "read"; ref: string };

async function runItems(cdpUrl: string, items: Item[]) {
  const browser = await chromium.connectOverCDP(cdpUrl);
  const context = browser.contexts()[0] ?? (await browser.newContext());
  const page = context.pages()[0] ?? (await context.newPage());

  for (const item of items) {
    switch (item.type) {
      case "open":
        await page.goto(item.url, { waitUntil: "domcontentloaded" });
        break;
      case "snapshot":
        // In practice, use the agent-browser snapshot helper to get refs.
        await page.accessibility.snapshot();
        break;
      case "click":
        await page.locator(`[data-ref="${item.ref}"]`).click();
        break;
      case "type":
        await page.locator(`[data-ref="${item.ref}"]`).fill(item.text);
        break;
      case "read":
        return await page.locator(`[data-ref="${item.ref}"]`).innerText();
    }
  }

  await browser.close();
}

Two things to note. First, connectOverCDP returns a browser that already has a context and page — you do not launch anything. Second, closing the browser closes your client connection, not necessarily the hosted session; session lifetime is controlled by the runtime. That distinction matters when you want a session to persist across multiple item runs, which is where persistent profiles come in.

For a deeper walkthrough of the connection model, see Remote Browser for AI Agents.

Local items vs hosted items: what actually changes

The item list is identical. What changes is everything around it.

ConcernLocal ChromeHosted Chromium
Session startupLaunch a binary per runConnect to an existing session over CDP
ScalingAdd machines, manage Chrome versionsRequest sessions; runtime handles capacity
IsolationProcess-level, shared filesystemSession-level isolation per browser
ProfilesManual user-data-dir managementPersistent profiles managed by the runtime
DebuggingAttach a local devtools windowLive viewer plus CDP access
Network settingsConfigure per launch flagConfigurable browser settings per session
Failure recoveryRestart the processReconnect to the session or start a new one
Cost modelYour computeMetered browser time — see /pricing

The table is not an argument that hosted is always better. It is an argument that the *items* should be portable so you can move between the two without rewriting your agent. If your items are declarative and your transport is CDP, the migration is a connection string change.

Production criteria for item-based agents

Before you commit to an item-based design, check these against your workload.

Determinism of refs. Refs are only useful if they are stable within a snapshot. If your target site re-renders aggressively, snapshot more often and keep item lists short. Long item lists against volatile pages are where refs break down.

Timeout discipline. Every interaction item should carry a timeout. A click that waits forever is worse than a click that fails, because it stalls the whole agent loop. Set per-item timeouts and a session-level ceiling.

Observation cost. Snapshots are not free. A full accessibility tree on a large page can be expensive to serialize and to feed into a model. Prefer scoped snapshots — a subtree, or a filtered list of interactive elements — when the page is large.

Session reuse. If your agent runs many short item lists against the same site, reuse a session with a persistent profile rather than starting fresh each time. This preserves cookies, local storage, and any authenticated state, and it avoids repeated login flows.

Failure semantics. Decide what happens when an item fails. Retry the item, re-snapshot and re-plan, or abort the run. The CLI can validate items, but only your agent knows whether a failed click is recoverable.

Observability. Log every item with its arguments, result, and duration. When an agent misbehaves, the item log is the first place to look. A live viewer helps here too — you can watch the session as items execute rather than reconstructing it from logs.

Where the CLI stops and the runtime starts

The agent-browser CLI is good at what it does: it gives agents a small, typed vocabulary for driving a browser. It is not a runtime. It does not manage session pools, persistent profiles, outbound network configuration, or capacity. Those are runtime concerns, and they are the ones that decide whether your agent survives contact with production traffic.

The clean split is:

  • CLI and schema — define and validate items.
  • Agent loop — decide which items to run and in what order.
  • Runtime — provide the browser, the session, the profile, and the network.

Remote Browser occupies the third layer. You keep your items and your loop; you point them at a hosted session. If you want to see what that looks like end to end, start with Remote Browser Online for the setup path, or Remote Control Browser for the control-plane view. The documentation covers the CDP endpoint, session lifecycle, and profile management in detail.

Practical next steps

If you are evaluating this stack, do it in this order:

  1. Write down your item list for one real task. Not a demo — a task your agent actually needs to complete.
  2. Run it locally with agent-browser to confirm the items and the schema cover it.
  3. Connect the same items to a hosted Chromium session over CDP and compare failure modes.
  4. Add persistent profiles if the task involves authentication.
  5. Add logging and a live viewer before you add scale.

The items are the easy part. The runtime is where the work is, and it is worth getting the boundary right before you write a thousand lines of agent code around the wrong abstraction.