qaitai docs

CLI

Run qaitai entirely on your machine with npx. No account, no server, your model key.

The qaitai CLI (MIT, Node.js 22+) runs the agent locally against localhost or any URL, with your own model key, and writes the report to disk.

Set a model key

Put one of these in your shell or in a .env file in the current directory (the first match wins):

VariableProvider
AI_GATEWAY_API_KEYVercel AI Gateway
ANTHROPIC_API_KEYAnthropic
AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY + AWS_REGIONAmazon Bedrock
OPENAI_COMPATIBLE_BASE_URL (+ OPENAI_COMPATIBLE_API_KEY)Any OpenAI-compatible endpoint (pass --model)

Get a browser

Local Chromium: npx playwright install chromium. Or set STEEL_BASE_URL (self-hosted steel-browser) or STEEL_API_KEY (Steel Cloud).

Check your setup

npx qaitai doctor

It checks Node, which model key would be used (verified with a read-only call, never printed), Steel reachability and whether Chromium launches, and prints a fix for each problem.

Run a journey

npx qaitai run http://localhost:3000 "sign up and create a project" --path /onboarding --workers 3

The report lands in ./.qaitai/runs/<id>/ as report.json, a single-file report.html and screenshots/.

Secrets

npx qaitai run https://www.saucedemo.com \
  "log in as problem_user with @secrets/pw, sort by price low to high, report problems" \
  --secret pw=secret_sauce --max-steps 30

The agent fills secrets through fill_secret as @secrets/<name>. Values are never printed, sent to the model or written to the report. Use --secrets-file .env.qaitai for many (keep it out of git).

Replay without the model

npx qaitai replay .qaitai/runs/20260923-101500-ab12 --url https://pr-42.preview.example.com

Re-runs one worker's recorded actions with the same role and accessible-name locators, and stops at the first step that fails.

Useful options

OptionDefault
--path <prefix>noneKeep top-level navigation under this path (repeatable)
--workers <n>1Parallel workers, each with a different angle
--model <id>claude-sonnet-5Model id
--max-steps <n> / --max-minutes <n>60 / 20Limits per worker
--browser <auto|local|steel>autoBrowser choice
--jsonoffMachine-readable summary on stdout
--fail-on <level>highExit 1 when a finding is at or above this level

Exit codes: 0 ok · 1 findings at or above --fail-on · 2 worker or setup error · 130 cancelled.

In GitHub Actions

This runs qaitai inside the job, against an app started in the job, with your own model key. To test a deployed environment on your qaitai instance instead (no browser or model key in CI), use qaitai/action@v1 or qaitai run --instance.

.github/workflows/qaitai.yml
name: qaitai
on: [pull_request]

jobs:
  qa:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm ci && npm run build
      - name: Start app
        run: npm start &
      - run: npx wait-on http://localhost:3000
      - name: Install Chromium
        run: npx playwright install --with-deps chromium
      - name: qaitai
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          QA_PASSWORD: ${{ secrets.QA_PASSWORD }}
        run: |
          npx qaitai run http://localhost:3000 --file .github/qaitai/checkout.md \
            --secret "pw=$QA_PASSWORD" --workers 2 --max-steps 40 \
            --json --fail-on high > qaitai.json
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: qaitai-report
          path: .qaitai/runs/

Full reference: packages/cli/README.md.

On this page