---
title: "Observability Dashboard"
description: "Browser automation CLI for AI agents"
canonical_url: "https://agent-browser.dev/dashboard"
---

# Observability Dashboard

Monitor agent-browser sessions in real time with a local web dashboard showing a live browser viewport and command activity feed.

## Usage

The dashboard is bundled into the binary and requires no separate install. Start the server and open any session:

```bash
agent-browser dashboard start
agent-browser open example.com
```

Then open `http://localhost:4848` in your browser to see the live dashboard. If you expose the dashboard through a reverse proxy or port forward, explicitly allow its browser HTTPS origin when starting the server:

```bash
agent-browser dashboard start --allowed-origins https://dashboard.example.com
```

All sessions automatically stream to the dashboard. Local loopback origins are allowed automatically over IPv4 and IPv6 without an access token. For a reverse-proxied dashboard, use a comma-separated list of exact origins with `--allowed-origins` or `AGENT_BROWSER_DASHBOARD_ALLOWED_ORIGINS`; this lets the dashboard reject cross-origin requests and DNS-rebinding attacks. Every configured origin must be valid, and custom ports must be integers from 1 to 65535. Unknown options, missing values, invalid ports, and malformed origins fail without starting the server. The command prints private tokenized access URLs only for external origins. Open the matching URL once to establish the browser session and do not share it. Its unguessable token stays in the initial URL fragment, then the browser stores it in a Secure, host-bound, same-site cookie for dashboard API and stream requests. Open `http://localhost:<port>` directly for local access; the external token is never written to a loopback cookie. Configure the reverse proxy to redact cookies from logs. The browser stays on the dashboard origin while the server proxies per-session tabs, status, and stream traffic internally, so session ports do not need to be exposed. Repeated starts reuse the dashboard only when these settings match; stop it before changing the port or allowed origins.

### Custom stream port

By default each session binds its WebSocket stream server to an OS-assigned port. To use a specific port, set the `AGENT_BROWSER_STREAM_PORT` environment variable:

```bash
AGENT_BROWSER_STREAM_PORT=9223 agent-browser open example.com
```

You can also use the runtime commands to control streaming on a running session:

```bash
agent-browser stream enable --port 9223
agent-browser stream status
agent-browser stream disable
```

## Dashboard features

The dashboard is a single-page web app with three areas:

<table>
  <thead>
    <tr>
      <th>Area</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Live viewport</strong></td>
      <td>Real-time JPEG frames from the browser, rendered to a canvas element</td>
    </tr>
    <tr>
      <td><strong>Activity feed</strong></td>
      <td>Chronological stream of commands, results, and console messages with expandable details</td>
    </tr>
    <tr>
      <td><strong>Session creation</strong></td>
      <td>Create new sessions from the dashboard with local engines (Chrome, Lightpanda) or cloud providers (AgentCore, Browserbase, Browserless, Browser Use, Kernel)</td>
    </tr>
    <tr>
      <td><strong>Status bar</strong></td>
      <td>Connection status, viewport dimensions, and WebSocket endpoint</td>
    </tr>
  </tbody>
</table>

## WebSocket protocol

The dashboard connects to the same WebSocket endpoint used by [Streaming](/streaming), with additional message types for observability:

### Command events

Sent when a command begins executing:

```json
{
  "type": "command",
  "action": "click",
  "id": "r123",
  "params": { "selector": "@e5" },
  "timestamp": 1711367000000
}
```

### Result events

Sent when a command finishes:

```json
{
  "type": "result",
  "id": "r123",
  "action": "click",
  "success": true,
  "data": {},
  "duration_ms": 45,
  "timestamp": 1711367000045
}
```

### Console events

Sent when the browser logs to the console:

```json
{
  "type": "console",
  "level": "log",
  "text": "Page loaded",
  "args": [{"type": "string", "value": "Page loaded"}],
  "timestamp": 1711367000100
}
```

The `args` array contains the raw CDP `Runtime.consoleAPICalled` arguments for programmatic access. Object arguments include preview data (e.g. `{userId: "abc", count: 42}` instead of `"Object"`).

These are in addition to the existing `frame`, `status`, and `error` message types documented on the [Streaming](/streaming) page.

## Architecture

The dashboard is a Next.js static export (`output: 'export'`) that produces plain HTML, CSS, and JS. It lives at `packages/dashboard/` in the monorepo and is built with:

```bash
pnpm build:dashboard
```

The dashboard is embedded into the CLI binary at compile time using `rust-embed`. Plain HTTP requests serve the embedded dashboard assets and same-origin API routes. Session-specific tabs, status, and stream WebSocket traffic are proxied through the dashboard server to loopback-only session ports.

## AI Chat

The dashboard includes an optional AI chat panel powered by the [Vercel AI Gateway](https://vercel.com/docs/ai-gateway). When enabled, a **Chat** tab appears in the right pane alongside Activity, Console, Network, Storage, and Extensions.

### Setup

The Chat tab is always visible. Set the API key to enable responses:

```bash
export AI_GATEWAY_API_KEY=gw_your_key_here
agent-browser dashboard start
```

Optionally override the gateway URL or model:

```bash
export AI_GATEWAY_URL=https://ai-gateway.vercel.sh   # this is the default
export AI_GATEWAY_MODEL=openai/gpt-4o-mini           # default: anthropic/claude-sonnet-4.6
```

### How it works

The Rust server proxies chat requests from the dashboard to the Vercel AI Gateway and streams responses back using the Vercel AI SDK's UI Message Stream protocol. The dashboard frontend uses `useChat` from `@ai-sdk/react` with `DefaultChatTransport`.

Chat runs one agent-browser command per tool call. A `;` or `&&` inside a quoted argument is kept as text, so JSON parameters can contain them. Chat can load bundled skills with `skills get <name>` and use page WebMCP tools: it fetches a tool's input schema with `webmcp list <tool> --frame <frame-id> --json`, then calls `webmcp invoke` with the same `--frame`.

<table>
  <thead>
    <tr><th>Variable</th><th>Description</th><th>Default</th></tr>
  </thead>
  <tbody>
    <tr><td><code>AI_GATEWAY_URL</code></td><td>Vercel AI Gateway base URL.</td><td><code>https://ai-gateway.vercel.sh</code></td></tr>
    <tr><td><code>AI_GATEWAY_API_KEY</code></td><td>API key for the AI Gateway. Required to enable AI chat responses.</td><td>(none)</td></tr>
    <tr><td><code>AI_GATEWAY_MODEL</code></td><td>Default AI model for chat requests.</td><td><code>anthropic/claude-sonnet-4.6</code></td></tr>
  </tbody>
</table>
