MCP server
twin-browser-mcp exposes the execution engine as 31 native tools over stdio to any MCP client — Cursor, Claude Desktop, Claude Code, Cline, or your own. One API key, nothing to install or clone: the client launches the server via npx. Every target-bearing tool is authenticated with your key, scoped to your tenant, metered, and audited.
1 · Get a key
The hosted server needs a single Twin Browser API key from Keys & Secrets.
# 1. Create an API key at https://twin-browser.com/dashboard/keys
# (starts with ab_live_…). That's the only thing the hosted server needs.
# 2. Optional — smoke-test the server yourself before wiring it into a client:
TWIN_API_KEY=ab_live_… npx -y twin-browser-mcp
# → "transport: customer (web API at https://twin-browser.com …)"2 · Register the server
Pick the config for your client — the shape is the same everywhere.
// .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)
// HOSTED setup — one variable, nothing to install. Every tool routes through the web API.
{
"mcpServers": {
"twin-browser": {
"command": "npx",
"args": ["-y", "twin-browser-mcp"],
"env": {
"TWIN_API_KEY": "ab_live_…"
}
}
}
}// claude_desktop_config.json → mcpServers
// HOSTED setup — one variable. WEB_BASE_URL defaults to https://twin-browser.com.
{
"mcpServers": {
"twin-browser": {
"command": "npx",
"args": ["-y", "twin-browser-mcp"],
"env": {
"TWIN_API_KEY": "ab_live_…"
}
}
}
}# Claude Code CLI — register the server in one line. Cline uses the same shape.
# HOSTED setup — one variable, nothing to install. (Operators running their own
# engine add EXEC_URL + EXEC_SHARED_SECRET instead.)
claude mcp add twin-browser \
--env TWIN_API_KEY=ab_live_… \
-- npx -y twin-browser-mcpEnvironment & modes
Hosted-only mode (recommended): set ONLY TWIN_API_KEY — WEB_BASE_URL defaults to https://twin-browser.com — and every tool routes through the hosted web API under your key. The startup log names the resolved mode: look for [twin-browser-mcp] transport: customer in your MCP client's logs; if it says operator, stale EXEC_URL/EXEC_SHARED_SECRET env is set.
Operator mode: running your own engine, set EXEC_URL (default http://localhost:7070) and EXEC_SHARED_SECRET instead of a key and the server talks to your fleet directly. The web-backed tools — search_library, dispatch, deep_search, etl/etl_query, the monitor tools, and the streamed-run branch of submit_verification — still need WEB_BASE_URL + TWIN_API_KEY.
3 · The tools
Lead with dispatch, run_goal, compile_skill and run_skill — the rest cover async jobs, observation, extraction, search, crawl, ETL, monitors, sessions, CAPTCHA, and recording.
Core — run, compile, replay, dispatch
run_goalExecute a goal on a target URL you provide — observe, plan, and act until a success condition is met. Optional proxy, video recording, and on-screen annotation. A sign-in run parks by default on a 2FA/approval wall it can’t auto-resolve, returning { status:"paused", sessionId } (resume with submit_verification); pass hitl:false to opt out.compile_skillDiscover a goal once with the planner, then minimize it into a reusable, deterministic skill.run_skillBlind-replay a compiled skill with no LLM in the loop — the cheap, deterministic path.dispatchThe cheap path: fuzzy-match a goal to an existing compiled skill via the semantic cache — a hit replays deterministically (~5× cheaper), a miss compiles and caches it for next time (needs WEB_BASE_URL + TWIN_API_KEY).list_skillsList the compiled skills available for replay.list_catalogThe runnable-skill catalog: each compiled skill plus its run contract — the params to pass, the secrets it fills, and your auth readiness on the host (mode + ready + missing). Plan a run before spending a credit.search_librarySemantically search the cross-tenant shared skill library by intent and host (needs WEB_BASE_URL + TWIN_API_KEY).
Async jobs
submit_runSubmit a goal as an async background job; returns a job id immediately. Like run_goal, a sign-in job parks by default on a 2FA/approval wall — get_job then reports status:"paused" with a sessionId.get_jobPoll an async job by id for status, success, steps and result.cancel_jobCancel a running async job by id (full credit refund).
Observation & data
observe_pageSerialize a page into token-efficient indexed DOM state without taking any action.screenshotCapture a single screenshot of an authorized URL as PNG or JPEG — full page or one CSS selector. No action, no LLM cost.extractRead an authorized page and return structured JSON matching the fields or JSON schema you request.searchWeb search returning ranked results; set fetchContent to also fetch and clean the top results.deep_searchAsync deep search — search, then scrape the top results (platform-aware) for cleaned content; returns a job id (needs WEB_BASE_URL + TWIN_API_KEY).map_siteDiscover a site’s URLs fast from sitemap.xml + robots.txt + a shallow link scan. No page content.submit_crawlCrawl a whole site asynchronously (BFS), bounded by page/depth limits and path globs; returns a job id. Optional per-page structured extraction.etlRun the ETL pipeline: extract → transform → chunk → embed → load into the queryable content store (needs WEB_BASE_URL + TWIN_API_KEY).etl_querySemantic search over content ingested with etl; returns the top-k matching chunks (needs WEB_BASE_URL + TWIN_API_KEY).
Monitors
create_monitorWatch a page on a schedule and push an HMAC-signed webhook when the watched value changes (needs WEB_BASE_URL + TWIN_API_KEY).list_monitorsList this tenant’s monitors.delete_monitorDelete a monitor by id.get_monitor_historyGet a monitor’s recent check history — changed/unchanged/error plus value excerpts.
Sessions, credentials & HITL
connect_accountGet a one-time link that lets a HUMAN sign into a site by hand, so Twin Browser captures the session and later runs are already logged in. Use it when a run returns code:"credential_missing", or when a site hard-challenges automated logins from datacenter IPs and simply cannot be signed into by an agent. Never ask the user to paste a password — send this link. Re-run the task afterwards and it restores the session (sessionRestored:true).list_connectionsCheck whether the user finished a connect link you sent them (pending | active | connected | failed | expired) before re-running the task.list_accountsList the stored logins you already have as { label, host, emailPreview } — masked, never a credential. Pass a returned label as account on run_goal/run_skill and that login plus its own saved session are applied automatically. Nothing back for a host? Use connect_account to have the user sign in once.control_runDrive a PAUSED run's browser directly — click, type, press a key, scroll, or navigate. Coordinates are 0..1 fractions of the viewport, read off a screenshot. The run continues by itself once the page no longer looks blocked; there is no "done" call. For a login a human must do, prefer connect_account; for a code, submit_verification.submit_verificationResume a run waiting on a 2FA/approval wall. Two paths: a PARKED run (from run_goal/submit_run) → pass its { sessionId, code } (resumes the engine session directly); a LIVE streamed run → pass its { token, code } (needs WEB_BASE_URL + TWIN_API_KEY). Codes: sms/email, TOTP, or phone approval; or cancel.solve_captchaHand a live/paused session’s CAPTCHA to the solver and continue.
Recording
record_runRun a goal and capture a video recording of the session.record_jobSubmit an async job that records its run to video.
Capture a session from your own browser
For sites whose sign-in is hard to automate remotely — popup-based “Continue with Google”, hardware-attested logins — sign in on your OWN browser (where OAuth just works) and hand the session to Twin Browser. Your password never leaves your browser; only the resulting session cookies are sent, encrypted at rest.
- Download the extension folder from the repo (
extension/) and openchrome://extensions. - Turn on Developer mode, click Load unpacked, select the folder.
- Sign into the site normally (e.g. linkedin.com → Continue with Google).
- Click the Twin Browser icon, paste your
ab_live_…key, add an optional account label, and Send this session.
From then on a run restores it (sessionRestored: true). Manage or forget connected sessions under Keys & secrets → Sessions. Works in any Chromium browser (Chrome, Edge, Brave, Arc). Under the hood it POSTs to /api/v1/sessions/import.
Enterprise / managed browsers: force-install by policy instead — a signed package with a stable ID and auto-update is hosted at /extension/twin-browser-extension.crx (update manifest /extension/updates.xml). No Chrome Web Store needed. See extension/SELF_HOSTING.md for the ExtensionInstallForcelist policy JSON.
Use it
# Once connected, ask your agent in natural language, e.g.:
# "Compile a skill that logs into app.acme.com and exports invoices,
# then replay it." → compile_skill → run_skill (no LLM on replay)
# "Search the library for 'export invoices as CSV' on app.acme.com"
# → search_library
# Every target-bearing call is authenticated with your key and acts on the
# url you pass — scoped to your tenant, metered, and written to the audit log.Replays run with no LLM: run_skill replays a compiled skill deterministically, and compile_skill discovers a path once and minimizes it for reuse — so repeated tasks avoid the per-run model cost entirely.