MCP

Run a browser agent over MCP

Register the Twin Browser MCP server in Cursor, Claude Desktop, Claude Code or Cline and give the agent thirty-one browser tools over stdio — with one environment variable and nothing to install.

The Model Context Protocol is how editors and desktop agents discover and call external tools. Twin ships an MCP server, so any MCP client can hand its agent a real browser with no glue code. This guide covers the config that actually works, what the tools are, and the two things people get wrong on the first attempt.

How is the server actually run?

Over stdio, launched by your client — not as a hosted URL. The config gives a command (`npx`), its args (`-y twin-browser-mcp`) and one environment variable (`TWIN_API_KEY`). There is nothing to install ahead of time and no second endpoint to point at; WEB_BASE_URL is optional and defaults to the hosted API.

mcpServers config — Cursor, Claude Desktop, Clinejson
{
  "mcpServers": {
    "twin-browser": {
      "command": "npx",
      "args": ["-y", "twin-browser-mcp"],
      "env": {
        "TWIN_API_KEY": "ab_live_…"
      }
    }
  }
}

Registering it from the CLI

Claude Code takes the same server as a one-liner, and `claude mcp list` confirms it connected and reports how many tools it discovered.

Claude Codebash
claude mcp add twin-browser \
  --env TWIN_API_KEY=ab_live_… \
  -- npx -y twin-browser-mcp

claude mcp list
# → twin-browser: connected

What tools does the agent get?

Thirty-one, in six groups: core execution and skills (run_goal, compile_skill, run_skill, dispatch, list_skills, list_catalog, search_library), async jobs, observation and data (observe_page, screenshot, extract, search, deep_search, map_site, submit_crawl, etl, etl_query), monitors, sessions and credentials (connect_account, list_accounts, control_run, submit_verification, solve_captcha), and recording. The client lists them to the model automatically.

  • run_goal takes { target, goal } — `goal` is a registry identifier (login, search, extract, reply, like), not a sentence.
  • dispatch is the one that takes free text: { url, prompt, success }. It is also the cheap path.
  • list_catalog is what an agent should call BEFORE spending: it returns each skill's params, secrets and auth readiness.

The two mistakes people make first

One: sending a sentence to run_goal. Its `goal` argument resolves against a built-in registry of one-word goals, and a sentence is rejected with a 400 that names the valid ones — free text belongs in dispatch. Two: asking the user for a password. When a run comes back with code "connect_required" it already carries a ready connectUrl; hand that link over and the person signs in themselves.

How does cost stay flat in an editor workflow?

The same compile-once economics apply, and dispatch is what applies them. The first time you ask your agent to do a web task it compiles a skill; the next time, a match replays it for 2 credits with no planner call. An agent you use dozens of times a day does not bill you the planner every time.

What about authorization and secrets?

Every call carries your Bearer key and the target URL is the authorization signal, so auth, billing and audit run on each one. Logins come from the vault by reference — the editor and the model never see a credential — and the stealth tier additionally requires an explicit authorized: true attestation that the person on whose behalf you are acting has to actually make.

Keep going

The capabilities behind it

Vocabulary

Common questions

Is the MCP server a hosted URL?
No. It runs over stdio, launched by your client with `npx -y twin-browser-mcp` and a TWIN_API_KEY environment variable. There is no MCP endpoint to point a URL at.
Which client works?
Any standards-compliant MCP client. Cursor, Claude Desktop and Cline share the same mcpServers JSON shape; Claude Code takes the same server via `claude mcp add`.
Why did run_goal reject my instruction?
Because `goal` there is a registry identifier — login, search, extract, reply, like — and a goal containing whitespace is rejected at the edge. Send free-text instructions to dispatch as { url, prompt, success }.
What should the agent do when a site blocks the sign-in?
Never ask the user for their password. A blocked run returns code "connect_required" with a ready connectUrl; the agent hands that link over, the person signs in once, and re-running the task restores the captured session.

Delegate the work. Keep the decision.

Hand off a real task, set the guardrails, and let repeated work compile into a skill that replays deterministically at near-zero cost.