Skip to content

CLI

cora [options] [command]

cora --help lists the global options and the commands on the command line, and cora <command> --help a command’s description, options and examples. A command that needs an account checks it before it runs, as What needs an account says.

Global options apply to every command.

Option Description
--version print cora’s version
--log-level <level> trace, debug, info, warn, error or silent
--log-file [path] write a JSON Lines log file, to the state directory’s logs/ (.cora/logs/ by default) without a path
--log-format <format> human or json, for stderr
-v, --verbose log at info
-q, --quiet log only errors, and print no progress or summary
--debug log at debug, and write a log file
--color color the output, even where it is not a terminal
--no-color never color the output
-h, --help display help for command
Command Description
cora scan scan the targets, write a results file, and compare it with the baseline
cora report merge merge results files, compare them with the baseline, and write the report
cora baseline update accept the issues in results files into the baseline
cora status show the account, the project’s newest scans and its fixes’ progress
cora auth login sign in to CORA in the browser, or with an account token from stdin
cora auth logout sign out, removing the credentials file
cora auth status print the account the credential names
cora auth token print the account token, renewing it first when it nears its expiry
cora init set up CORA in the project: its config, CORA’s build plugin or Angular’s source locations, and its coding agents
cora info print the environment a bug report needs
cora mcp run cora’s MCP server for coding agents, at the same version
cora hook answer a coding agent’s hook: read the event on stdin, and write the answer on stdout
cora help display help for command

Scans each target in a browser, and writes a results file to the state directory’s runs/. Targets and crawls on the command line replace the config’s targets.

When the config names a server, it starts the server first and stops it once the scan ends. It then compares the results with the baseline, and exits 1 when the gate fails. In CI, or with --report, it also writes the report directory.

With --shard or --no-gate, it writes only the results file, which cora report merge compares later.

cora scan [options] [targets...]

Needs an account: yes: cora checks it before the command runs, and stops with account.missing when you are not signed in.

Argument Description
targets URLs, or paths relative to the base URL; replace the config’s targets
Option Description
--base-url <url> replaces the config’s baseUrl
--crawl <url> crawl from this page, a URL or a path relative to the base URL, following its links that stay on its host; repeatable; with the targets, replaces the config’s targets
--crawl-max-pages <n> the most pages each crawl takes in, its start page included; 25 by default, as a crawl’s maxPages
--crawl-max-depth <n> the most links each crawl follows from its start page, 0 to scan the start page alone; 2 by default, as a crawl’s maxDepth
--crawl-exclude <pattern> a regular expression for links no crawl follows, such as /logout, tested against each link’s absolute URL; repeatable
--crawl-ignore-robots-txt follow links that a site’s robots.txt disallows, as a crawl’s ignoreRobotsTxt does
--page-timeout <ms> bounds each page’s visit, in milliseconds; replaces the config’s page.timeout
--headed shows the browser, to watch the scan; headless in CI, under a coding agent or without a display; replaces browser.headed in your user config
--only <selectors> run only the rules these selectors name, of those the config’s rules select: rule IDs such as axe/region, criteria such as 1.4.3, categories such as forms, or engines such as axe/*, comma-separated; repeatable
--skip <selectors> run none of the rules these selectors name; as --only takes them
--out <path> write the results file here instead of the state directory’s runs/ (.cora/runs/ by default); - for stdout
--shard <i/n> scan only shard i of n; cora report merge compares the shards
--no-gate only write the results file, for a later cora report merge
--baseline <path> compare with this baseline instead of cora.baseline.json
--report <dir> write the report directory here; in CI, the state directory’s report/ (.cora/report/ by default)
-h, --help display help for command

Examples:

Terminal window
# Scan the config's targets, and compare the results with the baseline
cora scan
# Scan one page of the app at localhost:5173
cora scan /pricing --base-url http://localhost:5173
# Crawl a site from its home page, taking in up to 50 pages
cora scan --crawl https://example.com/ --crawl-max-pages 50
# Scan with the browser shown, to watch it
cora scan --headed
# Run only the rules of the forms category and of WCAG's 1.4.3
cora scan --only forms,1.4.3
# Scan the second of four shards, for `cora report merge`
cora scan --shard 2/4 --out results-2.json

Merges results files, such as the shards of one run, into one run. It compares the merged run with the baseline, writes the report directory, and exits 1 when the gate fails.

Each input is a results file, or a directory whose .json files it reads. Every shard of a sharded run must be there: a missing one stops the merge with exit code 2.

cora report merge [options] <inputs...>

Needs an account: yes: cora checks it before the command runs, and stops with account.missing when you are not signed in.

Argument Description
inputs results files, or directories of them
Option Description
--baseline <path> compare with this baseline instead of cora.baseline.json
--report <dir> write the report directory here instead of the state directory’s report/ (.cora/report/ by default)
-h, --help display help for command

Examples:

Terminal window
# Merge every results file in `results/`
cora report merge results
# Merge them, and write the report directory to `report/`
cora report merge results --report report

Rewrites the baseline from the latest results. It adds each new violation, and removes each one the results prove fixed. It keeps what they did not verify, such as the violations of a rule the run skipped.

The baseline is cora.baseline.json in the project, unless --baseline names another. Commit it, so each run’s gate compares with it. Each input is a results file, or a directory whose .json files it reads.

cora baseline update [options] <inputs...>

Needs an account: yes: cora checks it before the command runs, and stops with account.missing when you are not signed in.

Argument Description
inputs results files, or directories of them
Option Description
--baseline <path> rewrite this baseline instead of cora.baseline.json
-h, --help display help for command

Examples:

Terminal window
# Accept the issues a scan found
cora baseline update results.json
# Accept those of every results file in `results/`, such as the shards of a run
cora baseline update results

Shows whether your account is valid, the project’s newest scans, and where each issue the coding agent’s fixer works on stands. With --json, it prints the same as one JSON object, in a versioned format.

It reports the account rather than requiring one. A coding agent’s subagent status line runs it with --subagent-status-line.

cora status [options]

Needs an account: no: the command reports whether you are signed in, and runs without an account.

Option Description
--json print one JSON object, in a versioned format
--subagent-status-line <harness> answer a coding agent’s subagent status line: read its rows on stdin, and write the fixer’s progress in the fixer’s row (claude)
-h, --help display help for command

Examples:

Terminal window
# Show the account, the newest scans and the fixes' progress
cora status
# Print the same for a script
cora status --json

Signs in to your CORA account. It prints a page and a code to enter there, and opens the page in your browser where it can. Once you approve the login, it saves the credential in your per-user config directory.

With --with-token, it saves the account token it reads from stdin instead, without the browser.

cora auth login [options]

Needs an account: no.

Option Description
--with-token save the account token read from stdin, without the browser
-h, --help display help for command

Examples:

Terminal window
# Sign in through the browser
cora auth login
# Save a token from a file, without the browser
cora auth login --with-token < token.txt

Signs out by removing the saved credential. When CORA_TOKEN is set, it says so, since the variable still provides a credential until you unset it.

cora auth logout

Needs an account: no.

Option Description
-h, --help display help for command

Examples:

Terminal window
# Sign out on this machine
cora auth logout

Checks the account, then prints the CORA service and your account there: its organization, by ID and name, its plan, when its token expires, and where the credential comes from. Without a credential, it fails with account.missing.

cora auth status

Needs an account: yes: the command checks it as it runs, and fails with account.missing when you are not signed in.

Option Description
-h, --help display help for command

Examples:

Terminal window
# Show the account and when its token expires
cora auth status

Prints the account token on stdout, alone, for a script that needs it. It renews a signed-in token first when the token expires within the hour. When CORA_TOKEN is set, it prints that token.

Treat what it prints as a secret: pass it on through a variable or a file, never on a command line.

cora auth token

Needs an account: yes: the command checks it as it runs, and fails with account.missing when you are not signed in.

Option Description
-h, --help display help for command

Examples:

Terminal window
# Give the commands this shell starts the token of your login
export CORA_TOKEN="$(cora auth token)"

Sets CORA up in the project in the working directory. It writes a starter config, unless the project has one: cora.config.ts beside a package.json, and cora.config.json elsewhere. In a Vite project, it registers CORA’s Vite plugin in the Vite config, and in a Nuxt or Astro project in vite.plugins of its nuxt.config or astro.config, where the framework reads Vite’s plugins; in a webpack, Rspack, Rsbuild, Rollup or Rolldown project, it registers that bundler’s plugin in its config’s plugins, so findings name the line to fix. In an Angular CLI workspace on Angular 22.1.4 or later, it turns on Angular’s own template source locations for each application’s development builds: a tsconfig.cora.json beside the application’s tsconfig, and the development configuration in angular.json pointed at it. A project that lists one of these tools without a config of it there is told it was not set up, and where the plugin goes, unless a tool that brings that bundler along is set up there, as Vite does Rollup.

The starter config’s target is a crawl from the home page, of up to 25 pages up to 2 links away, which skips common sign-out links. Where the nearest package.json’s dev script, or its start script where it has no dev, starts the dev server of Vite, Next.js, Nuxt, React Router, Docusaurus, Angular, Create React App, CRACO, webpack, Rspack, Rsbuild or Parcel, it sets server to run that script with the project’s package manager, and baseUrl to the server’s address: the port the script sets, or else the port the dev server’s own config writes out, or else the tool’s default. It reads the script and that config, and runs neither. It prints the command and URL it set, and cora scan then starts the app, and stops it once the scan ends. Where it cannot be sure where the server answers, as for a script that starts two servers, serves HTTPS, listens on an address localhost may not reach, or takes its port from a shell variable such as $PORT, or for a dev server whose own config computes or imports its port, it writes no server, says why, and leaves baseUrl a placeholder. With --base-url, it sets that address and no server.

For Claude Code, it adds CORA’s plugin to the project’s Claude Code settings. For Codex, it sets CORA’s fixer agent up in the project’s .codex/, from the cora the project installed, or as a copy where Codex can read no installed one, as on Yarn’s Plug’n’Play. Where neither is there yet, it prints the run of cora init that does this after the install. It finds the coding agents a project uses from their files in it, such as .claude/ or AGENTS.md, and from their CLIs on PATH, unless --agent names them.

It keeps each file’s own layout, and formats a new file with the project’s Prettier, which reads its config and .editorconfig, or else indented as the nearest package.json is, or with two spaces. It leaves a file it cannot edit as it is, and names the docs page that shows the change to make by hand.

It shows each change as a diff, and asks once before it writes anything. In CI, inside a coding agent, or with --yes, it writes without asking. Elsewhere, where it cannot ask, such as with stdin or stderr redirected, under -q or with --log-format json, it writes nothing and fails with cli.confirmation-required. Running it again changes only what is missing, CORA’s copies nobody has edited, and a fixer declaration whose file is gone.

cora init [options]

Needs an account: no: the command reports whether you are signed in, and runs without an account.

Option Description
--base-url <url> the address of an app init does not start, such as a staging site or one a backend serves, which a new config sets with no server
--agent <names...> set up these coding agents rather than those detected; repeatable (claude or codex)
--project-agent set up CORA’s fixer for Claude Code as a project agent with an MCP server of its own, so that only the fixer has CORA’s tools
-y, --yes write the changes without asking
-h, --help display help for command

Examples:

Terminal window
# Set up the project to start and scan the app's dev server
cora init
# Set up the project to scan an app it doesn't start, at staging.example.com
cora init --base-url https://staging.example.com
# Set up Codex alone, without asking
cora init --agent codex --yes

Prints what a bug report needs: which cora ran and why, Node.js, the operating system, the project’s config, your user config, the browsers cora would use, and which of the variables it reads are set.

Of the variables it reads, it prints which are set, not their values, and of your user config only whether cora used it. The exceptions are the CORA service, its request timeout, the paths cora uses, such as the state directory, the coding agent that runs cora, by the name its variable gives, and why your user config was ignored, such as a later version’s file. Paste its output into the report, or attach the JSON.

cora info [options]

Needs an account: no.

Option Description
--json print one JSON object
-h, --help display help for command

Examples:

Terminal window
# Print the environment for a bug report
cora info
# Save it as JSON, to attach
cora info --json > cora-info.json

Runs cora-mcp, CORA’s MCP server for coding agents, at this cora’s version. It fetches that release of @vispero/cora-mcp through npx, then hands over to it. Options after mcp pass to cora-mcp.

A coding agent’s MCP entry runs it as npx --no cora mcp, so the server follows the project’s cora through its upgrades.

cora mcp [cora-mcp options...]

Needs an account: yes, for its tools: cora-mcp starts and lists its tools without one, then checks it on each tool call, which it answers with account.missing when you are not signed in.

Argument Description
cora-mcp options passed to cora-mcp as they are, such as --headless
Option Description
-h, --help display help for command

Examples:

Terminal window
# Serve a coding agent on stdio, at this cora's version
cora mcp
# Serve with a browser that opens no window
cora mcp --headless

Answers a coding agent’s hook, as CORA’s plugin runs it: it reads the event on stdin, and writes its answer on stdout. Its answers ask you before an edit of what decides what CORA reports, keep CORA’s tools in the fixer, and start the fixer after UI edits.

It exits 0 whatever happens, since an agent reads another exit code as a block or an error. It writes nothing on stderr, and logs to its agent session’s file in the state directory’s logs/. Its stdout holds only its answer, so cora hook --help prints nothing; cora help hook prints this help.

cora hook [options] <event>

Needs an account: partly: without an account, the command says why, as a warning, then does only the work that needs none, such as asking you before an edit of what decides what CORA reports.

Argument Description
event the hook’s event: user-prompt, when the person submits a prompt to the coding agent; pre-tool-use, before the coding agent runs a tool; post-tool-use, after a tool the coding agent ran succeeds; stop, when the coding agent is about to end its turn; subagent-start, when the coding agent starts a subagent; subagent-stop, when a subagent is about to stop; session-end, when the coding agent’s session ends
Option Description
--harness <harness> the coding agent that runs the hook (claude or codex)

Examples:

Terminal window
# Answer Claude Code's event before a tool runs, saved in `event.json`
cora hook pre-tool-use --harness claude < event.json

display help for command

cora help [command]
Code Meaning
0 The gate passed, or a command that gives no verdict finished: cora scan with --shard or --no-gate, cora baseline update, cora auth login, cora auth logout, cora auth status, cora auth token, cora init, cora info or cora hook
1 The gate failed: new issues at or above policy.failOn
2 No verdict: a target or file was not scanned, such as a failed load or a redirect to a page the run did not scan, and nothing failed, or an error stopped the command: any code in the error reference

Exit code 2 covers both a run that gives no verdict and an error. A CI script that starts from an empty report directory tells them apart by whether results.json was written there: an incomplete run is reported in full, with results.json written last, and an error stops before it. A command that needs an account, such as cora scan, checks it before anything else: without a valid credential it fails with an account.* error, and with a service.* error when the CORA service does not answer as the check renews the credential or fetches the signing keys. cora hook exits 0 whatever happens, since a coding agent reads any other exit code from a hook as a block or an error: it reports an error, a missing account among them, as its answer on stdout. A signal ends a command by that signal, which a shell reports as 128 plus its number: 130 for Ctrl+C, 143 for SIGTERM. cora scan, cora auth login and cora init stop first and write no file from then on, so an interrupted scan writes no results, and cora mcp ends by the signal once the npx or the release it runs has ended.