---
name: seo-drift
description: 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".
---
> Example output: [examples/seo-drift-wix-com-20260514/compare/DRIFT-REPORT.md](../../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-seo` by 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 `WebFetch` tool 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 `
` + 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 ` | compare | Compare against a specific baseline by ID rather than the most recent. |
| `--limit ` | history | Cap the number of historical entries shown. |
## Subcommands
### `baseline `
Capture the current SEO state and write it to a snapshot file. No diff produced.
### `compare `
Load the most recent baseline for the target. Capture the current state. Diff. Produce `DRIFT-REPORT.md`.
### `history `
List all stored baselines for the target with their dates and key metrics (DA, traffic, keyword count). No diff produced.
## Process
### baseline mode
1. **Validate target.** Determine if domain or URL. Domain = `example.com`; URL = anything starting with `http(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 import `validate_url` directly 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 at `seo-drift/SKILL.md:97`.
2. **Preflight.** See `skills/seo-firecrawl/references/preflight.md` for 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 `` + JSON-LD content so canonical / robots / og:* / JSON-LD changes are detectable on diff. Without it the snapshot is partial. Pass `--no-firecrawl` to 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. See `skills/seo-google/references/cross-skill-integration.md` § "seo-drift" for the full recipe.
3. **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.
4. **Page snapshot** (if target is a URL): `WebFetch` (always) + `mcp__firecrawl-mcp__firecrawl_scrape` (when available)
- **WebFetch** (free): extract ``, all ``, lang, word count, internal-link count, image count, body markdown for prose-level diff.
- **Firecrawl** (1 Firecrawl credit per URL) — recovers `` and `