Core tool
Replay a compiled skill with no model in the loop
Blind deterministic replay of a stored path: the same actions, in the same order, against the same host — no planner, no tokens, one credit.
run_skill
What it is
The job: Run a known-good flow again, as cheaply as it can possibly be run.
Replay is the point of compiling. run_skill loads the stored path and executes it directly — no observation-plan-act loop, no model call, no token bill. What you pay for is browser time.
Credentials and sessions are resolved server-side: the skill records which secrets it fills, and the vault supplies them inside the browser at fill time. Nothing about the credential passes through your prompt or the response.
Replay is deliberately blind, which is its strength and its limit. It does not reason about the page, so it is fast and predictable; it also cannot improvise if the page has moved. Drift is detected and repaired at the platform level rather than replayed blindly into a wrong click.
The call
Call it exactly like this.
Copied from the tool's registration and the route handler — not paraphrased.
// MCP tool call — server "twin-browser"
{
"tool": "run_skill",
"arguments": {
"name": "acme-login",
"target": "https://app.example.com"
}
}curl -X POST https://twin-browser.com/api/v1/skills/acme-login/run \
-H "Authorization: Bearer $TWIN_API_KEY" \
-H "content-type: application/json" \
-d '{"target":"https://app.example.com","params":{"query":"invoices"},"account":"work"}'The MCP tool takes only { name, target }. The REST endpoint additionally accepts `params` (the values a parameterized skill binds) and `account` (which stored login to use). If your skill is parameterized, call it over REST — or use list_catalog first to see exactly which params it wants.
| Parameter | Type | What it does |
|---|---|---|
| name* | string | Name of a compiled skill in your tenant. list_skills and list_catalog both return valid names. |
| target* | string | Base URL to replay against. Normally the same host the skill was compiled on. |
Returns
{
"success": true,
"path": [ /* the replayed actions */ ],
"steps": 6,
"replayed": 6,
"runId": "…",
"credits_charged": 1
}What it costs
1 credit
Flat. There is no model in a replay, so there is no metered LLM cost to settle against — the 1 credit is the whole charge.
See the full rate cardWhich one
When a different tool is the right call.
The honest answer is often the neighbouring tool. These are the trades.
dispatchdispatch finds the right skill for you from a natural-language goal; run_skill needs you to already know its name. If your caller is an LLM improvising phrasing, dispatch. If it is your own code with a fixed workflow, run_skill is one less matching step and one less thing to go wrong.
dispatchrun_goalrun_goal re-reasons the flow every time — ten times the cost, and the right answer when the page genuinely differs run to run.
run_goalQuestions
run_skill, answered.
- What does “no LLM in the loop” actually mean for cost?
- It means the run has no token bill at all. Twin Browser bills higher-of(flat floor, metered model + compute + egress); with no model call the metered half is zero, so a replay settles at its flat floor every time. That is why the number is stable in a way a planner-driven run’s cannot be.
- Can I pass values into a replay?
- Yes, over REST: a compiled skill keeps {{param:NAME}} tokens rather than the literal values used at compile time, and POST /api/v1/skills/{name}/run accepts a `params` object that binds them. list_catalog tells you which params a given skill expects. The MCP tool does not currently forward params.
Keep going
The rest of the tool set.
compile_skillTurn a flow you are going to run many times into a stored artifact that costs almost nothing to run again.
dispatchBe the one call an agent makes, and get cheaper every time the agent asks for the same thing in different words.
list_catalogLet an agent plan: pick a skill it can actually run, with values it can actually supply.
list_skillsAnswer “what do I already have?” before spending anything.