Getting started — browse guides

Getting started

Link a repository, mint a token, and get a first green test — including how to bring existing Playwright or Cypress specs in without spending AI credits.

There are two different "getting started" paths, and it is worth knowing which one you are on:

  • Running Vera itself (self-hosting the control plane, or contributing to it) — see the repository README: Docker for Postgres + MinIO, pnpm setup, pnpm dev.
  • Wiring a repo you're working in to a Vera that already exists — this page. One command, and your editor, your coding agent, and your CI all know which Vera project this repo belongs to.

One minute to a linked repo

npx vera-agent init --url https://your-vera-host --token vera_your_token

Write vera-agent, not vera. The published package installs both bins, but npx vera fetches an unrelated package squatted on that name in 2022 — the short alias is safe only once vera-agent is already installed, never in an npx one-liner.

init is idempotent: it reports what changed, and re-running it when nothing has changed says so instead of touching tracked files.

What one run does:

  1. Resolves the project. Reads the repo root and origin, then matches a project this token can see: a GitHub-linked project wins, then a name match (my-app == My App). Two projects with the same name is ambiguous and it asks for --project <id> rather than guessing — linking a repo to the wrong project would silently misdirect every later run and coverage answer. Nothing matches at all? It prints the dashboard link to create one. A token cannot create projects, by design.
  2. Writes .vera/config.json{apiUrl, projectId, repoPathPrefix}. Commit it. No credential is in it.
  3. Saves the token to ~/.vera/cli.jsonchmod 600, keyed by apiUrl, so one machine can hold credentials for several deployments and a second repo on the same host needs only --url.
  4. Registers the vera MCP server at the repo root (claude mcp add at local scope — that scope is keyed by the directory a Claude Code session is started from), so a session opened in this repo has the tools. Skipped with --no-mcp; see MCP setup for the other scope and for non-Claude-Code clients. If a vera server is already registered in any scope, init leaves it alone and says so.
  5. Writes the agent-instructions block into whichever instructions file the repo already uses (AGENTS.md, else CLAUDE.md), between <!-- vera:sdlc:begin --> / <!-- vera:sdlc:end --> sentinels. Only the region between the markers is ever rewritten; your prose either side survives. --no-agents-md skips it.

Flags

FlagMeaning
--url <apiUrl>Your Vera origin (no trailing slash needed).
--token <vera_…>An API token (below). Omit it when one is already stored for that --url.
--project <id>Choose the Vera project explicitly — required when the name match is ambiguous, and the way to link a repo whose name doesn't match anything.
--mcp-scope local|projectWhere the MCP registration goes. local (default) → claude mcp add, private to you, carries the real token. project → merges a vera entry into the repo's committed .mcp.json using ${VERA_TOKEN}.
--no-mcpDon't register an MCP server.
--no-agents-mdDon't write the agent-instructions block.
--import <formats|all>Convert the E2E suite this repo already has into Vera tests (cypress, playwright, postman, wdio, selenium, testcafe, har, openapi). Deterministic, no AI. See below.
--no-importSkip the repo scan for importable suites.

In a terminal, omitting --url / --token prompts for them. In a script, both are required (or supplied via a token already stored for that URL).

Three files, and which ones carry a secret

This is the part people get wrong most often.

FileCommitted?HoldsWritten by
.vera/config.jsonYes — commit itapiUrl, projectId, repoPathPrefix. Never a credential; it lands in everyone's checkout.init
~/.vera/cli.jsonNeverYour vera_… API tokens, keyed by apiUrl. chmod 600.init
~/.vera/agent.jsonNeverThe different vera_agent_… enrollment token used to execute runs locally. chmod 600.vera-agent login

The last row is the one that surprises people: init and login write different files holding different credentials for different surfaces. init's token is a CI Token (vera_…) for the API and MCP; login's is an agent enrollment token (vera_agent_…) that lets this machine claim and run work. start, run, watch and verify all read the enrollment file, so if you only ran init, verify will tell you the handshake failed — run login too.

With --mcp-scope project, the committed .mcp.json carries the literal string ${VERA_TOKEN}; each developer exports their own token (export VERA_TOKEN=vera_…). No secret enters the repo either way.

Before that: mint a token

Settings → CI Tokens → name it → Create. Optionally set an expiry, and check org-wide for a shared/unowned token that keeps working after its creator leaves (needs the org-wide token permission; the default is personal, which is what you want for your own machine — audit rows and usage counters then name a human).

The plaintext vera_… token is shown once. Revoking it takes effect immediately.

Plan note, because the failure is otherwise mysterious. init reads GET /api/v1/projects, and on cloud /api/v1 requires the Pro api-access feature. A free cloud workspace gets mcp-basic instead, which covers /api/mcp only — so the MCP tools work while init refuses with:

Vera token not accepted. It may be revoked, expired, or this workspace may no longer include API access. Check Settings → API tokens, and the workspace plan.

Those three causes are deliberately indistinguishable from the outside, so don't assume "rotate the token" — check the plan too, especially on a recently downgraded workspace where the token is still perfectly valid. Self-hosted and local installs have no billing: every feature is on.

The ritual

init ends by printing this loop, because it is the whole point of installing anything:

  1. Change something in the UI.
  2. Verify it in a real browser as a real role. Not "it compiles" — an actual run, as a logged-in user, that reports what it observed. From Claude Code with the plugin: /vera:verify. Over MCP: run_scenario (unsaved) or run_test, then wait_for_run.
  3. Keep the check if it's worth keeping. A scenario you just watched pass is promoted into a durable test in one call (save_scenario_as_test) — better than authoring a test blind. Vera returns warnings when the steps prove nothing; act on them.
  4. On red, triage before repairing. Decide whether the test is wrong or the app is wrong. /vera:fix, or get_failure_detailssuggest_fix. A repair that makes a failing test agree with a bug converts a known failure into a silent one, so nothing is applied without your approval.

Before you push, npx vera-agent check maps the diff onto the tests that cover it and can run exactly that set (--run). Read change impact before you trust the answer — the joins are heuristics, and an unmapped file is not a safe one.

Verifying against localhost

A cloud Vera cannot reach http://localhost:3000. Two ways to close that gap, both requiring an agent enrollment (Settings → Agents → create → copy the vera_agent_… token):

npx vera-agent login --url https://your-vera-host --token vera_agent_...

# run an ad-hoc check here, now, in this process — seconds, no queue
echo '[{"action":"goto","url":"/orders"},
       {"action":"assert","selector":"#total","assertType":"text","value":"42 orders"}]' \
  | npx vera-agent verify --project prj_123 --steps - --role admin

# or replay something already saved
npx vera-agent verify --test tst_456

It is still a real run: the control plane creates the row, stores the step results and video, and shows it in the project's run feed — local and cloud checks share one history. What runs locally is the browser, not the bookkeeping.

For the standing setup — an environment whose runs always execute on your machine — see the local agent guide.

Bringing existing specs in (no AI credits)

If the repo already has an E2E suite, convert it instead of starting from an empty project. Eight formats are supported: postman, cypress, playwright, wdio, selenium, testcafe, har, openapi.

curl -s -X POST https://your-vera-host/api/v1/projects/prj_123/import/cypress \
  -H "Authorization: Bearer vera_your_token" \
  -H 'content-type: application/json' \
  -d '{"files":[{"path":"cypress/e2e/login.cy.ts","content":"…file text…"}]}'

Bounds, all of which refuse atomically rather than importing part of a batch: 50 files per request, 5,000,000 characters per file, 16 MiB per body. A 201 returns the created tests, per-format counts, skipped files with reasons, warnings, and an unresolved count.

Be careful what you quote from that response. Conversion is deterministic and costs no AI credits, and that is exactly why it is partial: navigation and interaction map cleanly, but an assertion the converter cannot express is reported, not converted — it lands in warnings with an unresolved count and is left out of the test. A Cypress spec whose only assertion was cy.contains('Welcome back') imports as goto, fill, fill, click: a test that replays green and proves nothing. So read unresolved before believing a test count, and add the missing assertions (by hand, or by re-importing with {"aiFallback": true}, which does spend AI credits on your own key).

Or let init do it

init scans the repo for importable suites and offers what it found:

npx vera-agent init --import all          # convert everything it finds
npx vera-agent init --import cypress,har  # or name the formats
npx vera-agent init --no-import           # skip the scan entirely

Without --import, an interactive init prints what it found and asks. When stdin is not a terminal (CI, a piped provisioning script) it imports nothing and says so, with the flag to opt in — importing writes tests into someone's workspace, and a script that piped vera-agent init did not consent to that. The scan honors .gitignore, and aiFallback is never sent from this path, so a first green costs no AI credits.

This is also the command vera check prints when its impact map is cold: imported tests carry their own goto URLs, which is exactly what the route join reads.

Where to go next

  • The Vera Claude Code plugin — the skill and the /vera:* commands, so the procedure isn't re-explained each session.
  • MCP server — every tool, the auth model, the confirm-to-apply rule.
  • The local agent — the full vera-agent command surface, environment run targets, native mobile, troubleshooting.
  • Change impact (vera check) — which tests a diff touches, the three joins and what they cannot see, --run and the opt-in --strict.
  • CI integration — triggering runs from CI with the same vera_… token; CI-rider for running them on your own runners.