Skip to main content
BAP sessions keep browser state alive across commands. When a client disconnects, the server parks the browser pages and contexts instead of destroying them. On reconnect with the same session ID, state is restored instantly.

How Sessions Work

bap -s=research goto https://example.com
    ↓ connects with sessionId: "research"
BAP Server creates browser + page
    ↓ client disconnects
Server parks session (browser, pages, contexts, element registries)
    ↓ 30 seconds later...
bap -s=research observe
    ↓ reconnects with sessionId: "research"
Server restores parked session → page is still on example.com

Named Sessions

Use the -s flag to create and reuse named sessions:
# Start a research session
bap -s=research goto https://arxiv.org --observe

# Start a shopping session (separate browser context)
bap -s=shopping goto https://store.example.com --observe

# Come back to the research session later
bap -s=research click text:"Next paper"

# List all active sessions
bap sessions
Without -s, the CLI auto-generates a session ID as cli-<port> (e.g., cli-9222). This means even without explicit naming, your session persists across commands on the same port.

Dormant Session Lifecycle

1

Park

When a client disconnects, the server parks the session. All state is preserved: browser instance, browser contexts, open pages, page-to-context mappings, element registries, frame contexts, and session approvals.The server also snapshots context.storageState() for crash recovery (best-effort, non-blocking).
2

TTL countdown

A dormant session has a configurable TTL (default: 300 seconds / 5 minutes). If no client reconnects within the TTL, the session expires and all resources are cleaned up.
3

Restore

When a client connects with a matching sessionId, the server checks if the parked browser is still alive. If so, all state is transferred to the new client connection. If the browser crashed during dormancy, the server starts fresh.
4

Expire

After TTL, dormant sessions are destroyed. Owned browsers are closed. CDP-attached (borrowed) browsers have their reference dropped without closing the external browser process.

What Gets Preserved

StatePreserved?Notes
Browser instanceYesStays running during dormancy
Open pages and URLsYesIncluding scroll position and form state
Browser contextsYesIncluding cookies and localStorage
Element registriesYesStable refs remain valid
Frame contextsYesiframe state preserved
Session approvalsYesPreviously approved actions stay approved
Storage state snapshotYesBest-effort crash recovery backup

Ghost Page Filtering

When a dormant session is restored, some pages may come back as about:blank if the browser discarded them during dormancy. BAP filters these out automatically — any page with url === "about:blank" is treated as non-existent, and ensureReady() creates a fresh page.
Without this filter, commands after session restore would silently operate on a blank page. BAP handles this transparently.

MCP vs CLI Sessions

BehaviorCLIMCP
Session persistenceYes (auto sessionId)No (destroy on disconnect)
Default session IDcli-<port>None
Named sessions-s=<name>Not supported
MCP clients get the current destroy-on-disconnect behavior. Session persistence is a CLI-specific feature designed for agents that make multiple sequential shell commands.

Configuration

The dormant session TTL is configured on the server:
OptionDefaultDescription
dormantSessionTtl300sTime before a parked session is destroyed
session.maxDuration3600sMaximum total session duration
session.idleTimeout600sIdle timeout before server-side disconnect

Practical Patterns

Multi-task agent

# Agent works on task A
bap -s=task-a goto https://site-a.com
bap -s=task-a observe
bap -s=task-a act click:text:"Download"

# Switch to task B without losing task A
bap -s=task-b goto https://site-b.com
bap -s=task-b extract --fields="title,status"

# Resume task A -- page is exactly where we left it
bap -s=task-a screenshot

Long-running workflow with breaks

# Start a multi-step workflow
bap -s=onboarding goto https://app.example.com/signup --observe
bap -s=onboarding act fill:label:"Email"="user@test.com" click:role:button:"Next"

# Agent pauses to process other tasks (session stays warm for 5 minutes)
# ...

# Resume where we left off
bap -s=onboarding observe
bap -s=onboarding act fill:label:"Company"="Acme Inc" click:role:button:"Continue"