Docs · MCP server

Give your client an authenticated, audited browser.

The Twin Browser MCP server exposes the execution engine as native tools over stdio. Any MCP client — Cursor, Claude Desktop, Claude Code, Cline, or your own — can compile skills, run goals, replay them with no LLM, and search the shared skill library.

1 · Start the engine

Run the execution engine, then the server

The MCP server runs locally over stdio and forwards to your execution engine. Start the engine first; your MCP client launches the server for you via the config below.

Start the engine + smoke-test the serverbash
# 1. Start the execution engine (serves the browser pool on :7070).
EXEC_SHARED_SECRET=<your secret> npm run exec

# 2. The MCP server talks to it over stdio. Your MCP client launches it
#    for you via the config below — or run it directly to smoke-test:
EXEC_URL=http://localhost:7070 \
EXEC_SHARED_SECRET=<your secret> \
npm run exec:mcp
2 · Register the server

Three ways to wire it up

Point your MCP client at the server with the right environment. Pick the config for your client — the shape is the same.

Cursorjson
// .cursor/mcp.json  (project) or ~/.cursor/mcp.json (global)
{
  "mcpServers": {
    "twin-browser": {
      "command": "node",
      "args": ["src/exec/mcp-server.js"],
      "env": {
        "EXEC_URL": "http://localhost:7070",
        "EXEC_SHARED_SECRET": "<your exec shared secret>",
        "WEB_BASE_URL": "https://twin-browser.com",
        "TWIN_API_KEY": "ab_live_…"
      }
    }
  }
}
Claude Desktopjson
// claude_desktop_config.json → mcpServers
{
  "mcpServers": {
    "twin-browser": {
      "command": "node",
      "args": ["src/exec/mcp-server.js"],
      "env": {
        "EXEC_URL": "http://localhost:7070",
        "EXEC_SHARED_SECRET": "<your exec shared secret>",
        "WEB_BASE_URL": "https://twin-browser.com",
        "TWIN_API_KEY": "ab_live_…"
      }
    }
  }
}
Claude Code / Clinebash
# Claude Code CLI — register the server in one line. Cline uses the same shape.
claude mcp add twin-browser \
  --env EXEC_URL=http://localhost:7070 \
  --env EXEC_SHARED_SECRET=<your exec shared secret> \
  --env WEB_BASE_URL=https://twin-browser.com \
  --env TWIN_API_KEY=ab_live_… \
  -- node src/exec/mcp-server.js
Environment. EXEC_URL points at your running engine (default http://localhost:7070). EXEC_SHARED_SECRET authenticates the server to the engine. WEB_BASE_URL + TWIN_API_KEY are needed for the web-backed tools — search_library, dispatch, deep_search, etl/etl_query, the monitor tools, and the streamed-run branch of submit_verification — which reach the platform through the web API.
3 · Tools

Twenty-six tools, one authenticated engine

Lead with dispatch, run_goal, compile_skill and run_skill — the rest cover async jobs, observation, extraction, search, crawl, ETL, monitors, CAPTCHA, recording, and the shared library. Every target-bearing tool is authenticated with your key and acts on the target URL you provide.

run_goal

Execute 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_skill

Discover a goal once with the planner, then minimize it into a reusable, deterministic skill.

run_skill

Blind-replay a compiled skill with no LLM in the loop — the cheap, deterministic path.

list_skills

List the compiled skills available for replay.

search_library

Semantically search the cross-tenant shared skill library by intent and host (needs WEB_BASE_URL + TWIN_API_KEY).

dispatch

The 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).

submit_run

Submit 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_job

Poll an async job by id for status, success, steps and result.

cancel_job

Cancel a running async job by id (full credit refund).

observe_page

Serialize a page into token-efficient indexed DOM state without taking any action.

screenshot

Capture a single screenshot of an authorized URL as PNG or JPEG — full page or one CSS selector. No action, no LLM cost.

extract

Read an authorized page and return structured JSON matching the fields or JSON schema you request.

search

Web search returning ranked results; set fetchContent to also fetch and clean the top results.

deep_search

Async 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_site

Discover a site’s URLs fast from sitemap.xml + robots.txt + a shallow link scan. No page content.

submit_crawl

Crawl a whole site asynchronously (BFS), bounded by page/depth limits and path globs; returns a job id. Optional per-page structured extraction.

etl

Run the ETL pipeline: extract → transform → chunk → embed → load into the queryable content store (needs WEB_BASE_URL + TWIN_API_KEY).

etl_query

Semantic search over content ingested with etl; returns the top-k matching chunks (needs WEB_BASE_URL + TWIN_API_KEY).

create_monitor

Watch a page on a schedule and push an HMAC-signed webhook when the watched value changes (needs WEB_BASE_URL + TWIN_API_KEY).

list_monitors

List this tenant’s monitors.

delete_monitor

Delete a monitor by id.

get_monitor_history

Get a monitor’s recent check history — changed/unchanged/error plus value excerpts.

solve_captcha

Hand a live/paused session’s CAPTCHA to the solver and continue.

connect_account

Get 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_connections

Check whether the user finished a connect link you sent them (pending | active | connected | failed | expired) before re-running the task.

control_run

Drive 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_verification

Resume 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.

record_run

Run a goal and capture a video recording of the session.

record_job

Submit an async job that records its run to video.

4 · Use it

Then just ask in natural language

Example promptstext
# 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.
FAQ

MCP server questions

What is the Twin Browser MCP server?
A Model Context Protocol server that exposes Twin Browser as native tools to any MCP client (Cursor, Claude Desktop, Claude Code, Cline, and others). It communicates over stdio and forwards calls to the authenticated, audited execution engine, so an AI can compile skills, run goals, replay them deterministically, search the shared skill library, solve CAPTCHAs and record runs.
How do I connect Twin Browser to Cursor?
Add a "twin-browser" entry to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global) pointing at "node src/exec/mcp-server.js" with EXEC_URL and EXEC_SHARED_SECRET set, plus WEB_BASE_URL + TWIN_API_KEY to enable shared-library search. Claude Desktop uses claude_desktop_config.json; Claude Code and Cline use "claude mcp add".
Does the MCP server re-run the LLM on every call?
No. run_skill replays a compiled skill deterministically with no LLM, and compile_skill discovers a path once and minimizes it for reuse — so repeated tasks avoid the per-run model cost.
How is access controlled?
Every target-bearing tool is authenticated with your per-tenant API key and acts on exactly the target URL you provide. Each run is scoped to your tenant, metered in credits, and written to the audit log — nothing runs autonomously or that you did not initiate.

Compile once, then replay for almost nothing.