Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

RaptorProto

Autonomous SEO audit engine with AI-driven analysis.

RaptorProto is a proof of concept for a fully autonomous SEO pipeline: crawl any website, render JavaScript-heavy pages via Cloudflare Browser Rendering, and feed structured audit data directly to Claude for intelligent analysis, recommendations, and ongoing monitoring -- all orchestrated through a REST API and MCP (Model Context Protocol) integration.

Built by Nick Mangubat, founder of Ravana Solutions, a Norfolk, Virginia web design and SEO studio. This prototype grew into Raptor, the audit toolkit behind every Ravana engagement — read the full story in the Raptor case study.

 ┌─────────────────────────────────────────────────────────────────┐
│ │
│ Website ──► Raptor Crawler ──► Structured SEO Data │
│ │ │ │
│ Cloudflare Browser │ │
│ Rendering (JS/SPA) ▼ │
│ Claude API / MCP │
│ │ │ │
│ REST API MCP Server │
│ (direct) (agentic) │
│ │ │ │
│ Prioritized Autonomous │
│ Fix Plans Monitoring │
│ │
└─────────────────────────────────────────────────────────────────┘

Table of Contents


What This Proves

  1. A Rust-native crawler can produce structured, machine-readable SEO audit data at scale. 114+ analyzers, health scoring, and multi-format reports -- all in seconds, not minutes.

  2. Cloudflare Browser Rendering closes the SPA gap. JS-heavy sites that return empty shells to traditional crawlers are fully rendered before analysis. Screenshots, entity extraction, and static-vs-rendered comparisons come free.

  3. The output is purpose-built for AI consumption. Raptor's structured JSON is designed to be fed directly into Claude via REST API for on-demand analysis, or exposed as an MCP server for agentic workflows where Claude autonomously crawls, analyzes, and acts.


The Crawler

The core engine is written in Rust using async I/O (tokio) for high-throughput concurrent crawling.

How It Works

Seed URL
│
▼
┌──────────────────────────────────────────────────┐
│ Crawl Queue (BFS, depth-bounded) │
│ ┌──────────┐ ┌───────────┐ ┌───────────────┐ │
│ │ Fetcher │ │ Parser │ │ URL Resolver │ │
│ │ (reqwest │──│ (scraper │──│ (normalize, │ │
│ │ async) │ │ HTML) │ │ dedup, scope)│ │
│ └──────────┘ └───────────┘ └───────────────┘ │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Analysis Pipeline (114+ checks) │
│ │
│ Technical On-Page Structured Data │
│ ───────── ──────── ─────────────── │
│ Canonicals Titles JSON-LD │
│ Directives Meta desc Microdata │
│ Status codes Headings Open Graph │
│ Security Content │
│ URL issues Images Links & Hreflang │
│ Sitemaps Readability Internal/External │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Scoring Engine │
│ 100-point scale, per-issue deductions with caps │
│ Grades: A (90+), B (80+), C (70+), D (60+), F │
└──────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────┐
│ Report Generation │
│ │
│ JSON ─── machine-readable, Claude-ready │
│ HTML ─── self-contained, offline-capable │
│ CSV ─── spreadsheet export │
│ SVG ─── site structure visualization │
└──────────────────────────────────────────────────┘

Key Capabilities

FeatureDetail
Async concurrent crawlingConfigurable concurrency (default 3), semaphore-bounded
robots.txt complianceHonors rules, crawl-delay, disallow patterns
Sitemap discoveryParses sitemap.xml/sitemap index for URL seeding
Depth + page limitsConfigurable max depth (10) and max pages (500)
114+ SEO analyzersTitles, meta, headings, images, links, structured data, security headers, canonicals, hreflang, content quality
Health scoring0-100 scale with per-issue weighted deductions and category caps
Self-contained HTML reportsSingle file, zero external dependencies, works offline
Event-driven architectureCrawlEvent channel decouples engine from UI -- reusable as a library

Example

raptor crawl https://example.com --max-pages 100 --concurrency 5
# Output:# JSON crawl-example.com-2026-04-09.json (structured audit data)# HTML crawl-example.com-2026-04-09.html (visual report)

Cloudflare Browser Rendering

Modern SPAs (React, Vue, Angular, Next.js) return skeleton HTML to crawlers. The real content only exists after JavaScript executes. Raptor integrates Cloudflare Browser Rendering to close this gap -- entirely optional, zero local dependencies.

Capabilities

CommandWhat It Does
raptor crawl --backend cloudflareFull JS-rendered crawl -- pages loaded in headless Chromium on Cloudflare's edge, then analyzed by all 114+ checks
raptor screenshot <url>Pixel-perfect full-page captures at any viewport size
raptor inspect <url> --compareSide-by-side static vs. JS-rendered audit -- reveals content invisible to traditional crawlers
raptor extract <url> --preset seoAI-powered entity extraction (business name, phone, address, services, hours) using Workers AI

How the Hybrid Crawl Works

 ┌──────────────────────────────┐
│ Raptor submits seed URL to │
│ CF /crawl endpoint │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Cloudflare renders pages in │
│ headless Chromium (JS runs) │
│ Discovers + follows links │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Raptor retrieves rendered │
│ HTML via cursor pagination │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Parallel security header │
│ fetch (HSTS, CSP, XFO) │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Same 114+ analyzers run on │
│ rendered HTML. Same reports. │
└──────────────────────────────┘

Static vs. Rendered Comparison

The inspect --compare command demonstrates why this matters:

 ┌────────────────────┬──────────────┬──────────────┐
│ Check │ Static │ Rendered │
├────────────────────┼──────────────┼──────────────┤
│ Title │ (empty) │ My SPA App │
│ Meta description │ (empty) │ Welcome to… │
│ H1 count │ 0 │ 1 │
│ Word count │ 12 │ 847 │
└────────────────────┴──────────────┴──────────────┘

A traditional crawler sees 12 words. Cloudflare rendering reveals 847. That gap is exactly what search engines penalize, and exactly what Raptor surfaces.

Free Tier

Cloudflare's free plan includes 10 minutes of browser time per day -- enough for 100-200 pages per crawl session. No credit card required.


Claude Integration: REST API + MCP

This is where Raptor becomes more than a crawler. The structured JSON output is designed to be consumed directly by Claude for AI-driven SEO analysis.

Approach 1: REST API (Direct Analysis)

Raptor's JSON output feeds directly into the Claude API (Anthropic REST) for on-demand, intelligent analysis that goes far beyond rule-based checks.

┌─────────────┐ ┌──────────────────┐ ┌──────────────┐
│ raptor │ │ Orchestrator │ │ Claude API │
│ crawl │──────►│ (service layer) │──────►│ (Anthropic) │
│ --json │ JSON │ │ REST │ │
└─────────────┘ │ Sends crawl │ │ Returns: │
│ data + prompt │ │ - Analysis │
│ template │◄──────│ - Fix plan │
└──────────────────┘ │ - Priority │
└──────────────┘

What Claude adds on top of Raptor's raw audit:

Raptor ProducesClaude Interprets
"47 images missing alt text""The product gallery on /shop uses decorative images that don't need alt text, but 12 hero images on landing pages are missing descriptive alt -- those are the priority."
"Health score: 72 (C)""The score is dragged down by 3 redirect chains on your highest-traffic pages. Fixing those alone would push you to B+."
"Missing meta descriptions on 23 pages""These 23 pages share a /blog/draft URL pattern -- they may be unpublished drafts indexed by mistake. Verify they should be public before writing descriptions."
"Duplicate title tags on 8 pages""All 8 are paginated category pages (/shoes?page=2, /shoes?page=3). Append the page number to each title to differentiate them."

Implementation pattern:

// Raptor outputs structured JSONlet crawl_result:CrawlResult = raptor_core::crawler::crawl(config, tx).await?;let json = serde_json::to_string(&crawl_result)?;// Feed into Claude API with a domain-specific promptlet response = anthropic_client
.messages().create(MessageRequest{model:"claude-sonnet-4-20250514",messages:vec![Message{
role:"user",
content: format!("Analyze this SEO audit and produce a prioritized action plan. \ Focus on fixes with the highest traffic impact first.\n\n{}",
json
),}],max_tokens:4096,}).await?;

Approach 2: MCP Server (Agentic Workflows)

The more powerful pattern: expose Raptor as an MCP (Model Context Protocol) server, giving Claude direct access to crawl, inspect, and extract as tools it can invoke autonomously.

┌───────────────────────────────────────────────────────┐
│ Claude (MCP Client) │
│ │
│ "Audit example.com, then check if the top 3 issues │
│ are also present on their staging site." │
│ │
│ Tool calls: │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. raptor_crawl(url: "example.com") │ │
│ │ 2. raptor_inspect(url: "staging.example.com", │ │
│ │ compare: true) │ │
│ │ 3. raptor_extract(url: "example.com/contact", │ │
│ │ preset: "seo") │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ Claude reasons over the combined results and │
│ produces a unified analysis without human prompting. │
└───────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ Raptor MCP Server │
│ │
│ Tools exposed: │
│ ───────────── │
│ raptor_crawl Full site crawl → JSON │
│ raptor_inspect Single-page audit (3 modes) │
│ raptor_screenshot Full-page capture → image │
│ raptor_extract Entity extraction → JSON │
│ raptor_compare Diff two crawl snapshots │
│ │
│ Resources exposed: │
│ ───────────────── │
│ Recent crawl results (read-only) │
│ Issue category definitions │
│ Scoring algorithm reference │
│ │
│ Transport: stdio or SSE │
└─────────────────────────────────────────────────────┘

MCP unlocks agentic workflows like:

WorkflowWhat Happens
Competitive audit"Compare our site against 3 competitors" -- Claude crawls all 4, cross-references scores, identifies gaps
Regression monitoring"Crawl weekly and alert if score drops" -- Claude diffs snapshots, flags regressions, explains root cause
SPA pre-launch check"Verify the React app is crawlable" -- Claude runs inspect --compare, checks for content gaps between static and rendered
Local SEO extraction"Pull business data from these 50 competitor pages" -- Claude calls extract in a loop, normalizes results into a spreadsheet
Fix verification"Re-crawl after deploy and confirm issues are resolved" -- Claude compares before/after, confirms fixes, flags new issues

MCP server definition (planned):

{
"mcpServers": {
"raptor": {
"command": "raptor",
"args": ["mcp-server"],
"env": {
"CLOUDFLARE_ACCOUNT_ID": "...",
"CLOUDFLARE_API_TOKEN": "..."
}
}
}
}

Architecture

RaptorProto/
├── raptor-core/ Core Rust library (zero CLI coupling)
│ └── src/
│ ├── crawler/ Async fetcher, parser, queue, robots.txt, sitemaps
│ ├── analysis/ 114+ SEO analyzers + scoring engine
│ ├── cloudflare/ CF Browser Rendering client (crawl, screenshot, inspect, extract)
│ ├── report/ JSON, HTML, CSV, SVG report generators
│ ├── models/ CrawlConfig, CrawlResult, PageData, CrawlEvent
│ └── utils/ Readability scoring, text analysis
│
├── raptor-cli/ CLI binary (clap-based, dispatches to core)
│ └── src/main.rs Dashboard, subcommands, progress bars
│
├── templates/ Minijinja HTML templates (compiled into binary)
│ ├── crawl-report.html Full report with sidebar, tabs, charts
│ ├── components/ Overview, Issues, Pages, Structure tabs
│ ├── styles/ Light theme CSS
│ └── mascot.svg Raptor mascot (mood changes with score)
│
├── python/ Companion analysis tools
│ ├── raptor-entity/ NER + Semantic Density Index (spaCy)
│ ├── raptor-link/ Internal link graph visualization
│ ├── raptor-fossil/ Historical SERP tracking (Wayback Machine)
│ └── raptor-common/ Shared console styling
│
└── docs/
└── cloudflare.md Cloudflare integration setup guide

Design Principles

  • Library-first.raptor-core is a standalone Rust library with no CLI coupling. It communicates via CrawlEvent channels, making it embeddable in any service -- including an MCP server.
  • Structured output. Every crawl produces machine-readable JSON following a consistent schema. This is what makes the Claude integration viable without any data transformation layer.
  • Cloudflare is optional. The core crawler, all 114 analyzers, scoring, and reporting work without it. CF integration is behind a Cargo feature flag (cloudflare, enabled by default).
  • Self-contained reports. HTML reports are single files with all CSS, JS, and SVG inlined. No CDN. Works offline.
  • Responsible crawling. Honors robots.txt, polite delays, exponential backoff, rate limiting by default.

Current Status

ComponentStatus
Rust crawler engineProduction-ready (v0.2.0)
114+ SEO analyzersComplete
Health scoring + gradingComplete
HTML/JSON/CSV/SVG reportsComplete
Cloudflare Browser RenderingComplete (crawl, screenshot, inspect, extract)
Python NER/link/fossil toolsComplete
Claude REST API integrationDesigned, ready to implement
MCP serverDesigned, ready to implement

Getting Started

Prerequisites

  • Rust 1.70+ (for building from source)
  • Python 3.10+ (for entity, link, and fossil analysis tools)
  • Cloudflare account (free tier, optional -- only for JS rendering features)

Build

git clone <repo-url> RaptorProto
cd RaptorProto
cargo build --release

Run

# Crawl a site
./target/release/raptor crawl https://example.com
# JS-rendered crawl (requires Cloudflare credentials)export CLOUDFLARE_ACCOUNT_ID="your-id"export CLOUDFLARE_API_TOKEN="your-token"
./target/release/raptor crawl https://example.com --backend cloudflare
# Single-page audit: static vs rendered comparison
./target/release/raptor inspect https://example.com --compare
# Screenshot
./target/release/raptor screenshot https://example.com
# Entity extraction
./target/release/raptor extract https://example.com --preset seo

License

MIT

About

Autonomous SEO audit engine with AI-driven analysis — Rust crawler, Cloudflare Browser Rendering, Claude REST API + MCP integration

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages