MCP Rigor logo MCP Rigor

CLI reference

Use npx mcprigor when installed locally. Examples below use mcprigor for brevity.

Create and author tests

init

mcprigor init tests/acceptance.mcpr
mcprigor init tests/acceptance.mcpr --force

Creates an editable plain-language example. Existing files are protected unless --force is supplied.

author

mcprigor author server.mcpr --out tests/customer.mcpr

Connects to the target in server.mcpr and guides you through creating a test. Alias: create.

Validate and run

check

mcprigor check tests/acceptance.mcpr

Validates language and configuration without connecting to the server. Alias: validate.

convert

mcprigor convert tests/acceptance.mcpr --out tests/acceptance.yaml
mcprigor convert tests/acceptance.mcpr --format json   # prints to stdout without --out

Emits the equivalent YAML or JSON suite for any input format. The natural language and YAML are in strict parity — both compile to the same suite model — so the converted file validates against the suite schema and runs with identical results. Use it to hand suites to programmatic tooling or to see exactly what a .mcpr file means.

test

mcprigor test tests/acceptance.mcpr

Aliases: run, for YAML/JSON compatibility.

Common options:

--test "pattern*"          Run matching tests
--command "node server.js" Override the suite's declared server target
--url https://qa.example.com/mcp
                           Override with a Streamable HTTP endpoint
--watch                    Rerun automatically when files change
--github-annotations       Emit ::error/::notice workflow commands
                           (automatic when GITHUB_ACTIONS=true;
                           disable with --no-github-annotations)
--html report.html         Write a readable HTML report with a clickable
                           request/response session timeline
--json result.json         Write structured JSON
--junit result.xml         Write JUnit XML
--evidence DIRECTORY       Save a sanitized evidence bundle
--snapshot FILE            Verify semantic snapshots
--update-snapshots         Explicitly create/update snapshots
--state-in FILE            Load persisted successful outputs
--state-out FILE           Save successful exported outputs
--max-rows NUMBER          Limit expanded data rows
--allow-remote-data        Enable REST and Google Sheets data
--allow-custom-code        Enable reviewed isolated extensions

Example CI run:

mcprigor test tests/acceptance.mcpr \
  --junit reports/mcp.xml \
  --evidence .mcprigor/ci-run

Browser workspace

mcprigor workspace
mcprigor workspace ./acceptance-tests
mcprigor workspace ./acceptance-tests --port 4173

Starts a loopback-only QA interface. Alias: web.

MCP server for agents

mcprigor serve
mcprigor serve path/to/project

Exposes MCP Rigor itself as an MCP server over stdio so coding agents can write, validate, and run suites. Alias: mcp. See the MCP server guide.

Transport parity

mcprigor parity tests/parity.mcpr
mcprigor parity tests/parity.mcpr --markdown
mcprigor parity tests/parity.mcpr --markdown --out parity.md

The suite must contain at least two Compare target declarations.

Discovery and contracts

Discover

mcprigor discover server.mcpr --out mcp.lock.yaml

Saves the server identity, capabilities, tools, resources, prompts, and fingerprint.

Generate contract tests

mcprigor generate mcp.lock.yaml --target server.mcpr --out generated.yaml

Check drift

mcprigor contract-check mcp.lock.yaml --target server.mcpr
mcprigor contract-check mcp.lock.yaml --target server.mcpr --markdown --out drift.md

Returns 1 when breaking drift exists.

Compare locks

mcprigor contract-diff old.lock.yaml new.lock.yaml
mcprigor contract-diff old.lock.yaml new.lock.yaml --markdown

Update a lock

mcprigor contract-update mcp.lock.yaml --target server.mcpr

Review the printed changes before committing the updated lock.

Record a session

mcprigor record --out draft.mcpr -- node dist/server.js

Proxies a live MCP stdio session: your client (an agent, MCP Inspector's CLI mode, or any harness) talks to mcprigor record on stdin/stdout, and Rigor forwards everything to the real server while logging each tools/call exchange. When the session ends it writes a reviewable .mcpr draft — one test per call, with deterministic assertions picked from the actual responses (up to three scalar structuredContent leaves, falling back to short text content). No AI: the draft is a literal transcription. Review it, prune it, and run it.

Multi-server compositions

Model the MCP fleet an agent mounts together without overloading parity environments:

MCP Test 1
Suite: "Checkout fleet"
Named server "catalog": node services/catalog.js
Named server "billing": https://qa.example.com/billing/mcp

Test: "catalog lookup"
  On server "catalog"
  Call tool "search" with:
    query: "widget"

Test: "billing health"
  On server "billing"
  Send "ping"

The YAML/JSON equivalent uses a top-level servers mapping and server on each test. The legacy target remains the default and existing suites are unchanged.

Composition governance:

mcprigor composition-check fleet.mcpr
mcprigor composition-discover fleet.mcpr --out mcp.composition.lock.yaml
mcprigor composition-drift fleet.mcpr --against mcp.composition.lock.yaml --fail-on breaking

The combined lock embeds each server's standard discovery contract, plus cross-server issues and a stable fleet fingerprint. Checks detect duplicate tool names, conflicting tool schemas, duplicate resource URIs/templates, duplicate prompts, server additions/removals, and per-server contract drift.

composition-drift --fail-on supports breaking (default), potentially-breaking, any, and none, matching the single-server drift gate.

Project environments

Define shared targets once in mcprigor.config.yaml (found in the working directory or any parent):

default: dev
environments:
  dev: node dist/server.js
  qa:
    url: https://qa.example.com/mcp
    token from: node scripts/get-token.mjs
  prod:
    url: https://api.example.com/mcp
    headers:
      Authorization: "Bearer ${env.PROD_TOKEN}"

Then select one per run:

mcprigor test suite.mcpr --env qa
mcprigor drift suite.mcpr --against mcp.lock.yaml --env prod

The selected environment replaces the suite's declared target and is announced in the output. With a default: set, plain mcprigor test suite.mcpr uses it automatically. --command/--url overrides still win over the environment when both are given. An environment value can be a command string, a URL string, or a mapping with server/cwd/env (stdio) or url/headers/token from (HTTP).

Deterministic security audit

Run the built-in security and permissions probe pack against a suite target:

mcprigor audit suite.mcpr --pdf security-audit.pdf --json security-audit.json
mcprigor audit --url https://qa.example.com/mcp --fail-on high

The default, non-destructive pack probes malformed JSON-RPC parameters, unknown/tool-name spoofing, oversized payloads, and path-traversal resource URIs. It also inventories every advertised tool for prompt-injection and secret-canary testing.

Tool calls are never guessed or executed by default. Explicitly allow only reviewed, non-destructive tools:

mcprigor audit suite.mcpr --allow-tool search --allow-tool summarize

Allowed tools receive a fixed prompt-injection string containing a deterministic canary. MCP Rigor checks whether the tool followed/reflected the payload or exposed the canary. The canary is redacted from report evidence.

Outputs:

Scoring deducts 35 for critical, 20 for high, 10 for medium, and 4 for low findings. Skipped probes do not affect the score and are shown with the exact opt-in needed.

Coverage gate

mcprigor coverage suite.mcpr --fail-under 80 --json coverage.json

Discovers the live MCP contract and reports untested tools, resources, resource templates, prompts, input properties, and enum/oneOf/anyOf branches. --fail-under accepts 0–100; --markdown produces a pull-request-friendly report. See Coverage.

Scheduled monitoring

mcprigor monitor prod.mcpr --every 15m --notify https://hooks.example/rigor

Runs an HTTP suite immediately and on a fixed interval, appends every result to trend history, and posts transition webhooks. --notify-on accepts change (default), failure, recovery, or always; --max-runs bounds cron/CI checks. See Scheduled monitoring.

GitHub Action

Use FusionOnePlatform/mcprigor@v1 to run suites, contract drift, flaky warnings, job summaries, and an update-in-place pull-request comment. See GitHub Action.

Shareable hosted reports

mcprigor publish suite.mcpr --site your-netlify-site
mcprigor publish suite.mcpr --out reports/latest

Runs the suite and hosts the HTML report (with the session timeline) at a shareable static URL, or writes a local bundle for any static host. The hosting token comes only from NETLIFY_AUTH_TOKEN. See Shareable hosted reports.

Latency budgets and regression gate

mcprigor test suite.mcpr --fail-on-regression

Export reports (PDF, CSV, JUnit)

Every run can be exported in machine- and human-friendly formats:

mcprigor test suite.mcpr --pdf report.pdf --csv report.csv --junit report.xml

Historical trends come from recorded run history (.mcprigor/workspace-history.jsonl):

mcprigor trends --pdf trends.pdf          # per-suite run timelines + per-test pass-rate bars
mcprigor trends --csv trends.csv          # per-test aggregates (pass rate, avg duration)
mcprigor trends --csv history.raw.csv     # a *.raw.csv name exports raw per-run rows instead
mcprigor trends suite.mcpr --window 100   # limit to one suite / recent runs

The QA workspace has the same exports as buttons: PDF / CSV / JUnit XML above run results, and PDF / CSV / Raw history CSV on the Trends tab.

Drift gate and flakiness

CI gate for contract drift:

mcprigor drift suite.mcpr --against mcp.lock.yaml --fail-on breaking

Compares the lock file against the live server the suite declares and classifies every change as breaking, potentially breaking, or non-breaking. --fail-on controls the gate: breaking (default), potentially-breaking, any, or none (report only). --json out.json writes the structured diff; --markdown renders for PR comments. In GitHub Actions each change becomes an ::error/::warning/::notice annotation automatically.

Detect flaky tests from recorded run history:

mcprigor flaky [DIRECTORY] [--window 200] [--json out.json]

A test is flaky when its pass/fail outcome flips between runs of the same suite. CLI runs, the QA workspace, and mcprigor serve all record history under .mcprigor/workspace-history.jsonl. Exit code 1 when flaky tests are found. Pair with:

mcprigor test suite.mcpr --retries 2      # retry failures up to 2 times
mcprigor test suite.mcpr --quarantine     # skip tests listed in .mcprigor/quarantine.txt

Quarantine file format: one suite.mcpr :: test name per line, # comments allowed. Tests that pass only on retry are marked retried in JSON reports so hidden flakiness stays visible.

Evidence

mcprigor evidence-show .mcprigor/run-001
mcprigor evidence-compare .mcprigor/run-001 .mcprigor/run-002

Snapshots and replay

mcprigor snapshot-diff old.json new.json
mcprigor replay .mcprigor/run-001/trace.normalized.jsonl \
  --target server.mcpr

Tool calls are denied during replay unless explicitly approved:

mcprigor replay trace.normalized.jsonl \
  --target server.mcpr \
  --allow-tool find_customer

--allow-tool may be repeated.

Exit codes

CodeMeaning
0Success
1Test, snapshot, parity, replay, or breaking-drift failure
2Invalid usage, language, or configuration
3Server, transport, extension, or internal failure
130Interrupted by the user

Safety flags

--allow-remote-data and --allow-custom-code are intentionally explicit. Do not add them automatically in shared scripts. Review the source and required permissions first.