Docs / Agent & automation / CLI & CI

Guide Agent & automation

The CLI & CI pipeline

~10 min · headless · JSON · Free / Hunter Pro

The short version. Crusader is the same engine on the desktop and on the command line. Every verb prints JSON to stdout; errors go to stderr as error: <msg> with exit code 1. That makes every command pipe-safe — you can jq the output, gate a build on it, or hand it to an agent. Basic verbs (send, history, import, read-only sql) are Free; the full automation surface — active scanner, hunt, identity writes, mcp write tools — is Hunter Pro (FullCli). This page is the command catalog, four worked examples, and a scriptable scan-over-imported-traffic pipeline you can drop into CI.

01How the CLI behaves

There is one binary. A packaged install exposes it as crusader <verb>; from a source checkout the same thing is dotnet run --project .\CrusaderAvalonia.csproj -- <verb>. Start with the built-in catalog:

# list every verb and its subcommands
crusader cli help

# or, from a source checkout
dotnet run --project .\CrusaderAvalonia.csproj -- cli help

Three contracts hold for every command, which is what makes the CLI scriptable:

  • Output is JSON on stdout. One result object (or array) per invocation. Nothing decorative is written to stdout, so you can pipe straight into jq or a file.
  • Errors are on stderr, exit code 1. Failures print error: <msg> to stderr and return a non-zero status — so set -e, && chains, and CI step-failure all work the way you expect.
  • It shares the desktop workspace. The CLI reads and writes the same ~/.crusader workspace as the GUI (relocate it with CRUSADER_HOME). A capture from crusader send lands in the same History the app shows; an import from the CLI opens in the app.

Because stdout is pure JSON, a clean run is silent except for the result object. If a command prints nothing and exits non-zero, check stderr — that's where the error: line is.

02The command catalog

The verbs group by what they touch. The tables below cover the surface; crusader cli help (or crusader <verb> --help) is always the authoritative, version-matched reference. Tier notes call out where a verb's write/active path needs Hunter Pro.

Project & import

VerbWhat it does
projectList, create, and switch the active project (each project is its own history DB).
importLoad traffic from another tool — burp, har, saz, fiddler, caido, or scope (Burp Target Scope JSON). Free; never modifies the source file.
settingsRead and set workspace settings.
scopeView and edit the engagement's in/out-of-scope rules.
licensestatus / features / accounts / switch / activate <key> / trial / free.
updateCheck for and apply Crusader updates.

Capture & replay

VerbWhat it does
proxyserve the intercepting proxy (emits JSONL), plus status / install-ca / cert-path.
sendFire a one-off HTTP request and capture the exchange. The CLI's curl.
repeatersend <history-id> — re-issue a captured request.
intruderdetect / run — payload-driven fuzzing (Sniper Free; other modes Pro).
interceptDrive interception (Off / Watch / Hold) from the shell.
wsInspect captured WebSocket traffic.
pass-throughSingle probe, e.g. --url <url> --mode probe-url.
transportJA3 / curl-impersonate sidecar: install / status / start / stop / test (Pro).

Search & navigate

VerbWhat it does
historylist / search captured exchanges, with --sort and a direction flag.
sitemapThe endpoint tree; filters like --auth-gated / --idor / --mutating / --untested / --ghosts (smart flags Pro).
sqlRead-only SQLite over the project history DB — tables / schema / query.
comparecompare <id-a> <id-b> [--unified|--side-by-side].
dashboardProject overview / activity rollup.

Find & prove (Pro)

VerbWhat it does
scannerrun over captured History, findings to filter results, test <traffic.jsonl>. Passive is Free; active proof replay is Pro and needs a target scope.
findingslist / get / add / read — the unified findings store (export is Pro).
huntrun — replays captured History with saved identities for IDOR / access-control. Needs traffic + an identity. Not a URL probe.
idorcandidates / scan / explain — IDOR-specific helpers.
beaconOut-of-band callbacks: payload --kind http|dns|smtp [--purpose ...] and callback review (BYO Free; hosted Pro).
mtlsmTLS client-cert extraction workflow (Pro).
mobileMobile / Frida instrumentation workflow (Pro).

Identity, agent & extend

VerbWhat it does
identitylist / get / rename / use / active / create / delete / refresh / export-pfx / import-pfx (writes Pro).
agentguide / status / next / memory / plan / mcp-config / tools — the planner loop for coding agents.
mcpserve the MCP server (stdio JSON-RPC), tools to print the catalog (write tools Pro).
plugin / extpreview / install JavaScript plugins (community plugins Free; advanced APIs Pro).
llmprompt <history-id> — BYO-AI analysis of an exchange (Pro).

Decode & transform

VerbWhat it does
decoderEncode/decode: Auto, URL, HTML, Base64, Hex, JSON, Protobuf.
match-replace / mrRequest/response rewrite rules (Free capped at 10 active regex rules; unlimited Pro).
bodydecode / encode / history — request/response body helpers.
protobufdecode / encode protobuf payloads.
graphqlGraphQL request helpers.
headersHeader inspection / manipulation helpers.

03Worked examples

Each of these is copy-pasteable. They all write a JSON result to stdout, so the pattern is always the same: run it, pipe it, gate on it.

Send a request

send is the CLI's curl: it issues the request through the same stack the proxy uses and returns the full exchange as JSON. Use --no-history to keep one-off probes out of your capture log:

# authenticated GET; don't record it in History
crusader send GET https://target.example/api/me \
  -H 'Authorization: Bearer x' --no-history

Query History, sorted

history list and history search both take --sort = number|id|time|date|timestamp and a direction (--asc / --desc, or --direction asc|desc); the default is Number / Desc. Pipe the JSON into jq to reshape it:

# 20 most recent exchanges, newest first
crusader history list --sort number --desc --limit 20

# search a path, sort by capture time, pull a flat table with jq
crusader history search "/api/users" --sort date --desc --limit 20 \
  | jq -r '.[] | [.id, .method, .status, .url] | @tsv'

Run the scanner, get findings JSON

The scanner runs over already-captured History — it is not a crawler. Passive analysis is Free; active proof replay (Hunter Pro) needs a target scope set, or the run hard-fails. --json emits the findings as one object you can redirect:

# active scan over captured traffic for one host → findings.json
crusader scanner run --host target.com --json > findings.json

# passive-only run (Free) — no active proofs
crusader scanner run --host target.com --passive --json > findings.json

Run active scans and hunts only against systems you're authorized to test. The active scanner refuses out-of-scope hosts and private / loopback / link-local / cloud-metadata IPs at connect time — but scope authority is yours to set.

Replay traffic for IDOR with hunt

hunt run is access-control testing, not a URL probe: it replays the requests already in your History using your saved identities and compares what each actor can reach. It needs captured traffic plus at least one identity:

# list identities first — hunt needs at least one
crusader identity list

# replay History across identities for IDOR / access-control drift
crusader hunt run

04A CI scan pipeline

Because the CLI is headless and JSON-first, you can run a scan in CI over traffic you captured earlier. The shape that works well: capture once, export the traffic, then in CI import it into a fresh project, set scope, scan, and gate the build on the findings JSON. The scanner reads History, so the job's input is a traffic file, not a live crawl.

Step 1 — capture and export the traffic (once)

During an engagement, browse the target through Crusader's proxy so the requests land in History. Then export that History to a portable JSONL file — this is the artifact CI consumes. The scanner's test verb accepts a .jsonl / .jsonl.gz traffic file directly, so commit a sanitized capture (or publish it as a build artifact) for the pipeline to pick up.

Step 2 — the pipeline script

This script is the body of a CI job. It imports the captured traffic into a clean project, sets a target scope (required for the active scan), runs the scan to findings.json, and fails the build if any High/Critical finding is present. Every step is gated with && so a non-zero exit stops the job:

#!/usr/bin/env bash
set -euo pipefail

# 1. fresh project from the captured traffic artifact
crusader import har ./artifacts/target-traffic.har --name "ci-$(date +%F)"

# 2. scope is REQUIRED — an active scan hard-fails without it
crusader scope add "*.target.com"

# 3. scan over the imported History; JSON to a file
crusader scanner run --host target.com --json > findings.json

# 4. gate the build: fail if any HIGH or CRITICAL finding exists
crusader scanner findings --severity HIGH --json \
  | jq -e 'length == 0' > /dev/null \
  || { echo "High-severity findings — failing build" >&2; exit 1; }

Swap import har for import burp / saz / fiddler / caido depending on where your traffic came from. The scanner test ./artifacts/target-traffic.jsonl.gz verb is an alternative when you want to scan a traffic file without first importing it into a named project.

Active proof replay is Hunter Pro (FullCli + ActiveScanner); the CI runner needs an activated license (crusader license status tells you the tier in JSON). For a Free pipeline, add --passive to scanner run — passive analysis still produces findings JSON, just without active proofs, and doesn't require scope.

Step 3 — collect the results

The job leaves a machine-readable findings.json you can publish as an artifact, post to a tracker, or diff against the previous run. Findings carry severity, status, module, endpoint and (for confirmed active findings) a ProofPack reproduction. Note that report export — Markdown, SARIF, JSON, CSV, HackerOne / Jira — is Hunter Pro (Reporting); local findings stay available either way, but generating an exported report file is gated.

05Tiers & gotchas

The CLI never crashes on a gated call: invoking a Pro verb on Free returns a normal JSON result with "code": "requires_upgrade" (carrying the feature, required_tier, and a hint to run crusader license status) — not an exception. Design scripts to read that field rather than relying on a thrown error.

  • Free CLI: send, history, import, read-only sql, decoder / body / protobuf / graphql, compare, sitemap (no smart flags), passive scanner run --passive, BYO beacon, Sniper intruder, read-only mcp.
  • Hunter Pro CLI (FullCli): active scanner proof replay, hunt run, identity writes, mcp serve write tools, mtls, mobile, JA3 transport, report export, full intruder modes, unlimited match-and-replace.
  • Active scan needs scope. scanner run (active) hard-fails without a target scope. Set it with crusader scope add <pattern> first.
  • hunt run replays History, it does not probe a URL. No captured traffic or no saved identity means nothing to replay.
  • It's the same workspace. CLI and GUI share ~/.crusader (override with CRUSADER_HOME), so a CI runner and a desktop pointed at the same home see the same projects.

The 14-day Hunter Pro trial needs just an email (no card), and an active lease keeps an offline grace of 21 days — handy when the CLI runs on a headless CI box or VPS. crusader license status reports the current state as JSON.

Want a guide that isn't here yet? Email hello@crusaderproxy.com.