Browser sessions
for agents.
One API call starts an isolated cloud browser your agent drives over CDP and your users watch live. Easy to start, built to scale, gone when you're done.
import { BrowserView } from "@browserview/typescript"; const bv = new BrowserView(); // One call. A real browser, ready in ~5 seconds.const session = await bv.sessions.create({ startUrl: "https://example.com",}); session.cdp_url; // your agent drivessession.viewer_url; // your users watch- from request to ready browser
- ~5 seconds
- per session, destroyed on exit
- 1 container
- view, control, and CDP
- 3 token scopes
- between any two sessions
- 0 shared state
from request to ready browser
per session, destroyed on exit
view, control, and CDP
between any two sessions
One browser.
Two ways in.
Every session is a real Chromium instance in its own container. The API hands you two doors to the same browser: a DevTools endpoint for machines and a live viewer for people.
- 01
Create
POST /sessions with an API key. About five seconds later you have a running browser with signed URLs for everything below.
- 02
Drive
Point Playwright or Puppeteer at the session's CDP URL. No plugins, no custom protocol — it's Chrome DevTools all the way down.
- 03
Watch
Hand the viewer link to a person. Control tokens allow mouse and keyboard; view tokens strip input server-side, so spectators can't touch anything.
// Your agent connects with the tools// it already uses.import { chromium } from "playwright"; const browser = await chromium.connectOverCDP( session.cdp_url, { headers: { "x-session-token": session.cdp_token } },);const page = browser.contexts()[0].pages()[0];await page.goto("https://news.ycombinator.com"); // Meanwhile, anyone with the viewer_url// is watching it happen.Easy by default.
Scalable by design.
Agent browsing fails in the dark. BrowserView makes every session observable while it runs — not a screenshot afterwards.
Human in the loop, literally
The viewer isn't a replay — it's the same browser the agent is driving. Watch it work, or grab the mouse when it gets stuck.
CDP native
Playwright, Puppeteer, and anything else that speaks Chrome DevTools Protocol connects unchanged. Discovery URLs are rewritten for you.
Isolated by construction
One container and one private network per session, read-only filesystem, no shared state. Sessions can't see each other, ever.
Scoped, expiring tokens
Leaking a viewer link exposes one session for a bounded time — never your API key. View-only tokens are enforced server-side.
Cleans up after itself
Idle and lifetime reaping destroy forgotten sessions automatically. Crashed clients can't leak browsers or their bills.
Honest capacity signals
When the fleet is full you get a 429 with Retry-After — a real backpressure signal your queue can act on, not an OOM kill.
Meet your agent
where it already lives.
SDKs for TypeScript, Python, and Go. An MCP server for Claude, Cursor, and every other MCP-capable agent. Plain REST for everything else.
Three languages, one shape
from browserview import BrowserView bv = BrowserView()session = bv.create_session( start_url="https://example.com")print(session.viewer_url)Tools for any MCP agent
claude mcp add browserview \ -e BROWSERVIEW_API_KEY=bv_live_... \ -- npx -y @browserview/mcp # create_session, list_sessions,# get_session, destroy_session,# mint_session_token, get_session_replayAnthropic, OpenAI, and beyond
// Any framework that can hold a// Playwright/Puppeteer browser can// hold a BrowserView session.const browser = await chromium .connectOverCDP(session.cdp_url, { headers: { "x-session-token": session.cdp_token } });Give your agent a browser people can actually see.
Sign up, mint an API key, and create your first session with a single request.