seo-drift
Skill201 starsChanged 5 months agoMITView on GitHub
Capture an SEO baseline snapshot for a domain or URL, then on later runs compare the current state and surface regressions. Tracks authority, traffic, keywords, backlinks, and on-page content. Three subcommands — `baseline`, `compare`, `history`. Use when the user asks for "SEO drift", "baseline this site", "did anything break", "SEO regression check", "compare before and after", "deployment check", or "monthly SEO snapshot".
24 other projects use a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- alpit-patel/seo-aeo-geo-kittheir own version, first seen Nov 8, 2026
- zhtyyx/codex-seotheir own version, first seen Nov 1, 2026
- joaoguirunas/team-ostheir own version, first seen Oct 21, 2026
- susantedit/claude-skillstheir own version, first seen Oct 20, 2026
- webdevarif/claude-skillstheir own version, first seen Oct 20, 2026
- ZachArticulateV/designer-pro-and-seotheir own version, first seen Oct 19, 2026
Used with
Projects with it also use seo-maps, seo-ecommerce and 5 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
timruebenachSkillseo-maps
Maps intelligence for local SEO — geo-grid rank tracking, GBP profile auditing via API, review intelligence across Google/Tripadvisor/Trustpilot, cross-platform NAP verification (Google/Bing/Apple/OSM), competitor radius mapping, and LocalBusiness schema generation from API data. Three-tier capability: free (Overpass + Geoapify), DataForSEO (full intelligence), DataForSEO + Google (maximum coverage). Use when user says "maps", "geo-grid", "rank tracking", "GBP audit", "review velocity", "competitor radius", "maps analysis", "local rank tracking", "Share of Local Voice", or "SoLV".
Also in 17 projects that use this
timruebenachSkillseo-ecommerce
E-commerce SEO analysis: Google Shopping visibility, Amazon marketplace intelligence, product schema validation, competitor pricing analysis, and marketplace keyword gaps. Combines on-page product SEO with marketplace data from DataForSEO Merchant API. Use when user says "ecommerce SEO", "product SEO", "Google Shopping", "marketplace SEO", "product schema", "Amazon SEO", "product listings", "shopping ads", or "merchant SEO".
Also in 16 projects that use this
AgriciDanielSkillseo-agentic
Audit and fix agent readiness: the Lighthouse Agentic Browsing fraction, accessibility tree for agents, robots.txt and Content-Signal for AI agents, WAF treatment of agent traffic, llms.txt, Markdown delivery, ai-catalog.json, /.well-known discovery files, and WebMCP tools. Use when the user asks whether AI agents can use or browse the site, or about llms.txt or WebMCP. Exclude AI citability and brand signals (seo-geo) and commerce protocol depth (seo-ecommerce).
Also in 4 projects that use this
mangollcSkillseo-backlinks
Backlink analysis and link building strategy: competitor backlink profiling, outreach plan generation, monthly SEO reporting framework, toxic link identification, link opportunity scoring, and unlinked mention discovery.
Also in 15 projects that use this
- +3 more from timruebenach
Other versions24 projects use a version of this.
Word for word · 0
None found.
Edited · 1
- amirjahfar1/automate-seo-with-claude★ 290% same
Wrote their own version · 23
- AgriciDaniel/claude-seo★ 20ksame name
- nowork-studio/toprank★ 4.1ksame name
- nowork-studio/notfair-plugin★ 4.1ksame name
- indranilbanerjee/digital-marketing-pro★ 934same name
- zhtyyx/codex-seo★ 152same name
- dancolta/seo-drift-monitor★ 19same name
- ZachArticulateV/designer-pro-and-seo★ 10same name
- joaoguirunas/team-os★ 6same name
- avalonreset/legends-seo-dungeon★ 4same name
- alpit-patel/seo-aeo-geo-kit★ 2same name
13 more not listed
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 repository31 other files it gives its agents.
- ai-search-gaps-to-social-campaignSkill
- client-onboarding-proposalSkill
- local-gmb-visibilitySkill
- seo-adsSkill
- seo-agency-landing-pageSkill
- seo-ai-search-share-of-voiceSkill
- seo-ai-social-reportSkill
- seo-apiSkill
- seo-backlink-gapSkill
- seo-backlinks-profileSkill
- seo-competitor-gap-analysisSkill
- seo-competitor-pagesSkill
- seo-content-auditSkill
- seo-content-briefSkill
- seo-firecrawlSkill
- seo-gaps-to-social-campaignSkill
- seo-geoSkill
- seo-googleSkill
- seo-hreflangSkill
- seo-imagesSkill
- seo-keyword-clusterSkill
- seo-keyword-nicheSkill
- seo-localSkill
- seo-pageSkill
- seo-planSkill
- seo-schemaSkill
- seo-sitemapSkill
- seo-subdomainSkill
- seo-sxoSkill
- seo-technical-auditSkill
- site-audit-to-social-distributionSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 2 are distinctive, and 6 are very specific to this project.
0
Common
Most of the 23 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 59
If Firecrawl unavailable (or
--no-firecrawlpassed): only WebFetch fields enter the fingerprint. - Very specific: line 66
If --skip-cwv was passed, skip this step entirely and store null for cwv / crux_history fields.
- Very specific: line 67
If CrUX returns insufficient data, store null for the affected metrics and continue.
- Distinctive: line 75
If no baseline exists, fall through to baseline mode and tell the user to come back later.
- Very specific: line 94
Caveat: if either snapshot lacks Google fields (creds were missing at one capture), surface Field-data / indexation drift: not comparable — …
- Very specific: line 101
Write HISTORY.md with the table.
- Very specific: line 176
Call DATA_getCreditBalance before running.
- Distinctive: line 180
Don't auto-disavow or auto-fix anything based on drift findings.
“Common” is measured: kept by at least 6 in 10 of the 23 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Example output: examples/seo-drift-wix-com-20260514/compare/DRIFT-REPORT.md
SEO Drift
Git for SEO. Capture a snapshot of a domain or URL's SEO state ("baseline"), then on later runs diff the current state against the baseline and surface regressions. Catches the things that get worse silently after a deploy, redesign, or content cull.
Acknowledgements: drift-as-an-SEO-skill framework originated in
claude-seoby AgriciDaniel (with the original concept credited to Dan Colta, Pro Hub Challenge). MIT-licensed both directions; this implementation is independent but the framing is theirs.
Prerequisites
- SE Ranking MCP server connected.
- Claude's
WebFetchtool available (for URL-mode page fingerprinting). - User provides: target domain or URL, plus a subcommand (
baseline,compare,history).
Optional flags
| Flag | Mode | Effect |
--no-firecrawl | baseline, compare | Skip Firecrawl-based <head> + JSON-LD capture even when Firecrawl is installed (saves credits at the cost of canonical / robots / og:* / JSON-LD diff coverage). |
--skip-cwv | baseline, compare | Skip the Google CrUX capture (step 4b) even when google-api.json is configured. Useful when you only care about content/structural drift, or when CrUX rate-limit concerns outweigh CWV coverage. Mirrors theirs at seo-drift/SKILL.md:107, 131. |
--baseline-id <n> | compare | Compare against a specific baseline by ID rather than the most recent. |
--limit <n> | history | Cap the number of historical entries shown. |
Subcommands
baseline <target>
Capture the current SEO state and write it to a snapshot file. No diff produced.
compare <target>
Load the most recent baseline for the target. Capture the current state. Diff. Produce DRIFT-REPORT.md.
history <target>
List all stored baselines for the target with their dates and key metrics (DA, traffic, keyword count). No diff produced.
Process
baseline mode
- Validate target. Determine if domain or URL. Domain =
example.com; URL = anything starting withhttp(s)://.- SSRF protection (URL mode). If target is a URL, validate via
python3 -c "from scripts.google_auth import validate_url; import sys; sys.exit(0 if validate_url('{target}') else 1)"(or importvalidate_urldirectly in any helper script). Reject loopback (127.0.0.1, ::1, localhost), private IP ranges (10/8, 172.16/12, 192.168/16), link-local (169.254/16), and Google metadata endpoints. If validation fails, abort with a clear error and don't proceed to fetch — feeding an unvalidated URL into Firecrawl / WebFetch / Google APIs would risk SSRF against internal services. Mirrors theirs atseo-drift/SKILL.md:97.
- SSRF protection (URL mode). If target is a URL, validate via
- Preflight. See
skills/seo-firecrawl/references/preflight.mdfor the canonical 3-stage preflight (credit balance, Firecrawl availability, Google APIs). Skill-specific notes:- Estimated SE Ranking cost for this skill: typical baseline costs ~10–20 SE Ranking credits depending on whether step 4 (URL-mode page snapshot) is included.
- Firecrawl: optional with WebFetch fallback, +1 Firecrawl credit per URL if available (URL mode). When available, the snapshot also captures
<head>+ JSON-LD content so canonical / robots / og:* / JSON-LD changes are detectable on diff. Without it the snapshot is partial. Pass--no-firecrawlto skip Firecrawl even when available (saves credits at the cost of diff coverage). - Google APIs: tier 0 unlocks CrUX p75 LCP/INP/CLS capture (origin in domain mode, URL in URL mode); tier 1 (URL mode only) additionally captures URL Inspection state (
indexStatusVerdict,googleCanonical,lastCrawlTime) so subsequent compares can flag field-data and indexation drift. Seeskills/seo-google/references/cross-skill-integration.md§ "seo-drift" for the full recipe.
- Domain snapshot (always):
DATA_getDomainOverviewWorldwide— DA, traffic, organic + paid keyword counts.DATA_getDomainKeywords— top 100 organic keywords with positions.DATA_getBacklinksSummary— backlinks total, referring domains total.DATA_getBacklinksRefDomains— top 20 referring domains with authority.
- Page snapshot (if target is a URL):
WebFetch(always) +mcp__firecrawl-mcp__firecrawl_scrape(when available)- WebFetch (free): extract
<title>, all<h1..h6>, lang, word count, internal-link count, image count, body markdown for prose-level diff. - Firecrawl (1 Firecrawl credit per URL) — recovers
<head>and<script>content WebFetch strips:- From
metadata: canonical URL, robots meta, og:title, og:description, og:image, twitter:card. - From returned
html: every<script type="application/ld+json">block. Capture both detected@types and a hash of the full block content (so any schema-content change is detected on diff, not just type-list changes).
- From
- If Firecrawl unavailable (or
--no-firecrawlpassed): only WebFetch fields enter the fingerprint.BASELINE.mdnotes:Snapshot fields recovered via WebFetch only — canonical, robots, og:*, twitter:*, and JSON-LD changes will not be detected on subsequent compares. Install Firecrawl for full coverage. - Compute a fingerprint hash of the captured fields.
- Also capture page authority:
DATA_getPageAuthority. 4b. Google field-data snapshot (only if google-api.json is present AND--skip-cwvnot set) - Tier 0 (always when configured):
python3 scripts/pagespeed_check.py "{target}" --crux-only --json(URL mode) orpython3 scripts/pagespeed_check.py "https://{domain}" --crux-only --json(domain mode, origin-level CrUX). Store the resulting p75 LCP / INP / CLS / FCP / TTFB and the source label ("URL" or "origin"). - Tier 0 (always when configured):
python3 scripts/crux_history.py "{target_or_origin}" --jsonfor the 25-week trend window snapshot — store ascrux_history_baseline. Subsequent compares can detect drift against the most recent week. - Tier 1 (URL mode only):
python3 scripts/gsc_inspect.py "{target_url}" --site-url "{config.default_property}" --json. StoreindexStatusVerdict,coverageState,googleCanonical,userCanonical,lastCrawlTime. - If
--skip-cwvwas passed, skip this step entirely and storenullforcwv/crux_historyfields. The compare-mode rules then surface "Field-data drift: skipped —--skip-cwvflag passed at baseline." - If CrUX returns insufficient data, store
nullfor the affected metrics and continue.
- WebFetch (free): extract
- Write snapshot file
seo-drift-{target-slug}-{YYYYMMDD}/snapshot.json. - Update index
seo-drift-{target-slug}/baselines.json— append{date, snapshot_path}entry.
compare mode
- Validate target + locate latest baseline in
seo-drift-{target-slug}/baselines.json.- SSRF protection (URL mode). Same
validate_url()check as baseline mode. Refuses to fetch private/loopback/metadata addresses. - If no baseline exists, fall through to baseline mode and tell the user to come back later.
- SSRF protection (URL mode). Same
- Capture current state (same data as baseline mode).
- Diff each metric using
references/drift-thresholds.md:- Domain authority: ±5 = yellow, ±10 = red.
- Estimated organic traffic: ±20% = yellow, ±50% = red.
- Organic keyword count: ±10% = yellow, ±30% = red.
- Top-3 keyword count: ±15% = yellow, ±40% = red.
- Top-100 keyword churn: any high-volume drop = red.
- Net referring domains: -5 to -20 = yellow, <-20 = red.
- Page-level (URL mode): any change to canonical / robots / lang / H1 = red; title or meta description change = yellow; schema types added/removed = yellow; og:* / twitter:* changes = yellow.
- Firecrawl-dependent diff caveat: canonical / robots / og:* / twitter:* / JSON-LD diffs require both baseline and current snapshots to have been captured with Firecrawl. If either snapshot was WebFetch-only, those fields surface as
not comparable — Firecrawl-only fields missing from {baseline | current} snapshotrather than as a green pass. - Google-data drift (only if both snapshots have Google fields):
- LCP p75 increased ≥20% → red.
- INP p75 increased ≥20% → red.
- CLS p75 increased ≥0.05 absolute → yellow.
- FCP / TTFB p75 increased ≥30% → yellow.
- Inspection status changed from
INDEXEDto anything else → red. googleCanonicalchanged → yellow.lastCrawlTime>60 days old → yellow.- Caveat: if either snapshot lacks Google fields (creds were missing at one capture), surface
Field-data / indexation drift: not comparable — Google fields missing from {baseline | current} snapshot.
- Synthesise
DRIFT-REPORT.md— red findings first, then yellow, then green/positive deltas. End with a "what to investigate first" recommendation.
history mode
- Load
baselines.json. - For each entry, render a one-row summary: date, DA, traffic, keyword count, top-3 count.
- Write
HISTORY.mdwith the table.
Output format
baseline mode
seo-drift-{target-slug}-{YYYYMMDD}/:
seo-drift-{target-slug}-{YYYYMMDD}/
├── snapshot.json (the captured state)
└── BASELINE.md (one-page human summary of what was captured)compare mode
seo-drift-{target-slug}-{YYYYMMDD}/:
seo-drift-{target-slug}-{YYYYMMDD}/
├── DRIFT-REPORT.md (synthesised: red/yellow/green changes — primary deliverable; inlines 01-domain-deltas, 02-keyword-churn, 03-backlink-deltas, 04-page-deltas as sections)
└── evidence/
├── baseline-snapshot.json (the prior reference — kept for replay)
├── current-snapshot.json (today's state — kept for replay)
├── 01-domain-deltas.md (DA, traffic, keyword count changes — raw step output)
├── 02-keyword-churn.md (top-100 entries/exits)
├── 03-backlink-deltas.md (new + lost backlinks/domains)
└── 04-page-deltas.md (URL mode only: HTML fingerprint diff)Top-level: DRIFT-REPORT.md only. The four delta step files are inlined into named sections in DRIFT-REPORT.md; evidence/ keeps the raw delta dumps and both snapshot JSONs so a future re-diff or audit can replay against them.
DRIFT-REPORT.md shape:
# Drift Report: {target}
> Baseline: {baseline date} · Current: {today's date}
## RED — investigate today
- {finding} ({severity rationale})
- ...
## YELLOW — investigate this week
- {finding}
- ...
## GREEN — positive deltas
- {finding}
- ...
## Field-data drift (CrUX + URL Inspection)
- LCP p75: {baseline} → {current} ms ({Δ%}) {↑ red / ↑ yellow / stable / ↓ green}
- INP p75: {baseline} → {current} ms ({Δ%}) {…}
- CLS p75: {baseline} → {current} ({Δ absolute}) {…}
- Indexation status: {baseline INDEXED → current EXCLUDED} (URL mode)
- googleCanonical: {baseline → current} (if changed)
- (Or: `Field-data / indexation drift: not configured` / `not comparable — missing from {snapshot}`)
## What to investigate first
1. {prioritised action with reasoning}
2. ...history mode
seo-drift-{target-slug}-{YYYYMMDD}/HISTORY.md:
# History: {target}
| Date | DA | Traffic | Keywords | Top-3 |
|---|---|---|---|---|
| 2026-04-27 | 42 | 18,500/mo | 1,247 | 89 |
| 2026-03-15 | 41 | 17,200/mo | 1,213 | 85 |
| ...Tips
- Respect rate limit: 10 req/sec. Baseline runs 4–6 sequential calls; pace easily.
- Call
DATA_getCreditBalancebefore running. Domain baseline ~10–15 SE Ranking credits; URL baseline ~15–20 SE Ranking credits + 1 Firecrawl credit; compare ~20–30 SE Ranking credits + 1 Firecrawl credit (current-state capture). - Snapshot storage is local-only in v0.4.0. If your team needs shared baselines, point everyone at the same
seo-drift-{target-slug}/directory in a shared filesystem or commit it to a private repo. Baselines are JSON — git-friendly. - Baseline cadence: monthly is the natural rhythm because SE Ranking's history endpoints have monthly granularity. Weekly is too noisy for backlink data. Document recommended cadence in handoff to your team.
- For deploy-time "did anything break in the last hour" use cases, the URL-mode page-fingerprint half is the workhorse — that doesn't depend on monthly data.
- Don't auto-disavow or auto-fix anything based on drift findings. The skill diagnoses; humans decide.
- Authority-history all-zeros caveat: if
DATA_getPageAuthorityHistory(URL mode) orDATA_getDomainAuthorityHistoryreturns flat-zero values across the window, treat as "insufficient history" — don't compute a delta or surface a regression based on missing data. Cross-check the current-value endpoint (DATA_getPageAuthority/DATA_getDomainOverviewWorldwide) — if the current value is meaningful but history is flat, surface that as a data-quality flag inDRIFT-REPORT.mdrather than fabricating a trend. - Cost of doing nothing: silent regressions. Cost of running monthly: ~15 credits. Run monthly.
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.

