Exit codes
mcptest's process exit codes are a contract: CI pipelines branch on them, so the values only change with a breaking release. Most are pinned as constants (in crates/mcptest/src/cli/exit_codes.rs and its tests); exit 7 is currently a literal in the run-selection code, and WOR-1351 tracks moving it into the same module.
| Code | Meaning | Example trigger |
|---|---|---|
| 0 | Success. The command completed and everything it checked passed, or there was nothing to check. | mcptest run against a suite where every test passes, or with no config file present. |
| 1 | Failure. The command completed but at least one test, check, gate, or probe failed, or a run-level error prevented a passing result. Also the catch-all for internal errors at the CLI boundary. | mcptest run with one failing assertion; mcptest doctor --url against a server whose probe fails. |
| 2 | Invalid invocation. Conflicting or malformed flags, an invalid config, or a suite CI refuses to run. Nothing was executed. | mcptest run --filter 're:(' (bad regex); a config that fails schema validation; --watch with a machine reporter such as --reporter json; a focused suite under CI=true; --deny-lints with lint findings. |
| 3 | Not ready. --wait-for-ready exhausted its budget before every URL server accepted connections. Distinct from 1 so CI can retry a slow-starting deployment instead of failing the build. | mcptest run --wait-for-ready 30s while the server never starts listening. |
| 5 | Refused by policy. The invocation is well-formed, but a policy gate said no. | mcptest run --update-snapshots under CI=true without --allow-update-in-ci; mcptest eval --max-cost 0.10 when the judge spend trips the budget. |
| 6 | Quality gate not met. The command ran cleanly but a measured floor or drift gate tripped. | mcptest coverage --tools-from tools.json --threshold 80 on a suite covering 60% of the catalog; mcptest model-compat reporting DRIFT; mcptest generate stubs --check finding generated stubs that differ from the checked-in files. |
| 7 | No tests selected. The run discovered zero tests (an empty suite, or a --filter, --shard, or --last-failed selection that matched nothing) and --pass-with-no-tests was not passed. | mcptest run --filter nomatch; a CI shard that drew an empty slice without --pass-with-no-tests. |
| 130 | Interrupted. The run received SIGINT (Ctrl-C); in-flight work was cancelled cleanly, partial results were written, and the process exited. The value follows the shell 128 + signal convention (SIGINT is 2). Distinct from 1 so a deliberate Ctrl-C is never read as a test regression. | mcptest run against a slow suite, then Ctrl-C before it finishes. |
Code 4 is reserved and currently unused.
Notes:
mcptest run's 0-vs-1 outcome folds in every gate that rides on the run: failing tests, tool-selection floors, matrix assertion floors, timing-baseline breaches, and (when the suite opts in viarun_options.inconclusive.treat_as: fail) inconclusive verdicts.- Security commands (
mcptest security redteam,adaptive) report whether the run completed, not whether the model was exploited (ADR 0041); see their own docs for the verdict surface.