core

Core agent-browser usage guide. Read this before running any agent-browser commands. Covers the snapshot-and-ref workflow, navigating pages, interacting with elements (click, fill, type, select), extracting text and data, taking screenshots, managing tabs, handling forms and auth, waiting for content, running multiple browser sessions in parallel, and troubleshooting common failures. Use when the user asks to interact with a website, fill a form, click something, extract data, take a screenshot, log into a site, test a web app, or automate any browser task.

Install
npx skills add 'https://github.com/vercel-labs/agent-browser/tree/main/skill-data/core'
Download bundle ↓
main · aff6125Scanned 2026-09-17

Contributors

GitHub-linked commit authors for this SKILL.md at the saved revision. Co-authors and history before file renames are not included.

File history ↗
View on GitHub
← Back to SKILL.md

Session Management

Multiple isolated browser sessions with state persistence and concurrent browsing.

Related: authentication.md for login patterns, SKILL.md for quick start.

Contents

Named Sessions

Use --session to isolate browser contexts. Agent skills should derive one stable id and reuse it on every command:

SESSION="$(agent-browser session id --scope worktree --prefix my-skill)"
agent-browser --session "$SESSION" --restore open https://app.example.com/login

--scope worktree uses the Git worktree root when available, then the Git root, then the canonical current directory. This is the recommended default for agents because worktrees are commonly used for parallel agent runs.

# Session 1: Authentication flow
agent-browser --session auth open https://app.example.com/login

# Session 2: Public browsing (separate cookies, storage)
agent-browser --session public open https://example.com

# Commands are isolated by session
agent-browser --session auth fill @e1 "user@example.com"
agent-browser --session public get text body

Session Isolation Properties

Each session has independent:

  • Cookies
  • LocalStorage / SessionStorage
  • IndexedDB
  • Cache
  • Browsing history
  • Open tabs

Tab Pinning in a Shared Browser

Full isolation applies when each session launches its own browser. When sessions instead share one Chrome over --cdp <port>, cookies and storage are shared, and only the tab selection separates the sessions. Add --pin-tab so each session sticks to its own tab:

agent-browser --session agent1 --cdp 9222 --pin-tab open https://site-a.com
agent-browser --session agent2 --cdp 9222 --pin-tab open https://site-b.com

Every session remembers which tab it is bound to (by CDP target id, persisted in the session's state directory), so a restarted daemon reattaches to the session's own tab instead of adopting the most recently active one. --pin-tab (env AGENT_BROWSER_PIN_TAB=1) additionally makes the binding strict:

  • Attaching with no binding opens a fresh tab instead of adopting an existing one
  • If the bound tab is closed, commands fail with a tab_gone error instead of silently acting on another tab. JSON output includes "code": "tab_gone", data.targetId, and optional data.lastUrl
  • Recovery commands still work in that state: run tab new <url> to bind a fresh tab, or tab list and switch to an existing one
  • Tabs opened by other sessions or the user never steal the pinned session's active tab

The flag is sticky per session: pass it once at session creation and later commands and daemon restarts keep the strict semantics. Pass --no-pin-tab to explicitly turn the pin off again. Use each tab's targetId from tab list --json when one session needs to reference another session's tab; target ids stay stable across daemon restarts.

The structured lastUrl is limited to sanitized HTTP(S) URLs and about:blank. Credentials, query strings, and fragments are removed from HTTP(S) URLs. Opaque URLs such as data: are omitted. In batch JSON, the recovery object appears under result instead of data.

When re-running a shared-tab script such as the repro from #1530, add --pin-tab to the first command for every session. Without it, open intentionally preserves the legacy behavior and navigates the shared active tab, so the original script still collides. The same rule applies when sessions attach with --auto-connect instead of --cdp.

Session State Persistence

Automatic Restore

# Bare --restore uses the current --session as the persistence key
SESSION="$(agent-browser session id --scope worktree --prefix next-dev-loop)"
agent-browser --session "$SESSION" --restore open https://app.example.com/dashboard

When --restore or another restore key is configured, state is loaded before navigation and saved on close, daemon shutdown, idle timeout, and compatible relaunch. It is also saved periodically while the browser is open (after commands settle, at most once per AGENT_BROWSER_AUTOSAVE_INTERVAL_MS, default 30000; set to 0 to save only on close), so a browser window the user closes by hand still leaves a recent save behind. A session ID by itself only isolates the daemon and does not enable persistence; without a restore key, shutdown discards transient browser state and open tabs. Idle sessions with configured persistence keep saving on the same interval, capturing changes the page makes on its own such as token refreshes. The daemon exits after one hour without commands or dashboard input by default; --idle-timeout <time> or AGENT_BROWSER_IDLE_TIMEOUT_MS tunes this, and 0 disables it. Headed, Safari/iOS WebDriver, and user-attached browsers are exempt from the default timeout; provider-owned cloud browsers are not. The default save policy is --restore-save auto, which skips auto-save if restore failed or validation failed; never disables periodic autosave too.

agent-browser --session "$SESSION" --restore --restore-check-url "**/dashboard" open https://app.example.com/dashboard
agent-browser --session "$SESSION" --restore --restore-check-text Dashboard open https://app.example.com/dashboard
agent-browser --session "$SESSION" --restore --restore-check-fn "!!localStorage.getItem('session')" open https://app.example.com/dashboard

Use agent-browser session info --json for diagnostics:

agent-browser --session "$SESSION" session info --json

Manual State Files

Use state save, state load, and --state <path> when you need an explicit portable JSON file. Do not make agents construct paths under ~/.agent-browser/sessions/; prefer --restore for reusable agent sessions.

Common Patterns

Authenticated Session Reuse

#!/bin/bash
SESSION="$(agent-browser session id --scope worktree --prefix app)"
agent-browser --session "$SESSION" --restore open https://app.example.com/dashboard

Concurrent Scraping

#!/bin/bash
# Scrape multiple sites concurrently

# Start all sessions
agent-browser --session site1 open https://site1.com &
agent-browser --session site2 open https://site2.com &
agent-browser --session site3 open https://site3.com &
wait

# Extract from each
agent-browser --session site1 get text body > site1.txt
agent-browser --session site2 get text body > site2.txt
agent-browser --session site3 get text body > site3.txt

# Cleanup
agent-browser --session site1 close
agent-browser --session site2 close
agent-browser --session site3 close

A/B Testing Sessions

# Test different user experiences
agent-browser --session variant-a open "https://app.com?variant=a"
agent-browser --session variant-b open "https://app.com?variant=b"

# Compare
agent-browser --session variant-a screenshot /tmp/variant-a.png
agent-browser --session variant-b screenshot /tmp/variant-b.png

Default Session

When --session is omitted, commands use the default session:

# These use the same default session
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser close  # Closes default session

Session Cleanup

# Close specific session
agent-browser --session auth close

# List active sessions
agent-browser session list

Best Practices

1. Name Sessions Semantically

# GOOD: Clear purpose
agent-browser --session github-auth open https://github.com
agent-browser --session docs-scrape open https://docs.example.com

# AVOID: Generic names
agent-browser --session s1 open https://github.com

2. Always Clean Up

# Close sessions when done
agent-browser --session auth close
agent-browser --session scrape close

3. Handle State Files Securely

# Don't commit state files (contain auth tokens!)
echo "*.auth-state.json" >> .gitignore

# Delete after use
rm /tmp/auth-state.json

4. Timeout Long Sessions

# Set timeout for automated scripts
timeout 60 agent-browser --session long-task get text body
Referenced from SKILL.md
SKILL.mdView in source ↗
Source excerpt starting at line 44.
The default (unnamed) session is a single shared browser: it is shared with every other agent on the machine and it persists across conversations, so working in it can hijack another agent's page mid-task or navigate away from something the human left open. Every example below assumes a named session is active. See [Run multiple browsers in parallel](#run-multiple-browsers-in-parallel) and `references/session-management.md`.
SKILL.mdView in source ↗
Source excerpt starting at line 362.
When several sessions share one Chrome over `--cdp <port>`, add `--pin-tab` so each session sticks to its own tab. Every session remembers its bound tab across daemon restarts; with `--pin-tab` a command whose bound tab was closed fails with a `tab_gone` error instead of acting on another session's tab. JSON output includes `"code": "tab_gone"`, `data.targetId`, and an optional sanitized `data.lastUrl` for recovery. Recover with `tab new <url>` or pick a tab from `tab list`. The flag is sticky per session, so pass it once (`--no-pin-tab` turns it off again). See `references/session-management.md` for details.
SKILL.mdView in source ↗
Source excerpt starting at line 481.
**Authentication expires mid-workflow** Use `--session <id> --restore` so your session survives browser restarts. Check `agent-browser session info --json` if restore fails. See [references/session-management.md](references/session-management.md) and [references/authentication.md](references/authentication.md).
SKILL.mdView in source ↗
Source excerpt starting at line 571.
- `references/trust-boundaries.md` — safety rules for driving a real browser- `references/session-management.md` — persistence, multi-session workflows- `references/profiling.md` — Chrome DevTools tracing and profiling