Overview
Beryl is the web-testing integration for your coding agent: an MCP server and CLI that let it write and maintain end-to-end tests for any web app, from the editor you already work in. It runs as a local stdio MCP server, so it plugs into Claude Code, Claude Desktop, Cursor, VS Code, opencode, and any other client that speaks MCP.
Tests are durable, plain-language plans, not selector scripts, and they live on beryl.so: versioned, run in real cloud browsers, scheduled, diffed, and healed when your UI drifts. Signup, OTP, and magic-link flows are self-contained through durable test accounts with real inboxes, and your suite stays portable as standard Playwright.
Quickstart
Beryl plugs into the coding agent you already use. One command wires it up; from then on your agent asks Beryl's cloud agent to create durable end-to-end tests from a document, and runs them in Beryl's cloud.
- 1
Set up: run in your repo
npx @beryl-so/cli@latest initSigns you in, asks which agent to wire the
berylMCP server into, and installs the beryl-test skill. Nothing goes in your app code. The per-agent flags, and manual setup for any other MCP client, are in MCP setup. - 2
Approve the sign-in
Your browser opens
beryl.so/cli/connect. Confirm the code shown in the terminal. No browser handy? Press Enter for an emailed 6-digit code; a new email gets an account created automatically. - 3
Ask your agent for tests
"Create tests for https://example.com from docs/checkout.md"Your agent starts a test-creation job (
beryl jobs create): Beryl's cloud agent reads the document, explores the site, and authors one test per flow it describes. The document is sent to the LLM that drives the agent. - 4
Run them
beryl runs trigger --watchRuns the suite in Beryl's cloud browsers;
--watchstreams progress and exits non-zero unless every test passed.
Signing in
beryl login (run by init too) signs in via the browser: the CLI opens beryl.so/cli/connect, you approve the code shown in the terminal, and a personal access token is stored in ~/.config/beryl/config.json. Nothing else is persisted.
beryl login| Fallback | When to use it |
|---|---|
| Press Enter at the prompt | Emails a 6-digit code instead. A brand-new email gets an account created automatically, with no separate signup. |
beryl login --otp | Skip the browser entirely and go straight to the emailed code. |
beryl login --token | Use an existing token from beryl.so → Account → Personal access tokens. |
BERYL_API_KEY | Environment variable for CI and headless machines, with no login command at all. |
The full flag reference, including the non-interactive --email --code flow for agents, is on the CLI page.
How Beryl works
Durable tests, not scripts
A Beryl test is a JSON action plan: the steps to take, each carrying its intent in plain language. There are no selectors or XPath to maintain. When the UI shifts, the recorded intent lets Beryl heal the step instead of you hand-fixing a script.
Every test is authored by Beryl's cloud agent, from a document a human writes (beryl jobs create), so all plans are built one way. Your own agent stays in the loop over the beryl MCP server: it triggers runs, reads failures, and fixes a test by editing its plain-JSON plan and submitting it with beryl tests recompile, which proves the change with a replay before it saves. The beryl-test skill installed by init teaches it the plan shape; beryl guide prints the same guide.
Sign-in flows are self-contained: authenticated tests sign in as durable test accounts, and their email (OTP codes, magic links) arrives at the project's own mailbox, so signup and login flows run with no human in the loop.
What init sets up
| Piece | What it does |
|---|---|
beryl MCP server | Every CLI command, served as a tool over stdio. The config holds no token. The server reads your CLI login from ~/.config/beryl. |
| beryl-test skill | The test guide, installed to ~/.agents/skills/ and ~/.claude/skills/. |
The default scope is per-user (matching where your login token lives), so the setup follows you into every repo. beryl init --scope project writes a committed .mcp.json and repo-local skills for teammates instead. Re-running is safe: it refreshes the skill to the CLI's version and skips whatever is already configured. Which files it touches for each agent is listed in MCP setup.
Cloud runs & CI
The suite runs in Beryl's cloud browsers with beryl runs trigger. --watch streams progress and exits non-zero unless every test passed, so one line gates a deploy.
beryl runs trigger --watchIn CI, authenticate with a project-scoped CI token (created in the project's Settings → CI, it can only trigger and read that project's runs) stored as a secret:
env:
BERYL_TOKEN: ${{ secrets.BERYL_CI_TOKEN }}
run: |
npx @beryl-so/cli runs trigger --watchToken setup, the full flag vocabulary, exit codes, and a prompt for your coding agent are covered in CI integration.
Scheduling & healing
Banked tests keep working without you. Put the suite on a schedule and Beryl re-runs it in the cloud, diffs each run against the previous one, and shows exactly what changed, so a flow that passed yesterday and fails today surfaces immediately.
beryl schedule add --frequency daily --hour 6 --tz UTCWhen a step breaks but the flow still works, Beryl heals the test from its recorded intent instead of paging you. Every run produces a report: pass/fail per test, timing, and history over time (beryl projects report).
The web app
Everything lives at beryl.so too: projects, tests, runs, replays, diffs, reports, and team management. Login-gated apps work through durable test accounts and the project's own mailbox.
FAQ
What do I need installed?
Node 20.19+. init handles the rest: the beryl MCP server wiring and the beryl-test skill. Nothing is added to your application code, and tests run in Beryl's cloud, not on your machine.
Do I write test code?
No. Beryl's cloud agent authors JSON action plans from a document you write, with each step's intent in plain language. No selectors or XPath to maintain.
Can it test flows behind a login?
Yes. Authenticated tests sign in as durable test accounts, and sign-up or OTP email arrives at the project's own mailbox, so magic-link and verification flows run without a human.
How do regressions get caught?
Scheduled cloud runs diff each run against the last, so real failures surface immediately, while healable breaks (a moved button, a renamed label) are healed from the test's recorded intent instead of failing the run.
Support
Browse the Support Center or reach the team at [email protected]. We respond within one business day.
