Receipts for
every preview.

katalepsis runs your Playwright tests, or checks written in plain English, against a preview deployment. You get a report you can paste into the pull request: what passed, what broke, what couldn't run, and what nobody tested.

Get it on GitHub

Open source and local. Agent checks use your own key, and everything else needs none.

A real katalepsis report for the demo signup form: 2 passed, 1 failed, with the failing assertion and its screenshot
Built for

Four ways to run it

katalepsis run

Your Playwright tests

Runs the tests you already have against the preview. No AI key, and --install-browsers fetches whatever Playwright needs.

katalepsis verify

Checks without tests

Describe what should happen and a model works through it in a real browser on your OpenAI or OpenRouter key.

MCP server

From your coding agent

Claude Code, Codex or Cursor can run tests and checks, then read the report, without you typing a command.

CI job

On every pull request

Run either command in a CI job and upload the report folder. A ready-made GitHub Action isn't built yet.

Every check ends up passed, failed, blocked or not tested

A green tick tells you nothing about what was skipped. katalepsis sorts every check into one of these.

Passed

Playwright said so, or an assertion in the browser did.

Failed

Something on the page was wrong. You get the assertion that caught it, plus the screenshot, video and trace.

Blocked

The preview was down or the browser wouldn't start. Not your app's fault, and not counted against it.

Not tested

Skipped or filtered out. Listed by name, so nobody assumes it passed.

Your tests

Works with the Playwright tests you already have

Read the base URL from KATALEPSIS_BASE_URL and you're done. katalepsis uses your Playwright install and your config, asks the preview if it's up before starting a browser, and bundles whatever Playwright recorded.

  • No new test format, no AI key
  • --grep and --project work as usual
  • Every file in the bundle is listed with its SHA-256
~/your-app
$ katalepsis run --url http://127.0.0.1:4173 --cwd apps/demo-form
katalepsis: FAILED
  2 passed, 1 failed, 0 blocked, 0 not tested
  Report: artifacts/katalepsis/2026-10-10T12-45-00-937Z-bcfc2b/report.html
  Markdown: artifacts/katalepsis/2026-10-10T12-45-00-937Z-bcfc2b/report.md

Agent checks

Agent checks only pass when the browser agrees

For the things nobody wrote a test for, describe what should happen. A model with your OpenAI or OpenRouter key clicks through it in a real browser. To pass, it has to cite an assertion katalepsis ran that shows something it changed. When one of the models we tested cited a heading that was already on the page, the check was blocked.

  • Keys stay in your keychain or environment
  • Caps on steps, tokens and time per check
  • The browser can't leave your preview's domain
checks.json
{
  "id": "empty-form",
  "intent": "Submit the signup form without filling it",
  "passCondition": "A required-field error is visible"
}
openrouter / claude-haiku-5.5
FAILED  A cited assertion failed.
- a1 FAILED: role "alert" is visible
  (0 visible match(es) after waiting up to 3s)

MCP

Your coding agent can check its own work

katalepsis runs as an MCP server, so Claude Code, Codex or Cursor can test a preview and read the report without you in the loop. Same rules: the agent gets results, not a browser it can talk its way through.

  • Three tools: run tests, run checks, read a report
  • Locked to one folder, one run at a time
  • Never takes a key as an argument
codex exec
user
Use the katalepsis MCP tool verification_run_tests with
baseUrl http://127.0.0.1:4173/ . Then reply with only the
runId, status and counts from the result.
mcp: katalepsis/verification_run_tests started
mcp: katalepsis/verification_run_tests (completed)
codex
{"runId":"2026-10-10T13-09-00-026Z-0aadc0","status":"failed",
 "counts":{"passed":2,"failed":1,"blocked":0,"notTested":0}}

One minute, all real output

Find out what the preview actually does

Katalepsis (κατάληψις) is the Stoics' word for grasping something so clearly you can't be wrong about it. Seemed like a fair bar for a pull request.