seo-agent
Skill14 starsChanged 32 days agoMITView on GitHub
Daily SEO audit-and-fix loop for a website you own, driven by one config file per site. Crawls the live site with free stdlib Python scripts (technical crawl, indexability, internal-link graph with day-over-day regression diff, JSON-LD validity, AI-crawler access, Core Web Vitals via Lighthouse/PageSpeed), pulls real queries from Google Search Console with your own credentials, ranks issues by impact vs effort, ships safe fixes as pull requests (and optional CMS patches) behind a human review gate, and writes a dated report. Use when asked to run an SEO audit, a technical SEO audit, find SEO quick wins, check indexing or AI crawlability, or run the daily SEO check: /seo-agent <slug> or /seo-agent <slug> technical. Requires Claude Code (runs scripts, git, gh); never merges, never direct-pushes.
- Installs packages
- Commits and pushes
1 other project uses a version of this.
Adopted by
Most recently taken up by
- 01clauding/claude-seo-skilltheir own version, first seen Mar 13, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- 01clauding/claude-seo-skill★ 4same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository63 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- board-advisorSkill
- bottleneck-removalSkill
- business-auditSkill
- business-starterSkill
- competitor-researchSkill
- founder-independenceSkill
- hand-it-offSkill
- happy-customerSkill
- hiring-replacementSkill
- meeting-follow-upSkill
- monday-numbersSkill
- new-hireSkill
- no-meeting-mondaySkill
- obsidian-brainSkill
- ops-deskSkill
- safe-resaleSkill
- spreadsheet-dashboardSkill
- warm-leadSkill
- downloadable-asset-engineeringSkill
- html-to-pdfSkill
- linux-server-opsSkill
- precision-pdf-editingSkill
- repo-radarSkill
- secure-credentialsSkill
- security-auditorSkill
- best-timeSkill
- brand-deal-filterSkill
- comment-replySkill
- content-monthSkill
- daily-socialSkill
- dm-closerSkill
- idea-bankSkill
- marketing-teamSkill
- reel-ideationSkill
- reel-scorecardSkill
- trial-postSkill
- viral-breakdownSkill
- youtube-seoSkill
- caption-engineSkill
- content-multiplierSkill
- edit-styleSkill
- footage-ingestSkill
- longform-editSkill
- podcast-repurposeSkill
- raw-to-reelSkill
- ready-to-filmSkill
- reel-captionsSkill
- script-polishSkill
- thumbnail-generatorSkill
- use-local-whisperSkill
- conversion-funnel-auditingSkill
- llms-txtSkill
- website-designerSkill
- website-devSkill
- be-conciseSkill
- humanizerSkill
- launch-weekSkill
- linkedin-writerSkill
- newsletterSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
11 rules. About 0 are common, 2 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Very specific: line 18
All commands below run from this skill folder (S=scripts).
- Very specific: line 32
Read sites/<slug>.md first.
- Distinctive: line 37
Run in this order; each writes machine-readable output the report uses.
- Very specific: line 48
Use bash -c for anything with $PROBES (--probe /api/ --probe /admin ...): zsh does not word-split it and the probes silently vanish.
- Very specific: line 57
Check robots.txt by hand if techaudit did not run: GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, PerplexityBot, …
- Very specific: line 62
Prefer long-tail problem language (what buyers type before they know the category) over head terms in avoid.
- Very specific: line 79
Run the config's build; never push a failing build.
- Very specific: line 81
Never push to the default branch, never merge, never touch design/CSS/components unless asked.
- Very specific: line 88
Optional: after shipping changed URLs, python3 $S/indexnow.py <domain> <key> <urls> (Bing and others.
- Very specific: line 91
Write ~/.claude/seo-reports/<slug>-<YYYY-MM-DD>.md (format below).
- Distinctive: line 94
Lean rule: if the linkgraph diff is empty, GSC shows no material movement and no priority changed, write a 3-line "no material changes" …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
SEO Agent
One engine, one config per site. Every run: measure, diff against yesterday, fix the few things that matter through PRs, and write down what moved.
Requirements
- Claude Code with Bash. Python 3 (scripts are stdlib only, except
gsc.py:pip install google-auth). - Optional: Chrome/Chromium (for
render_check.py),npm i -g lighthouse(forcwv.py),ghCLI (PRs and preview-host discovery). - A site config at
sites/<slug>.md. Copysites/example.mdand fill the placeholders. - GSC is optional but turns guesses into measurements. Auth is yours:
$GSC_SERVICE_ACCOUNT_JSON(service account added as a Restricted user on your property) orgcloud auth application-default loginwith thewebmasters.readonlyscope.
All commands below run from this skill folder (S=scripts). Output goes to
~/.claude/seo-reports/ (reports) and ~/.claude/seo-state/ (snapshots).
Modes
| mode | trigger | does |
| daily (default) | /seo-agent <slug> | steps 1-6, lean and diff-driven |
| technical | /seo-agent <slug> technical, "deep audit", weekly, or after any routing/middleware/sitemap/layout change | full checklist in references/technical-seo.md |
| audit-only | the user says read-only | steps 1-4 and 6; every fix becomes a proposal with an owner; no branches, PRs or CMS writes |
Steps
1. Load the config
Read sites/<slug>.md first. If it does not exist, stop and offer to create it from
sites/example.md (ask for domain, repo, build command, GSC property). Never redo
anything under known_wins.
2. Measure (free, no paid APIs)
Run in this order; each writes machine-readable output the report uses.
python3 $S/linkgraph.py <domain> # link graph + orphans, snapshot, diff vs last run
python3 $S/crawl.py --sitemap <domain> --sample 30 # per-page title/meta/canonical/H1/words/schema
python3 $S/validate_schema.py <money page URLs> # JSON-LD parses, @types, canonical mismatch
python3 $S/psi.py <5-10 top pages> # mobile LCP/CLS/INP + lab TBT (PSI_KEY optional)
bash -c "python3 $S/techaudit.py <domain> --out <dir> --max 3000 --thin 250 --depth-limit 4 \
--preview-from-gh <owner/repo> $PROBES" # when linkgraph shows new 4xx/orphans/lost schemaUse bash -c for anything with $PROBES (--probe /api/ --probe /admin ...): zsh does not word-split it and the probes silently vanish.
GSC (if configured): preflight under a 60 s cap, then snapshot every run.
perl -e 'alarm 60; exec @ARGV' python3 $S/gsc.py <property> preflight
python3 $S/gsc.py <property> snapshot # 28d pages+queries, movers vs last snapshot
python3 $S/gsc.py <property> searchanalytics --days 28 --dim query --top 200Check robots.txt by hand if techaudit did not run: GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-SearchBot, PerplexityBot, Google-Extended, Applebot-Extended, CCBot must not be blocked unless that is a deliberate policy.
3. Research
- With GSC: queries at average position 11-30 with real impressions are the cheapest page-1 pushes. Start there.
- Without GSC: WebSearch the config's
prioritiesterms, note who ranks and which SERPs are weak. - Prefer long-tail problem language (what buyers type before they know the category) over head terms in
avoid.
4. Prioritise
Build one table: issue | impact H/M/L | effort S/M/L | evidence (URL + observed value) | action.
Rank in this order:
- Linkgraph regressions (inlink drops, lost schema, new orphans, title drift). Highest confidence, usually small.
- Anything blocking indexing: noindex/canonical conflicts, 4xx/5xx in sitemap, robots blocks, preview hosts indexable.
- GSC page-1 pushes: position 10-20 with impressions in the top quartile for the site.
- Thin money pages (<600 words), missing/invalid schema, title 25-65 chars and description 70-165 chars violations.
- CWV failures at p75: LCP >2.5 s, CLS >0.1, INP >200 ms (field data only; lab is diagnosis).
Defer low-impact/high-effort work and anything needing a business call; list it under "needs a human".
5. Ship fixes (review gate)
Code (only if repo_path is set):
- Branch
fix/seo-<topic>offdefault_branch. One concern per PR. - Run the config's
build; never push a failing build. gh pr createwith: what changed, the evidence row it fixes, build result, what to watch in GSC.- Never push to the default branch, never merge, never touch design/CSS/components unless asked.
CMS (dispatch on cms.driver; token from the env var named in token_env):
- Patch scalar fields only: title, meta description, excerpt. Do not rewrite rich-text bodies unless asked.
- Hard gate before every patch:
python3 $S/lint_brand.py "<new text>" <each brand_voice.forbidden item>. Exit 1 means rewrite and lint again. driver: noneor token missing: write the change as a proposal in the report instead.
Optional: after shipping changed URLs, python3 $S/indexnow.py <domain> <key> <urls> (Bing and others; key file must be served at /<key>.txt).
6. Report
Write ~/.claude/seo-reports/<slug>-<YYYY-MM-DD>.md (format below). Every 7th run
also write <slug>-week-<YYYY-Www>.md: what shipped vs what moved in GSC.
Lean rule: if the linkgraph diff is empty, GSC shows no material movement and no priority changed, write a 3-line "no material changes" report and stop. Do not manufacture work.
Decision rules
- Numbers in reports: same source, same window length, before/after pairs via
--start/--endaround the change date. Never compare a UI export to an API pull or a 7-day window to a 28-day one. - Lab vs field CWV never share one claim.
- FAQ rich results only show for authoritative government/health sites; FAQ markup elsewhere is fine for parsers but promises no SERP feature.
- Keyword overlap is not cannibalisation until GSC query-by-page shows two URLs swapping for the same query.
- A preview host (
*.vercel.app,*.netlify.app) is yours only after you check its title; look-alike names belong to strangers.
Failure handling
| problem | do this |
| GSC preflight fails or hangs | record the exact error, use the newest ~/.claude/seo-state/<host>/gsc-*.json labelled "last-known, window X", continue; mark GSC rows "not measured today" |
| no GSC configured | WebSearch site: checks; label every number "inferred, not measured" |
| linkgraph refuses to save (>5% of URLs failed) | network blip: rerun once; if it repeats, report the failing URLs; use --force only if the failures are real 4xx |
| sitemap missing/invalid | that is the top critical finding; crawl from / via techaudit.py instead |
| Lighthouse/Chrome missing | use psi.py (Google-hosted) and say lab data came from PSI |
cwv.py slow (~90 s/URL) | run it with nohup ... & and poll its log; long silent foreground commands can time out |
| build fails on a fix branch | fix it or drop the PR; never push red |
Report format
# SEO daily: example.com, 2026-03-04
Crawl: 412 URLs, 398 indexable, 0 5xx. Linkgraph: 2 regressions (below).
| issue | impact | effort | evidence | action |
|---|---|---|---|---|
| /pricing lost 6 inlinks | H | S | footer nav change, 9 -> 3 inlinks | PR #41 restores footer link |
| /blog/x missing Article schema | M | S | validate_schema: 0 JSON-LD | PR #42 |
Shipped: PR #41, PR #42 (build green). CMS: 1 title patch, lint_brand PASS.
GSC 28d vs last: /guide/y pos 14.2 -> 11.8, impressions 1,920 -> 2,410 (same window length).
Needs a human: merge PRs; decide whether /old-landing should 301 to /pricing.
Carry forward: page-1 push for "<query>"; thin /features page (310 words).Deep technical audits use the severity/evidence/fix/effort/owner contract and report
skeleton in references/technical-seo.md.
Running it daily
In-session: /loop 24h /seo-agent <slug> (only fires while Claude Code is open).
Unattended: scripts/daily.sh <slug> from cron on a server; see references/deploy.md.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

