Live website auditor for accessibility, TLS, cookies, and security headers
inspect is a Go library that crawls live websites and audits the pages it finds — broken links, security headers, forms, accessibility, performance, SEO, TLS, cookies, mixed content, subresource integrity, AI-readiness, and reachability. It is part of the hawk ecosystem: hawk wires inspect into its own commands, and inspect also ships an MCP server so any MCP-compatible agent can run audits.
inspect is a Go library (and MCP server), not a CLI. It ships no
inspectbinary of its own — it analyzes running URLs, not source code. Import it directly to embed website auditing in your own Go program, or run the MCP server to expose it to an agent.
It crawls concurrently (with rate limiting, robots.txt support, redirect handling, and SSRF protection), runs each check against the discovered pages, and returns findings with severity levels. Results can be emitted as SARIF for the GitHub Security tab.
import (
"context"
"fmt"
"github.com/GrayCodeAI/inspect"
)
// One-shot scan with the Standard preset.
report, err := inspect.Scan(ctx, "https://example.com", inspect.Standard)
if err != nil {
// handle error
}
for _, f := range report.Findings {
fmt.Printf("[%s] %s: %s\n", f.Severity, f.URL, f.Message)
}Requires Go 1.26+.
For repeated or high-throughput scans, reuse a Scanner (safe for concurrent use):
scanner := inspect.NewScanner(inspect.Standard, inspect.WithDepth(3))
r1, _ := scanner.Scan(ctx, "https://site-a.com")
r2, _ := scanner.Scan(ctx, "https://site-b.com")inspect ships nine built-in checks (registered in check.DefaultRegistry). The
six marked (default) run in the Standard, Deep, and CI presets; the
remaining three are opt-in via WithChecks.
- Links (default) — crawls and reports broken/unreachable links
- Security headers (default) — detects missing CSP, HSTS, and related
headers; also audits TLS certificate validity/expiry, cookie
Secure/HttpOnly/SameSiteflags, and mixed content on HTTPS pages - Forms (default) — form validation checks (CSRF, action URLs)
- Accessibility (
a11y) (default) — meta/ARIA checks; optional axe-core and color-contrast analysis through thebrowsersub-module (headless Chromium via rod) - Performance (
perf) (default) — resource sizes and render-blocking resources - SEO (default) — meta tags, structured data, and metadata checks
- SRI — Subresource Integrity validation
- AI-ready (
aiready) — checks for agent/LLM-friendly metadata - Reachability — host/URL reachability checks
- Concurrent crawler — depth limits, rate limiting, robots.txt, redirect following, and SSRF protection (private IPs blocked by default)
- SARIF output —
inspect.GenerateSARIFemits SARIF 2.1.0 for the GitHub Security tab - MCP server — expose
inspect_scanandinspect_scan_dirto any agent - Extensible — register custom
Checkerimplementations or declarativeRuleCheckpatterns
The default checks are: links, security, forms, a11y, perf, seo.
Add the opt-in checks (sri, aiready, reachability) with WithChecks.
| Preset | Behavior |
|---|---|
Quick |
Shallow crawl (depth 2), links only |
Standard |
Balanced crawl (depth 5), the six default checks |
Deep |
Exhaustive crawl (no depth limit), the six default checks |
SecurityOnly |
Security-related checks only |
CI |
Default checks, fail on high severity |
inspect ships an MCP server (stdio transport) that exposes website auditing to any MCP-compatible agent:
import inspectmcp "github.com/GrayCodeAI/inspect/mcp"
srv := inspectmcp.New(inspect.Standard)
if err := srv.ServeStdio(); err != nil {
// handle error
}Tools:
inspect_scan— crawl a URL and run the configured checksinspect_scan_dir— serve and scan a local directory of HTML files
By default inspect analyzes raw HTTP responses. To analyze JavaScript-rendered
pages and run axe-core accessibility checks, supply a BrowserEngine from the
browser sub-module:
import "github.com/GrayCodeAI/inspect/browser"
engine, err := browser.New()
if err != nil {
// handle error
}
defer engine.Close()
report, err := inspect.Scan(ctx, "https://example.com",
inspect.Standard,
inspect.WithBrowser(engine),
)// Declarative rule — no Go code beyond the struct.
inspect.RegisterRule(inspect.RuleCheck{
RuleName: "x-frame-options",
RuleSeverity: inspect.SeverityHigh,
HeaderMissing: []string{"X-Frame-Options"},
})
// Full Checker implementation, scoped to a single Scanner.
scanner := inspect.NewScanner(inspect.WithCustomChecks(myCheck))See the examples/ directory for runnable code samples.
See docs/architecture.md for the package layout and data flow.
inspect is part of the hawk ecosystem:
| Component | Repository | Purpose |
|---|---|---|
| hawk | GrayCodeAI/hawk | AI coding agent |
| eyrie | GrayCodeAI/eyrie | LLM provider runtime |
| yaad | GrayCodeAI/yaad | Graph-based memory |
| inspect | This repo | Website audit library + MCP server |
Contributions are welcome — please read CONTRIBUTING.md before opening a pull request.
MIT - see LICENSE for details.