A report you'd send to a client

Every crawl writes one HTML file: the grade and why, what to fix first in plain words, and every page each problem is on. It loads nothing from the network, so it's safe to email. This is the real one from the Fernhollow crawl. Take the tour, or just use it.

crawl-127.0.0.1-2026-10-17.htmlOpen in a new tab

1 of 9The answer first

The grade, the score and its name, then one sentence on what costs the most: a page that returns 404 and a canonical that points at it, about 3.7 points each. The counts follow: 13 findings to fix on 12 pages, 4 notes, 94 checks passed.

The file Raptor 0.3.0 wrote on 17 Oct 2026 for Fernhollow Outdoor, a test shop built for this site, unchanged apart from its name. It follows this site’s light or dark theme. Everything in it works here as it would on your machine, from the filters to the exports.

Hand a fix to whoever does it

A finding leaves the report as a task, a list or a spreadsheet, so the person who fixes it never needs the report open.

Copy fix brief

One finding as a short Markdown task, ready to paste into Claude Code, a ticket or an email: what was found, where, why it matters, how to fix it, and up to 25 affected addresses with the true total. Copy all fixes puts every finding to fix in one brief, most important first.

It’s the same text, byte for byte, that raptor_findings returns over MCP for that check, so a fix reads the same in the report and in Claude’s hands.

What Copy fix brief put on the clipboard, from the third Fix first card
## 1 page both allows and blocks listing in search results

`directives.conflicting_directives` · Fix now · 1 page

**What we found:** These pages give robots rules (instructions for search engines) in both a meta tag and an X-Robots-Tag header, and together the two say both index (list this page) and noindex (do not list it).

**Why it matters:** Search engines obey the stricter rule, so these pages are likely to be left out of search results.

**How to fix:** Make the robots meta tag in the page template and the X-Robots-Tag header in the server settings agree. Remove noindex from both on any page you want in search results.

**Example:** "Waterproof Jackets and Trousers | Fernhollow" http://127.0.0.1:8006/waterproofs/
> Meta robots: [index, follow], X-Robots-Tag: noindex

**Affected pages (1):**
- http://127.0.0.1:8006/waterproofs/ — Meta robots: [index, follow], X-Robots-Tag: noindex

Copy URLs and Download CSV

Every affected address of one finding, for whichever folder you’re looking at, with the page title, folder and the detail Raptor measured. The lists are complete: the report holds every crawled page.

A cell that would start a spreadsheet formula, with =, +, - or @, gets a leading apostrophe, so a hostile page title can’t run as a formula when your client opens the file.

sitemaps.non_indexable_in_sitemap.csv, as Download CSV saved it
url,page_title,directory,detail
http://127.0.0.1:8006/products/storm-shell,,/products/,Non-indexable (status 404) in http://127.0.0.1:8006/sitemap.xml
http://127.0.0.1:8006/waterproofs/,Waterproof Jackets and Trousers | Fernhollow,/waterproofs/,Non-indexable (noindex) in http://127.0.0.1:8006/sitemap.xml

Your agency's name on it

Put your name, logo, colour and contact line on every report with one small file. The crawls the REST API and the MCP server run use it too.

The same report with Kestrel Bay Digital's logo, name and rust accentThe same report with Kestrel Bay Digital's logo, name and rust accent

The same crawl twice, captured from the two files Raptor wrote. Kestrel Bay Digital is fictional, the agency from Raptor’s own canonical-variants test site, and its .example addresses reach no one.

brand.toml
# Kestrel Bay Digital is fictional. .example addresses reach no one.
agency_name  = "Kestrel Bay Digital"
logo         = "logo.svg"
accent       = "#8A3B12"
accent_dark  = "#F0A877"
contact_line = "Questions about this audit? audits@kestrelbay.example"
contact_url  = "https://kestrelbay.example/contact"
voice        = "raptor"
mascot       = true
Or put it in ~/.raptor/brand.toml
$ raptor crawl https://example.com/ --brand brand.toml

What your colour changes

Links, the main button and the keyboard focus ring. The green that marks a passing check or a healthy score stays Raptor’s, so it means the same in every report. Each theme is checked on its own: an accent that can’t reach 4.5:1 contrast, the WCAG level for text, keeps Raptor green on that theme.

What stays

“Made with Raptor” and the small Raptor mark in the footer. The panels Claude shows in a conversation keep Raptor’s look too, because the apps that host them don’t allow logo headers; they follow your voice and mascot settings.

The branded report's footer: Kestrel Bay Digital's contact line and Made with RaptorThe branded report's footer: Kestrel Bay Digital's contact line and Made with Raptor

A wrong file stops the crawl, before a single page

A report with half a client’s brand on it is worse than none, so Raptor checks the file first and names the key. It reads an SVG logo the way a browser would and refuses one that could run code or load anything. Only a colour too faint to read is a warning. Three real runs:

error: ./not-a-colour.toml: accent: "green" is not a #RRGGBB colourexit 1, nothing crawled
error: ./script-logo.toml: logo: ./script-logo.svg has an inline onload handlerexit 1, nothing crawled
warning: brand.toml: #C8E6C9 reaches only 1.21:1 against the light background #F6F3ED, below the 4.5:1 text needs, so the light theme uses Raptor greenexit 0, the crawl carries on

Save as PDF from your browser and the report lays itself out for paper: the header, the grade, Fix first in full, one line for every other finding and note, the crawl's limits and the footer. Buttons, filters, Pages and Structure stay on screen, and it always prints light, whatever theme you read it in.

Page 1 of 4 of the printed reportPage 2 of 4 of the printed reportPage 3 of 4 of the printed reportPage 4 of 4 of the printed report

The Fernhollow report printed from Chromium to A4, with the browser in dark mode and background graphics off, the print dialog’s default. Open the PDF (214 KB, 4 pages).

One file, and it calls no one

The fonts and the data are inside the file. It works offline, it's safe to attach to an email, and opening it tells no one you did.

Every request the report made

We opened it in Chromium, let it settle, scrolled it, and logged every request. This is the whole list.

MethodAddressStatusType
GET/demo/reports/fernhollow.html200the file itself

Its own security policy

The report carries a Content-Security-Policy that lets only its own two scripts run and loads nothing from the network, so text copied from a crawled page can never act as code. A report downloaded from the REST API gets a stricter one that blocks scripts too; the first screen and every finding still read in full.

The report's <meta http-equiv="Content-Security-Policy">, one directive a line
default-src 'none';
script-src 'sha256-4PatMwXmpHr31ooiuGeXbc3xb7zd7wlgFqf6+Kfwy10=' 'sha256-w+3dmaR8qGcUS6OVS489CObhy707AeHB/1DpR833fFA=';
style-src 'unsafe-inline';
img-src data:;
font-src data:;
base-uri 'none';
form-action 'none'

Every page, at any size

The report holds every crawled page, with nothing left out, so a finding’s affected pages are always complete and the exports are exact. Only the per-page details are capped, at 100 per finding, and the report says when.

Raptor’s docs put a 20,000-page report at about 6 MB, up to about 9 MB when nearly every page has findings. It opens in well under a second, because the Pages table only builds the rows you can see. This one is 320 KB for 27 pages.

How the report works, in full

Write one for your own site

Raptor builds from source for now. Then one command writes the report beside the crawl's JSON, named for the site and the day.

Shell
$ raptor crawl https://example.com/

That writes crawl-example.com-<date>.html. Or ask Claude to crawl it and read you the findings, with Raptor’s MCP server.