seo-drift

SEO drift monitoring: capture baselines of SEO-critical elements, detect changes, and track regressions over time. Git for SEO: baseline, diff, and track changes to your on-page SEO. Use when user says "SEO drift", "baseline", "track changes", "did anything break", "SEO regression", "compare SEO", "

By agricidaniel · 4,287 installs

npx skills add agricidaniel/claude-seo --skill seo-drift

Source repository · Upstream listing

SEO Drift Monitor (April 2026) Git for your SEO. Capture baselines, detect regressions, track changes over time. Commands Command Purpose /seo drift baseline <url Capture current SEO state as a "known good" snapshot /seo drift compare <url Compare current page state to stored baseline /seo drift history <url Show change history and past comparisons What It Captures Every baseline records these SEO critical elements: Element Field Source Title tag title parse html.py Meta description meta description parse html.py Canonical URL canonical parse html.py Robots directives meta robots parse html.py H1 headings h1 (array) parse html.py H2 headings h2 (array) parse html.py H3 headings h3 (array) parse html.py JSON LD schema schema (array) parse html.py Open Graph tags open graph (dict) parse html.py Core Web Vitals cwv (dict) pagespeed check.py HTTP status code status code fetch page.py HTML content hash html hash (SHA 256) Computed Schema content hash schema hash (SHA 256) Computed How Comparison Works The comparison engine applies 17 rules across 3 severity levels . Load references/comparison rules.md for the full rule set with thresholds, recommended actions, and cross skill references. Severity Levels Level Meaning Response Time CRITICAL SEO breaking change, likely traffic loss Immediate WARNING Potential impact, needs investigation Within 1 week INFO Awareness only, may be intentional Review at convenience Storage All data is stored locally in SQLite: Tables baselines : Captured snapshots with all SEO elements comparisons : Diff results with triggered rules and severities URL normalization ensures consistent matching: lowercase scheme/host, strip default ports (80/443), sort query parameters, remove UTM parameters, strip trailing slashes. Command: baseline Captures the current state of a page and stores it. Steps: 1. Validate URL (SSRF protection via google auth.validate url() ) 2. Fetch page via "${CLAUDE PLUGIN ROOT}/scripts/claude seo" run fetch page.py <URL 3. Parse HTML via "${CLAUDE PLUGIN ROOT}/scripts/claude seo" run parse html.py <URL 4. Optionally fetch CWV via "${CLAUDE PLUGIN ROOT}/scripts/claude seo" run pagespeed check.py <URL (use skip cwv to skip) 5. Hash HTML body and schema content (SHA 256) 6. Store snapshot in SQLite Execution: Output: JSON with baseline ID, timestamp, URL, and summary of captured elements. Command: compare Fetches the current page state and diffs it against the most recent baseline. Steps: 1. Validate URL 2. Load most recent baseline from SQLite (or specific baseline id ) 3. Fetch and parse current page state 4. Run all 17 comparison rules 5. Classify findings by severity 6. Store comparison result 7. Output JSON diff report Execution: Output: JSON with all triggered rules, old/new values, severity, and actions. After comparison, offer to generate an HTML report: Command: history Shows all baselines and comparisons for a URL. Execution: Output: JSON array of baselines (newest first) with timestamps and comparison summaries. Cross Skill Integration When drift is detected, recommend the appropriate specialized skill: Finding Recommendation Schema removed or modified Run /seo schema <url for full validation CWV regression Run /seo technical <url for performance audit Title or meta description changed Run /seo page <url for content analysis Canonical changed or removed Run /seo technical <url for indexability check Noindex added Run /seo technical <url for crawlability audit H1/heading structure changed Run /seo content <url for E E A T review OG tags removed Run /seo page <url for social sharing analysis Status code changed to error Run /seo technical <url for full diagnostics Error Handling Scenario Action URL unreachable Report error from fetch page.py . Do not guess state. Suggest user verify URL. No baseline exists for URL Inform user and suggest running baseline first. SSRF blocked (private IP) Report validate url() rejection. Never bypass. SQLite database missing Auto create on first use. No error. CWV fetch fails (no API key) Store null for CWV fields. Skip CWV rules during comparison. Page returns 4xx/5xx Still capture as baseline (status code IS a tracked field). Multiple baselines exist Use most recent unless baseline id specified. Security All URL fetching goes through "${CLAUDE PLUGIN ROOT}/scripts/claude seo" run fetch page.py , which enforces SSRF protection (blocks private IPs, loopback, reserved ranges, GCP metadata endpoints) No curl, no subprocess HTTP calls only the project's validated fetch pipeline All SQLite queries use parameterized placeholders ( ? ), never string interpolation TLS always verified no verify=False anywhere in the pipeline Typical Workflows Pre/Post Deployment Check Ongoing Monitoring Investigating a Traffic Drop