Every command is raptor <command>. Run raptor <command> --help for the exact flag list; this
document explains what each command does and how it works, which the help text does not.
| Command | Needs network | Input | Purpose |
|---|---|---|---|
crawl | yes | a URL | Crawl a site and analyse it |
link | no | crawl.json | Internal link graph: PageRank, orphans, hubs, silos |
sitemap | no | crawl.json | XML sitemap of the indexable pages |
inspect | yes | a URL | Single-page audit, no crawl needed |
serve | yes | — | REST API and/or MCP server |
screenshot | yes | a URL | Full-page screenshot (Cloudflare feature) |
extract | yes | a URL | AI structured extraction (Cloudflare feature) |
setup | no | — | Store integration credentials |
version | no | — | The version and the features this build has |
Run raptor on its own in a terminal for the home screen: the commands to start with and your
recent crawls.
Output: rich, plain and JSON
Raptor prints for whoever is reading. In an interactive terminal window (a "TTY") you get the
rich layout: colour, a live progress region while the crawl runs, and a summary that leads with
the grade and what to fix first. Through a pipe (raptor crawl … | tee log.txt), in CI, or when an
AI agent runs it, you get the plain layout: one key: value fact per line, no colour, no
progress animation, full URLs and absolute file paths, with the verdict first and the files last.
--json prints a small JSON summary instead, for scripts and agents that parse output.
Progress and logs always go to stderr, and results to stdout, so raptor crawl … > summary.txt
captures the summary while the progress stays on screen.
Each output stream decides on its own, in this order (the first rule that applies wins):
| Order | Setting | Effect |
|---|---|---|
| 1 | --json (crawl and inspect) | stdout prints the JSON summary |
| 2 | --format rich or --format plain | that layout |
| 3 | --color always, FORCE_COLOR set, or CLICOLOR_FORCE set (not 0) | rich, in colour |
| 4 | An AI agent is detected (below) | plain |
| 5 | The stream is a TTY and TERM is not dumb | rich |
| 6 | Otherwise | plain |
Colour in the rich layout follows the usual standards: --color always|never first, then
NO_COLOR (set to anything turns colour off), FORCE_COLOR, and CLICOLOR=0. NO_COLOR on its
own keeps the rich layout, just without colour. Plain and JSON output never carry colour or
terminal control codes.
An AI agent is detected when CLAUDE_CODE_CHILD_SESSION=1, when CLAUDECODE=1 and stdout is
not a TTY (an IDE terminal sets CLAUDECODE=1 on a real terminal, where a person reads), or when
AI_AGENT, AGENT or CURSOR_AGENT is set. An agent gets plain output even on a terminal.
--format goes after crawl or inspect (raptor crawl https://example.com --format plain), or
before any subcommand (raptor --format plain link crawl.json). raptor screenshot --format is
still the image format, png or jpeg.
-q (--quiet) prints only errors: no progress, no summary and no log warnings, though a crawl
that has nothing to grade still names its cause on stderr; the files are still written. -v adds
a line per page and Raptor's own debug log; -vv logs every library. --color, -q and -v
work before or after any subcommand.
Exit codes
An exit code is the number a command hands back to the shell or CI when it ends; 0 means
success. Every Raptor command uses the same table:
| Code | Meaning |
|---|---|
0 | it worked (findings never fail a run on their own; stopping at --max-pages is still 0) |
1 | runtime error: an unwritable output path, a request that failed, a backend this build lacks, a brand file Raptor cannot use |
2 | usage error: an unknown flag or value, or a URL without https:// |
3 | nothing to grade: the start URL could not be reached, robots.txt disallows it, every page answered with an HTTP error, or the crawl ran but nothing could be graded (a bot wall, or an app shell with no readable content) |
4 | a quality gate failed (--min-score, --fail-on) |
130 | interrupted with Ctrl-C (what was crawled is saved) |
raptor crawl
raptor crawl https://example.com/ -o crawl.jsonCrawls a site breadth-first from the seed URL, then runs every analyser over the collected pages. This is the command the others consume.
How it works
The seed is resolved first. Before anything else, Raptor follows the seed's own redirect and
treats where it lands as the site under audit. Seeding https://www.example.com/ on a site that
canonicalises to the apex used to classify every discovered link as external and end the crawl
after one page — with a passing grade and no warning. The URL that finally served a page is that
page's identity throughout; the URL as requested is preserved in its redirect chain.
Scope is the seed's host and port. A link to a different host is external and is recorded but
not crawled. --follow-subdomains widens this to subdomains of the same registrable domain.
Scheme is deliberately not compared, so an http:// link on an HTTPS site is still internal.
Politeness is a single shared gate, not a per-worker sleep: --concurrency workers share one
--delay interval, so three workers with a 250 ms delay produce one request per 250 ms, not three.
robots.txt is fetched and honoured (RFC 9309), and a Crawl-delay larger than --delay wins.
A robots.txt that answers 5xx or 429 makes every path disallowed, as Google does (RFC 9309 says so
for 5xx only). A robots.txt that cannot be fetched at all (DNS, refused, TLS, timeout) does not
block the crawl: Raptor crawls without rules and lets the start page decide whether the site is
reachable. That is a deliberate departure from RFC 9309 §2.3.1.4, and Google treats an unreachable
robots.txt as blocking the whole site, so the robots line says so.
--ignore-robots exists and is labelled not recommended for good reason: it is for auditing
sites you control.
Budget. --max-pages is an exact upper bound, not approximate. --depth bounds distance from
the seed. A crawl that reaches --max-pages with URLs still waiting prints "Stopped at the page
limit" with how many it left behind, and the JSON records them as stopped_at_page_limit and
urls_not_crawled.
Safety. Crawl targets are checked against private, loopback, link-local and cloud-metadata
ranges to prevent SSRF, with the DNS resolution that is vetted being the one actually dialled.
Set RAPTOR_ALLOW_PRIVATE_TARGETS=1 to audit an intranet or a local fixture.
What it prints
In a terminal the crawl opens with a header (the /// mark, the URL and the settings on one quiet
line) and a live progress region: the phase, pages done and queued, a tally of answers by status,
the rate and the page in flight. Each finished phase collapses into one ✓ line with its time, and
robots.txt and fetch errors print as they happen (the first ten errors, then one line saying the
summary counts the rest).
The end of the run leads with the grade and the score, one sentence on where the points went, and
Fix first: the five most important things to fix, in plain words, each with how far it reaches,
the points it is costing, how to fix it, an example page and the stable check id (such as
links.broken_internal). Below that come the run's limits, any quality gates, the files written
and what to do next.
Piped, the same facts come one per line:
raptor 0.3.0 crawl https://example.com/
result: ok (exit 0)
crawl: Crawl complete: 125 pages in 31s.
headline: 83/100: Good. Here is what is holding the score back.
grade: B 83/100 (Good)
why: Render-blocking script on every page costs the most, about 5.7 points.
findings: 21 to fix, 2 notes; 96 checks passed
fix first:
1. High · javascript.js_render_blocking · 125 pages wait for a script before showing anything
reach: Every page — fix once; points: +5.7
fix: Add defer to the script tag (or async if no other script depends on it), …
example: https://example.com/ (https://example.com/assets/app.js)
…
next: Map internal links: raptor link /home/me/crawl-example.com-2026-10-17.json
files:
json: /home/me/crawl-example.com-2026-10-17.json
html: /home/me/crawl-example.com-2026-10-17.html--json prints the same summary as one line of JSON (pretty-printed in a terminal), with the schema
name raptor.crawl-summary/1: the result and exit code, the headline, the score, the counts, the
Fix first items with their copy, the limits, the gates, the next steps and the absolute paths of the
files. It never lists every affected URL, so it stays small on a large crawl; the full detail is in
the crawl JSON file.
Output files
By default writes the JSON and a self-contained HTML report beside it, sharing the stem of
--output: -o crawl.json produces crawl.json, crawl.html, and crawl.csv with --csv.
| Flag | Effect |
|---|---|
--no-html | JSON only — what you want when an agent or a script is the consumer |
--csv | Also write a CSV, one row per page |
--summary-only | Metadata, issues and summary; drops the per-page array |
--include-body-text | Include page text in the JSON (excluded by default; it dominates file size) |
--json-compact | Minified JSON |
--json | Print the JSON summary on stdout instead of text (the crawl JSON file is still written) |
The HTML report is genuinely self-contained: no CDN, no external fonts, nothing fetched when it is opened. It is safe to email to a client. The report embeds every crawled page; only per-URL detail strings are capped (100 per finding), and the report says so.
Branding
| Flag or variable | Effect |
|---|---|
--brand <FILE> | Put your agency's name, logo and colour on the HTML report, from a brand.toml. See report.md |
RAPTOR_BRAND | The path of a brand.toml to use when --brand is not given |
--no-brand | Use the plain Raptor brand, ignoring --brand, RAPTOR_BRAND and brand.toml in Raptor's home folder |
A brand file can also set the voice: with voice = "plain" the terminal's rich output speaks
plainly too.
Quality gates
Gates let CI fail a build when the site gets worse. A run with a failed gate still writes its files and exits 4.
| Flag | Fails the run when |
|---|---|
--min-score N | the score is below N (0 to 100) |
--fail-on PRIORITY | any finding is at that priority or more urgent: fix-now, high, medium or low |
Notes never fail a run (--fail-on note is refused). A crawl with nothing to grade exits 3 before
any gate is checked, so a blocked or unreachable site never passes by accident.
raptor crawl https://staging.example.com --json --min-score 80 --fail-on high > summary.jsonStopping a crawl
Press Ctrl-C once to stop: Raptor lets the requests already in flight finish, analyses the pages it has, writes the files and exits 130. The summary says the crawl was interrupted and gives the command that runs it again. What one press can stop depends on when it lands:
- while pages are still being fetched, the crawl stops there and keeps what it has;
- once every page is fetched, it skips the sitemap check (the summary says so, exit 130);
- during
--pagespeed, it skips the PageSpeed tests and saves the crawl as it is (exit 130); - while the crawl is analysed or saved, nothing is left to stop: the crawl is saved whole and the run ends with its usual result.
Press Ctrl-C a second time to quit at once without saving.
When a crawl cannot see the site
When Raptor gets nothing it can grade, the summary names the cause instead of a grade:
- the start URL could not be reached, and why: the name did not resolve (DNS), the secure connection failed (TLS), the connection was refused, it timed out, the connection closed before a response, or the address is private and blocked;
- robots.txt disallows the start URL, or robots.txt answered 5xx or 429, so every path is disallowed;
- every page Raptor fetched answered with an HTTP error, counted by status, as in
HTTP 403 on 1 of 1.
result: nothing to grade (exit 3)
failure: Could not reach https://example.com/: connection refused (…). Nothing was crawled.Only the JSON is written, because it records what failed. crawl_metadata.seed_error holds the
start URL's failure (url, kind such as dns, tls, timeout or refused, and detail), and
crawl_metadata.robots holds what robots.txt said. There is no HTML report and no CSV. If an
earlier run left them at the paths this run would have used, they are removed, and a
cleanup: Removed … line names each one, so an old report never sits beside a crawl that reached
nothing. The run exits 3. With -q the cause still prints, on stderr.
Rendering and Core Web Vitals
--backend playwright renders pages in local Chrome instead of fetching raw HTML — needed for
sites that inject their content, title or canonical client-side. Requires the playwright feature.
The release binaries are built without it, so build Raptor from source with
cargo build --release --features playwright to get it.
--pagespeed adds Core Web Vitals via the Google PageSpeed API (--pagespeed-key, or
PAGESPEED_API_KEY); --pagespeed-sample N limits it to N pages, since the API is rate-limited
and one call per page on a large crawl is slow.
raptor link
raptor link crawl.json # terminal summary
raptor link crawl.json --json # full report as JSONBuilds the internal link graph from a completed crawl and reports PageRank, orphan pages, hubs, silos and connected components. It performs no network I/O.
See link-graph.md for what each number means and how it is computed — that document is the one to read before acting on the output.
--top N bounds every ranked list (default 15). The report always carries the true totals
(orphan_page_count, silo_count) alongside the truncated lists.
raptor sitemap
raptor sitemap crawl.json -o sitemap.xmlWrites an XML sitemap containing the crawl's indexable pages: 2xx HTML that is not noindex.
A 404, a redirect, a PDF or a noindex page is excluded.
If nothing qualifies — or the crawl was run with --summary-only, so there is no page array to
read — it writes nothing and exits non-zero, saying which of the two applies. It will not produce
a schema-valid-looking empty <urlset>, which Search Console reads as an empty sitemap.
Above the 50,000-URL protocol limit it emits a <sitemapindex> plus chunk files rather than one
oversized file, which Google rejects whole.
raptor inspect
raptor inspect https://example.com/pricingAudits one URL and prints a single-page report: title, meta description, canonical, indexability with the directives that decided it, status, word count, readability, links, images, schema types, security headers, and the findings that apply to that page, most important first and in the same plain words as a crawl, with Notes last.
A page that answers with an error (a 404, say) is still inspected, and the report opens by saying
it is gone. A page that never answers exits 3, with the same message a crawl gives for an
unreachable start URL. --json prints a JSON summary (schema raptor.inspect-summary/1) instead of
text, and -o page.json still saves the full result, in its old shape.
Useful for checking one page quickly, and for confirming a finding from a crawl without re-running it. Inspecting a URL that redirects reports on the page that served it and still tells you about the redirect.
With the cloudflare feature: --rendered audits the JS-rendered DOM, and --compare shows
static vs rendered side by side — the fastest way to see what a crawler misses on a JS-heavy site.
raptor serve
raptor serve # REST API on 127.0.0.1:3001
raptor serve --mcp # MCP server over stdioSee mcp.md for the tools, the job lifecycle and the REST endpoints.
Two things worth knowing here:
- Auth is off unless you set a key.
--api-key, orRAPTOR_API_KEYin the environment. With no key, every route except/api/v1/healthis open to anything that can reach the port — which is why the default bind is127.0.0.1, not0.0.0.0. - Jobs are shared state. Every Raptor process on the same
RAPTOR_HOME(default~/.raptor) reads the same SQLite job store. Running an MCP server and a REST server at once is supported; jobs are owned and heartbeated, so one process no longer reclaims another's running work.
raptor screenshot
Full-page or element screenshots through Cloudflare Browser Rendering. Requires the cloudflare
feature and credentials. --full-page, --selector, --viewport WxH, --format png|jpeg.
raptor extract
AI structured extraction from a page through Cloudflare, with an SEO preset by default or your own
--prompt / --schema. Requires the cloudflare feature and credentials.
raptor setup
raptor setup cloudflareAsks for the account ID and token, checks them with Cloudflare, and writes them to
$RAPTOR_HOME/.env with 0600 permissions — not to the working directory, so they cannot be
committed by accident. It needs an interactive terminal; without one (in a script, or for an AI
agent) it exits 2 and says to put CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN in that file
instead.
raptor version
Prints the version and the optional features this build has, such as features: server.
raptor on its own
In a terminal, raptor with no command shows the home screen: the four commands to start with and
the last five crawls you ran, each with its grade, score, page count, how long ago it ran and the
path of its report. The list comes from $RAPTOR_HOME/history.jsonl, which every crawl adds a line
to. In a pipe or for an agent it prints the help instead.
Environment variables
| Variable | Purpose |
|---|---|
RAPTOR_HOME | Data directory (default ~/.raptor): job database, job output, credentials |
RAPTOR_API_KEY | Bearer token required by the REST API and MCP HTTP routes |
RAPTOR_ALLOW_PRIVATE_TARGETS | Allow crawling private/loopback addresses (intranet audits, local fixtures) |
RAPTOR_CORS_ORIGINS | Comma-separated CORS allowlist; CORS is closed by default |
RAPTOR_MAX_CONCURRENT_CRAWLS | Concurrent crawl cap for the server (default 3) |
CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_API_TOKEN | Cloudflare rendering credentials |
PAGESPEED_API_KEY | Google PageSpeed API key |
RAPTOR_BRAND | The brand.toml the HTML report uses when --brand is not given |
RUST_LOG | Log filter, which wins over -q and -v (for example RUST_LOG=raptor_core::crawler=debug). Without it a crawl logs warnings, -v adds Raptor's own debug lines and -vv every library's. In MCP mode logs go to stderr, never stdout |
NO_COLOR, FORCE_COLOR, CLICOLOR, CLICOLOR_FORCE | Colour standards; see Output |
CLAUDE_CODE_CHILD_SESSION, CLAUDECODE, AI_AGENT, AGENT, CURSOR_AGENT | Tell Raptor an AI agent is reading, which gets plain output; see Output |
COLORTERM | truecolor or 24bit paints the /// mark in Raptor's exact green |
COLORFGBG | A light background (…;15 or …;7) switches the mark to the darker green |