Skip to content

Docs

Steerpane documentation

Steerpane gives AI agents real Chromium browsers with saved logins, a live view, and a takeover button for humans. This page walks you from zero to a session you can take over, then covers the core concepts and APIs.

Quickstart

You'll need a Steerpane account and an API token. Create the token under Tokens in the dashboard — it starts with stp_live_ and inherits your role in the project.

1. Connect via MCP

Steerpane's MCP server lives at https://api.steerpane.app/mcp and speaks Streamable HTTP. Pick your client:

Terminal
claude mcp add --transport http steerpane https://api.steerpane.app/mcp \
  --header "Authorization: Bearer stp_live_YOUR_TOKEN"
Other clients — VS Code, Windsurf, n8n, OpenAI Agents SDK, LangChain — are covered on the MCP page in the dashboard with copy-ready configs.

2. Create a session

Ask your agent to "open a Steerpane session on linkedin.com", or call the API directly. Pass a profile_id to start already signed in.

curl
curl https://api.steerpane.app/v1/sessions \
  -H "Authorization: Bearer stp_live_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"profile_id":"prf_linkedin","initial_url":"https://linkedin.com"}'

The response includes the session id, a cdp_url for Playwright or Puppeteer, and a live_url you can open to watch.

3. Take over

When your agent hits a CAPTCHA or 2FA prompt it calls request_human_help. You'll see a "Needs help" badge and a notification. Click Take over in the live view — or call the endpoint below. The agent is put on hold: any commands it sends are queued, not dropped, and it receives a 409 human_in_control status if it asks.

Takeover & hand back
# Take control (agent goes on hold; its commands queue)
curl -X POST https://api.steerpane.app/v1/sessions/ses_8f2k1q/takeover \
  -H "Authorization: Bearer stp_live_YOUR_TOKEN"

# Hand back (queued commands replay in order)
curl -X POST https://api.steerpane.app/v1/sessions/ses_8f2k1q/handback \
  -H "Authorization: Bearer stp_live_YOUR_TOKEN"

4. Hand back

Finish the step and click Hand back. Queued commands replay in order and the agent continues from the page you left it on. Always end with stop_session so the recording is finalised and minutes stop counting.

Sessions

A session is one running Chromium instance. It moves through starting → running → stopped, and can be awaiting_help or under human_control along the way. Every session is recorded: events, console, network and a replay you can scrub.

Profiles

A profile is a saved browser state — cookies, local storage, extensions and fingerprint settings. Start a session from a profile to reuse logins; changes are written back when the session ends, unless you start it read-only.

Takeover

Takeover moves control from the agent to a person. Exactly one party controls a session at a time. While a human is in control the agent is on hold, its commands queue, and webhooks fire control.takeover and control.handback. Teams can require approval before an agent submits payments or forms on specific domains.

You're in control — agent on hold (3 queued)

API tokens

Tokens authenticate MCP, REST and CDP. They inherit the permissions of the user who created them, are scoped to a project, and can be given an expiry. Send them as Authorization: Bearer <token>. Revoke a token and every connection using it closes immediately.

MCP

Tools are ordered cheapest first. Agents should try fetch_page or web_search before starting a browser.

ToolWhat it does
fetch_pageFetch a URL as Markdown/HTML without starting a browser (cheapest — try first)
web_searchSearch the web and return title/url/snippet results
screenshot_url / pdf_urlScreenshot or print a URL in one call (no session) — saved to the file store with a file_id + download url
map_siteList a site's URLs (sitemaps + start-page links), filtered by keyword — find the right page before fetching
crawl_site → get_crawlCrawl a site in the background (same site, robots.txt respected) and page through the results
extract_urlStructured JSON from up to 10 URLs with an instruction (+ optional JSON schema), no session needed
create_sessionStart a remote Chromium session, optionally from a saved profile
list_profiles / verify_profile_loginsFind a profile and check it is still signed in to a site (loads the site with the profile's cookies) before relying on it
navigate / click / type / scrollGranular browser actions on the live page — selectors are also found inside iframes (or pass frame); use id=<exact id> for ids with dots
form_fields → type / select_option / upload_fileFill a form: form_fields lists every field (incl. iframes) with label, required, options and a ready selector; select_option handles native and custom dropdowns
url_historyEvery URL the session's tabs and iframes visited — find a one-time login link again instead of navigating away
get_page_text / extract / screenshotRead the page as text, structured data or an image
browser_executeRun a JS snippet in the live page and return its `result` (console logs only with include_logs: true)
create_upload_url → upload_file(file_id)Attach a local file (e.g. a resume): create_upload_url, run the returned curl in your own shell, then upload_file with file_id — the bytes never pass through the model
download / list_filesSaved downloads get a file_id you can pass straight to upload_file
captcha_snapshot → captcha_clickSolve a CAPTCHA yourself: a numbered image of the challenge, then click the matching tile numbers and verify
solve_captchaOn a CAPTCHA: Steerpane's CAPTCHA worker solves it with its own vision model; if it can't, a human takes over. Calls wait ~45 s each — repeat per next_step until solved / solved_by_human
request_human_helpPause and ask the human to take over (CAPTCHA you couldn't solve, 2FA, payment confirmation)
run_taskHand a whole goal to Steerpane's hosted browser agent and get a structured result
stop_sessionEnd the session (reason required). Sticky sessions: only when the user says they are done or asks you to close it. auto_close sessions: reason task_done once the task is done

REST API

Base URL https://api.steerpane.app/v1. Click an endpoint for the equivalent curl; the full reference with request and response schemas is in the dashboard.

GET/v1/sessions/{id}POST/v1/sessions/{id}/takeoverPOST/v1/sessions/{id}/handbackDELETE/v1/sessions/{id}GET/v1/profilesPOST/v1/fetch
Full API reference (sign-in required)

Webhooks

Subscribe an endpoint to events like session.started, control.help_requested, control.takeover and session.ended. Each delivery is signed with HMAC-SHA256 in the Conduit-Signature header; reject anything older than five minutes.

Verify signature · Node.js
import crypto from "node:crypto";

export function verify(rawBody, header, secret = "whsec_YOUR_SECRET") {
  const parts = header.split(",").map((p) => p.split("="));
  const t = parts.find(([k]) => k === "t")?.[1];
  const sigs = parts.filter(([k]) => k === "v1").map(([, v]) => v);
  if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; // 5 min tolerance
  const expected = Buffer.from(crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"));
  // During a secret rotation the header carries one v1= per secret — accept any match.
  return sigs.some((v1) => v1.length === expected.length && crypto.timingSafeEqual(expected, Buffer.from(v1)));
}

Self-hosting

Steerpane ships as Docker images: the API, the session scheduler, and Chromium nodes built on kernel-images (Apache-2.0). Run them with docker compose on one machine, or deploy the same compose file on Dokploy and scale nodes independently.

docker-compose.yml
# docker-compose.yml (excerpt)
services:
  conduit-api:
    image: ghcr.io/conduit/api:0.14
    env_file: .env
    ports: ["8080:8080"]
  conduit-scheduler:
    image: ghcr.io/conduit/scheduler:0.14
    env_file: .env
  chromium-node:
    image: ghcr.io/conduit/chromium-node:0.14   # built on kernel-images (Apache-2.0)
    deploy: { replicas: 4 }
    shm_size: 2gb
  1. Copy .env.example to .env and set your database URL, object storage for recordings, and a signing secret.
  2. Run docker compose up -d and open port 8080 to create the first admin.
  3. Add more Chromium nodes from Admin → Nodes; the scheduler balances sessions across them.
On Dokploy, create a Compose service from the same file, attach a domain to steerpane-api, and enable WebSocket support for live view.