Unbreakable web automation API

Automate any website,even behind a login.

Kaabist is an API that does work on websites for you: it signs in, fills in forms, downloads reports and returns the data as JSON. Your coding agent builds the automation, and Kaabist runs it whenever you call it or on a schedule. If the site asks for a 2FA code, Kaabist emails you a link; you type the code and the run carries on from where it paused.

Setup for agentsclaude mcp add --transport http kaab https://mcp.kaab.ist/mcp
web · eulive
watching 4 jobsring 1

How it works

Describe the task.Kaabist runs it.

  1. 01

    Describe the task

    Tell Claude Code, Codex or Cursor what you need, in plain words: “download last month’s invoices from our supplier portal on the 1st of every month”.

  2. 02

    Your agent builds a program

    It works through the site in a real Kaabist browser and saves the steps as a program: a short JSON file you can read, test and version, not a pile of selectors.

  3. 03

    Kaabist runs it

    Call it from your code, the CLI or a schedule. It runs in Kaabist’s browsers, signs in with the details you pass, and sends the results to your app as typed data or a signed webhook.

  4. 04

    It keeps working

    If the site moves a button, Kaabist finds it again and sends you the fix to approve. If it asks for a 2FA code, you get a link. If a payment step crashes, it is never pressed twice.

Where Kaabist fits

Your agent writes the program.Kaabist keeps it running.

mcp.kaab.ist/mcpstreamable http · oauth
CC
Claude Code
CX
Codex
CR
Cursor
mcp.kaab.ist
▢
real browser
{ }
program v1
Any agent
Claude Code · Codex · Cursor · any MCP client
Any flow
logins · 2FA · iframes · shadow DOM · downloads
Your code
TypeScript · Python · Go · REST · CLI

Built by your coding agent

One line in your agent.A program in your account.

~/projects/billing — claude
$ claude mcp add --transport http kaab https://mcp.kaab.ist/mcp
Added HTTP MCP server kaab
$ claude "renew my subscription on portal.example.test every month"
› browser_open https://portal.example.test/login
› browser_fill #email, #password
› await_input otp a person answers from a link
› browser_click Renew marked side_effect: true
› test_program dry_run stops before the first side effect
✓ program prg_4Rb · v1 saved · schedule: monthly
Opening a Kaabist browser

The portal redirects to /login; the form has email and password fields.

Sign in is a button with an accessible name, so I target it by role.

After sign in the site asks for a one-time code sent by e-mail.

I cannot read that inbox, so the step becomes await_input otp.

The person gets a hosted page; the job parks until they answer.

I add a checkpoint after login, so a retry does not log in again.

Renew changes the subscription: side_effect true, never retried blindly.

A dry run stops before Renew; every locator resolved uniquely.

Done. The program logs in, waits for your one-time code on a hosted page, and renews exactly once.

renew-subscription@v1succeeded

Never submits twice

A worker crashes on “Pay now”.Kaabist doesn’t press it again.

  1. fill

    card details

  2. checkpoint

    before_payment

  3. fence

    about_to_execute

  4. crash

    worker lost

  5. park

    side_effect_ambiguous

  6. confirm

    you check the order

renew.spec.tsbreaks on the next redesign
await page.goto('https://portal.example.test/login');
await page.fill('#root > div:nth-child(2) input', email);
await page.fill('.css-1x9f2k input[type=password]', pw);
await page.click('button.btn-primary');
// 2FA? someone has to be at the keyboard
const code = await waitForSlackMessage();
await page.fill('#otp', code);
await page.click('text=Renew');
// crashed here? the retry renews twice
renew-subscription.jsonkept working by Kaabist
{ "goto": "https://portal.example.test/login" },
{ "fill": "#email", "value": "{{inputs.email}}" },
{ "fill": "#password", "value": "{{inputs.password}}" },
{ "click": { "role": "button", "name": "Sign in" } },
{ "await_input": "otp" },
{ "fill": "#otp", "value": "{{vars.otp}}" },
{ "checkpoint": "after_login" },
{ "click": { "role": "button", "name": "Renew" }, "side_effect": true }

Live

Every job tells youwhat it did.

to answer a 2FA link, by default
24h
a paused run can wait
7days
per webhook
5retries
job.succeeded41.2 s · 12 credits
step.fencedclick Renew · runs once
job.resumedfrom checkpoint after_login
job.parkedawait_input otp · waiting for a person
job.startedrenew-subscription@v14

Start in one call

Any URL in.Structured data out.

import { Kaab } from "@kaabist/sdk";

const kaab = new Kaab(); // KAAB_API_KEY
const job = await kaab.jobs.create({
  url: "https://shop.example.test/p/1",
  extract: { title: "h1", price: { selector: ".price", type: "money" } },
  wait: 30,
});
console.log(job.data);

Plans

Start free.Grow by credits.

  • Free

    500

  • Developer

    10,000

  • Team

    60,000

  • Scale

    300,000

From config/plans.yaml.

How it compares

Not anotherscraping API.

CapabilityKaabistRemote browser platformsCrawl-to-markdown APIs
Pause for your 2FA code or approval, then continue from the last checkpointYesPartlyNo
A submit or payment never runs twice, even after a crashYesNoNo
Your coding agent builds the program over MCPYesPartlyPartly
Self-healing locators, delivered as proposals you reviewYesPartlyNo

Categories summarised from vendors' public documentation. Last verified 2026-10-10.

Questions

Askedbefore you ask.

It runs your website tasks (signing in, filling in forms, downloading files, pulling out data) as programs that survive 2FA prompts, redesigns and crashes, and returns the results to your code.

The run pauses and saves its place. Kaabist emails a link to you, or to whoever you choose, such as a teammate or your customer. They type the code on that page, and the run continues from where it paused instead of starting over.

No. Steps that submit are marked, and Kaabist records each one before and after it runs. If a server dies in the middle, Kaabist does not click again: the run pauses and you decide whether it went through.

Your coding agent records the program in a real Kaabist browser over MCP, with ranked locator candidates for every target. When the site changes, healing proposes a new locator for you to review.

Stop fixing selectors.Ship the automation.

Opening soon

Kaabist is getting ready for launch. The panel, the docs and the status page open on launch day.