seo-audit — local & technical SEO audit toolkit
A two-layer audit engine. Measurement is deterministic (a Python CLI + 53
curated scripts). Judgment is where the model interprets those findings and
writes the plan. Both stay on your machine: no API keys for the core, no
third-party SaaS, no per-domain pricing.
Use this first
- Broad, then deep. Run
./seo audit <url> once, then drill into the
highest-impact findings. Starting with single commands optimises symptoms
instead of root causes.
- Setup first. If
./seo doctor reports an error, run ./setup.sh. Chromium
is workspace-local; occasional sandbox hangs are caught by a subprocess
timeout — just retry.
- Recommendations carry 4 fields. Observation → Dependency → Failure signal →
Early indicator. Field 2 sets the order, field 3 tells you how you'd know it
worked.
Command surface
| Command |
Measures |
./seo doctor |
Environment health check |
./seo audit <url> |
Full weighted verdict (specialists + sitemap + structure) |
./seo technical <url> |
Technical SEO (9 categories) |
./seo page <url> |
On-page: content, links, keyword signals |
./seo schema <url> |
JSON-LD / LocalBusiness detection + validation |
./seo local <url> |
Local / NAP consistency |
./seo visual <url> |
Render, hydration, console errors, load time (lab) |
./seo sitemap <url> |
Sitemap discovery + validation |
./seo content <url|file> |
QRG-style content-quality scoring |
./seo hreflang <url> |
hreflang / i18n extraction |
./seo backlinks <url> |
Free sources (Moz/Bing/Common Crawl); premium via DataForSEO |
./seo cluster <keyword> |
Keyword clustering |
./seo content-brief <topic> [kw] |
Content brief |
./seo drift baseline|compare|history <url> |
Time-series drift |
./seo google <sub> [args] |
PSI / CrUX / GSC / GA4 (key required) |
./seo run <script.py> [args] |
Run any of the 53 scripts directly |
./seo list |
Enumerate scripts, sub-skills, extensions |
Judgment layer
For anything that needs interpretation — not just measurement — load the matching
sub-skill and execute it (optionally in parallel via subagent):
- E-E-A-T / content quality →
skills/seo-content/SKILL.md
- GEO / AI Overviews →
skills/seo-geo/SKILL.md
- Local / GBP →
skills/seo-local/SKILL.md
- Maps intelligence →
skills/seo-maps/SKILL.md
- SXO (search experience, personas) →
skills/seo-sxo/SKILL.md
- Strategy per industry →
skills/seo-plan/SKILL.md
- Programmatic SEO →
skills/seo-programmatic/SKILL.md
- Competitor pages →
skills/seo-competitor-pages/SKILL.md
- E-commerce →
skills/seo-ecommerce/SKILL.md
- Image SEO →
skills/seo-images/SKILL.md
- FLOW framework →
skills/seo-flow/SKILL.md
- Cluster (SERP-based) →
skills/seo-cluster/SKILL.md
Orchestration — gated multi-agent fan-out
Only as many agents as the site actually needs (typically 7–10, never all 18):
- Detect business type (SaaS / local-service / ecommerce / publisher /
agency / other) from homepage signals.
- Choose the category set:
- Always: technical, content (E-E-A-T), schema, page, sxo, geo
- By industry: saas → cluster/programmatic · local-service → local/maps
· ecommerce → ecommerce · publisher → cluster/images
· agency → competitor-pages
- By credential: google, backlinks, dataforseo, firecrawl (only with keys)
- Run in parallel. Each subagent loads its
skills/seo-<category>/SKILL.md,
runs measurement via ./seo <cmd>, and returns structured findings with the
4 fields.
- Synthesise into one weighted score (in
lib/report.py): Technical 22% ·
Content 23% · On-Page 20% · Schema 10% · Performance 10% ·
AI-Readiness 10% · Images 5%.
- Action plan sorted by dependency, with a falsifiability check per
recommendation.
Quality gates (do not ignore)
- 30+ location pages → warn (enforce 60% unique content); 50+ → hard stop.
- Never recommend HowTo schema (deprecated since Sept 2023).
- FAQ schema: rich results withdrawn for all sites on 7 May 2026 → note only;
use QAPage for genuine Q&A.
- Core Web Vitals always INP, never FID.
Honest limits
- Without a Google key: load time is a lab estimate, no CrUX/PSI/GSC data.
- Without third-party index: no search volumes/backlink graph
(DataForSEO/Ahrefs/Bing need their own keys).
- Extensions (DataForSEO, Firecrawl, Ahrefs, Bing, Banana, Profound,
SE Ranking, Unlighthouse) are ported but only work once you supply credentials.
- Scroll/hydration content stays noisy → use
visual as a cross-check.
Cost
The measurement layer is pure local Python — $0 in tokens. Only the LLM
interpretation costs anything, which is typically ~12×–30× cheaper than the
equivalent Claude-based audit. See the project README for the worked example.
1---2name: seo-audit3description: Run a full, weighted local & technical SEO audit on any website — entirely local, no SaaS, no per-domain pricing. Measures 8 discipline areas with a Python CLI (technical, on-page, schema.org/JSON-LD, local/GBP, Core Web Vitals, GEO/AI-Overview, content/E-E-A-T, images, sitemap, hreflang, content briefs, keyword clustering, drift, and Google APIs), then synthesises the findings into one prioritised report with weighted scoring, dependency-ordered actions and falsifiable recommendations.4---56# seo-audit — local & technical SEO audit toolkit78A two-layer audit engine. **Measurement** is deterministic (a Python CLI + 539curated scripts). **Judgment** is where the model interprets those findings and10writes the plan. Both stay on your machine: no API keys for the core, no11third-party SaaS, no per-domain pricing.1213## Use this first14151. **Broad, then deep.** Run `./seo audit <url>` once, then drill into the16 highest-impact findings. Starting with single commands optimises symptoms17 instead of root causes.182. **Setup first.** If `./seo doctor` reports an error, run `./setup.sh`. Chromium19 is workspace-local; occasional sandbox hangs are caught by a subprocess20 timeout — just retry.213. **Recommendations carry 4 fields.** Observation → Dependency → Failure signal →22 Early indicator. Field 2 sets the order, field 3 tells you how you'd know it23 worked.2425## Command surface2627| Command | Measures |28|---------|----------|29| `./seo doctor` | Environment health check |30| `./seo audit <url>` | Full weighted verdict (specialists + sitemap + structure) |31| `./seo technical <url>` | Technical SEO (9 categories) |32| `./seo page <url>` | On-page: content, links, keyword signals |33| `./seo schema <url>` | JSON-LD / LocalBusiness detection + validation |34| `./seo local <url>` | Local / NAP consistency |35| `./seo visual <url>` | Render, hydration, console errors, load time (lab) |36| `./seo sitemap <url>` | Sitemap discovery + validation |37| `./seo content <url\|file>` | QRG-style content-quality scoring |38| `./seo hreflang <url>` | hreflang / i18n extraction |39| `./seo backlinks <url>` | Free sources (Moz/Bing/Common Crawl); premium via DataForSEO |40| `./seo cluster <keyword>` | Keyword clustering |41| `./seo content-brief <topic> [kw]` | Content brief |42| `./seo drift baseline\|compare\|history <url>` | Time-series drift |43| `./seo google <sub> [args]` | PSI / CrUX / GSC / GA4 (key required) |44| `./seo run <script.py> [args]` | Run any of the 53 scripts directly |45| `./seo list` | Enumerate scripts, sub-skills, extensions |4647## Judgment layer4849For anything that needs interpretation — not just measurement — load the matching50sub-skill and execute it (optionally in parallel via `subagent`):5152- **E-E-A-T / content quality** → `skills/seo-content/SKILL.md`53- **GEO / AI Overviews** → `skills/seo-geo/SKILL.md`54- **Local / GBP** → `skills/seo-local/SKILL.md`55- **Maps intelligence** → `skills/seo-maps/SKILL.md`56- **SXO** (search experience, personas) → `skills/seo-sxo/SKILL.md`57- **Strategy per industry** → `skills/seo-plan/SKILL.md`58- **Programmatic SEO** → `skills/seo-programmatic/SKILL.md`59- **Competitor pages** → `skills/seo-competitor-pages/SKILL.md`60- **E-commerce** → `skills/seo-ecommerce/SKILL.md`61- **Image SEO** → `skills/seo-images/SKILL.md`62- **FLOW framework** → `skills/seo-flow/SKILL.md`63- **Cluster (SERP-based)** → `skills/seo-cluster/SKILL.md`6465## Orchestration — gated multi-agent fan-out6667Only as many agents as the site actually needs (typically 7–10, never all 18):68691. **Detect business type** (SaaS / local-service / ecommerce / publisher /70 agency / other) from homepage signals.712. **Choose the category set:**72 - **Always:** technical, content (E-E-A-T), schema, page, sxo, geo73 - **By industry:** saas → cluster/programmatic · local-service → local/maps74 · ecommerce → ecommerce · publisher → cluster/images75 · agency → competitor-pages76 - **By credential:** google, backlinks, dataforseo, firecrawl (only with keys)773. **Run in parallel.** Each subagent loads its `skills/seo-<category>/SKILL.md`,78 runs measurement via `./seo <cmd>`, and returns structured findings with the79 4 fields.804. **Synthesise** into one weighted score (in `lib/report.py`): Technical 22% ·81 Content 23% · On-Page 20% · Schema 10% · Performance 10% ·82 AI-Readiness 10% · Images 5%.835. **Action plan** sorted by dependency, with a falsifiability check per84 recommendation.8586## Quality gates (do not ignore)8788- **30+ location pages** → warn (enforce 60% unique content); **50+ → hard stop**.89- **Never recommend HowTo schema** (deprecated since Sept 2023).90- **FAQ schema:** rich results withdrawn for all sites on 7 May 2026 → note only;91 use QAPage for genuine Q&A.92- **Core Web Vitals always INP, never FID.**9394## Honest limits9596- **Without a Google key:** load time is a lab estimate, no CrUX/PSI/GSC data.97- **Without third-party index:** no search volumes/backlink graph98 (DataForSEO/Ahrefs/Bing need their own keys).99- **Extensions** (DataForSEO, Firecrawl, Ahrefs, Bing, Banana, Profound,100 SE Ranking, Unlighthouse) are ported but only work once you supply credentials.101- **Scroll/hydration content** stays noisy → use `visual` as a cross-check.102103## Cost104105The measurement layer is pure local Python — **$0 in tokens**. Only the LLM106interpretation costs anything, which is typically **~12×–30× cheaper** than the107equivalent Claude-based audit. See the project README for the worked example.