Install
$ agentstack add skill-jgoullet-seo-geo-audit-seo-monitor ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Skill: SEO Monitor — Periodic Delta Tracking
All responses and reports are produced in English by default. Switch to the user's language if they explicitly request it.
Overview
This skill is Step 4 in the SEO-GEO pipeline. It re-crawls a previously audited site, compares the current state against the original baseline, and produces a delta report highlighting what improved, what regressed, and what needs attention.
Position in the pipeline
[seo-collector] → site-data.json ──────────────────────┐
↓ │
[seo-geo-audit] → audit-report.md + audit-actions.json │
↓ │
[seo-implementer] → fixes/ │
↓ │
┌─────────────────────────┐ │
│ SEO MONITOR (this) │ ←──────────────┘
└─────────────────────────┘ (re-uses collector)
↓
monitoring/
├── baseline.json
├── delta-[date].md
└── alerts.md
↓
↻ loops back to collector for next cycle
What it produces
seo-project-[domain]/
└── monitoring/
├── baseline.json ← Snapshot from the first audit (created once)
├── scan-[date].json ← Each new crawl result
├── delta-[date].md ← Comparison report (human-readable)
├── delta-[date].json ← Comparison data (machine-readable)
├── alerts.md ← Active alerts (updated each scan)
└── history.md ← Score evolution over time
Step 0: Determine monitoring mode
First run (no baseline exists)
If no monitoring/baseline.json exists in the project folder:
- Check if
site-data.jsonandaudit-actions.jsonexist from a previous audit - If yes → convert them into the baseline:
- Copy
site-data.json→monitoring/baseline.json(addbaseline_datefield) - Extract scores from
audit-actions.json→ store in baseline
- If no → ask the user:
``` No previous audit found for this domain. Would you like me to:
- Run a full audit first (collector + audit) to establish the baseline
- Run a quick scan now and use it as the baseline
```
Subsequent runs (baseline exists)
- Load
monitoring/baseline.json - Run a fresh data collection (re-use
seo-collectormethodology) - Compare and generate the delta
Step 1: Re-collect current data
Re-run the collector methodology on the same URL. Collect the same data points as the original site-data.json:
1.1 Quick scan (default)
Focused on the metrics most likely to change:
| Data point | Method | Why it matters | |---|---|---| | Homepage meta tags | web_fetch homepage | Detect if fixes were applied | | Robots.txt | web_fetch /robots.txt | Detect if AI bots were unblocked | | Core Web Vitals | web_search PageSpeed data | Detect performance changes | | Indexation count | web_search site:[domain] | Detect indexation gains/losses | | Schema markup | web_fetch HTML check | Detect if schemas were added | | Sample pages (3-5) | web_fetch key pages | Detect meta tag changes | | AI bot access | Parse robots.txt for each bot | Detect GEO improvements |
Ahrefs MCP data points (if connected)
If Ahrefs MCP was used in the baseline collection, re-query the same endpoints for delta comparison:
| Ahrefs data point | Endpoint | What to compare | |---|---|---| | Domain Rating | domain-rating | DR change since baseline (gaining/losing authority?) | | Referring domains | backlinks-stats | New referring domains acquired? Lost any? | | Broken backlinks | broken-backlinks | Were broken links fixed? New ones appeared? | | Organic keywords | organic-keywords | Keyword position changes, new rankings gained | | Top pages traffic | top-pages | Traffic shifts on key pages | | Brand Radar | brand-radar | AI citation changes (new mentions? lost mentions?) |
> Brand Radar delta is critical for GEO monitoring: if the baseline showed 3 AI citations and the current scan shows 5, that's a direct measure of GEO improvement. If it dropped, investigate why (content freshness? bot access changed?).
1.2 Full re-scan (on request)
Runs the complete seo-collector methodology. Use when the user requests a comprehensive re-audit or when significant changes are expected.
Save the scan result to monitoring/scan-[date].json.
Step 2: Compare against baseline
For each data point, compute the delta:
2.1 Score comparison
{
"comparison_date": "[ISO 8601]",
"baseline_date": "[ISO 8601 from baseline]",
"days_since_baseline": 0,
"scores": {
"technical_seo": {
"baseline": 0,
"current": 0,
"delta": 0,
"trend": "improved|regressed|unchanged"
},
"core_web_vitals": { "..." },
"local_or_content": { "..." },
"eeat": { "..." },
"entity_seo": { "..." },
"geo": { "..." },
"ux_conversion": { "..." },
"overall": {
"baseline": 0,
"current": 0,
"delta": 0,
"max": 90
}
}
}
2.2 Specific change detection
For each category, track specific changes:
Meta tags changes:
{
"url": "https://example.com/page",
"field": "title",
"baseline_value": "[old title]",
"current_value": "[new title]",
"status": "fixed|regressed|unchanged|new_issue"
}
Robots.txt changes:
{
"bot": "GPTBot",
"baseline_status": "blocked",
"current_status": "allowed",
"status": "fixed"
}
Indexation changes:
{
"google_indexed": { "baseline": "~340", "current": "~380", "delta": "+~40" },
"bing_indexed": { "baseline": true, "current": true },
"brave_indexed": { "baseline": "unknown", "current": true }
}
Core Web Vitals changes:
{
"lcp_mobile": { "baseline": "3.2s", "current": "2.4s", "delta": "-0.8s", "status": "improved" },
"cls_mobile": { "baseline": "0.12", "current": "0.08", "delta": "-0.04", "status": "improved" },
"inp_mobile": { "baseline": "280ms", "current": "190ms", "delta": "-90ms", "status": "improved" }
}
Save the full comparison to monitoring/delta-[date].json.
Step 3: Generate alerts
Evaluate each change against alert thresholds:
Alert levels
| Level | Trigger | Example | |---|---|---| | 🔴 CRITICAL | Score dropped by > 10 points overall, or a previously fixed issue has returned | Overall score went from 62 to 48; H1 that was fixed is missing again | | 🟠 WARNING | Score dropped in any single dimension by > 3 points, or a new issue appeared | GEO score dropped from 14 to 10; a new 404 page detected | | 🟢 POSITIVE | Score improved in any dimension, or a fix was confirmed working | Core Web Vitals improved; schema markup now detected | | ℹ️ INFO | Change detected but no clear positive/negative impact | Indexation count changed by This table grows with each scan. It provides a quick view of the site's SEO health trajectory.
Monitoring frequency recommendations
| Site type | Recommended interval | Rationale | |---|---|---| | E-commerce (active) | Weekly | Frequent product/price changes, competitive market | | SaaS / B2B | Bi-weekly | Moderate content velocity, feature pages change | | Blog / Media | Weekly | New content published frequently | | Local business | Monthly | Slower pace of change, review monitoring more important | | Corporate / Institutional | Monthly | Rarely changes, but regressions must be caught | | Post-fix verification | 1 week after deployment | Confirm fixes took effect before next audit |
Output summary
After generating the monitoring report, present:
═══════════════════════════════════════════
SEO MONITORING REPORT — [domain]
Scan: [date] | vs Baseline: [date] ([N] days)
═══════════════════════════════════════════
📊 Score evolution: [baseline]/90 → [current]/90 ([+/-delta])
✅ Fixes confirmed: [N] of [total] recommendations implemented
⏳ Pending fixes: [N] not yet applied
🔴 Regressions: [N] metrics worsened
🆕 New issues: [N] new problems detected
📁 Files updated:
monitoring/delta-[date].md — Full comparison report
monitoring/delta-[date].json — Machine-readable delta
monitoring/alerts.md — Active alerts
monitoring/history.md — Score timeline
[If regressions detected:]
⚠️ Action needed: [brief description of most critical regression]
[If all good:]
✅ All stable — no critical changes since baseline.
Next scan recommended: [date]
Would you like me to:
1. Detail the regressions and suggest fixes?
2. Re-run the full audit for a complete re-score?
3. Generate an updated implementation checklist?
Integration with scheduled tasks
When running as a scheduled task (Pattern 3 from the skill system architecture):
Cron / scheduled task setup
# Weekly SEO monitoring — runs every Monday at 7am
0 7 * * 1 claude "Run SEO monitor on https://[domain]"
# Bi-weekly
0 7 * * 1 [ $(( $(date +%V) % 2 )) -eq 0 ] && claude "Run SEO monitor on https://[domain]"
# Monthly (1st of month)
0 7 1 * * claude "Run SEO monitor on https://[domain]"
Claude Code / Cowork scheduled tasks
Schedule: "Every Monday at 7am, run a quick SEO scan on https://[domain] and compare to baseline. If any critical alerts, notify me."
The monitor should:
- Load the baseline silently
- Run the quick scan
- Generate the delta
- Only notify the user if there are 🔴 CRITICAL or 🟠 WARNING alerts
- If all clear, log the scan silently to
monitoring/history.md
> Pattern 3 applied: Scheduled orchestration. The monitor runs on a schedule without user intervention. It triggers alerts only when something needs attention. The user reviews results, not processes.
Edge cases
| Situation | Handling | |---|---| | Site is down during scan | Log the failure, retry once after 5 min. If still down → 🔴 CRITICAL alert "Site unreachable" | | Domain changed | Detect via redirect. Ask user to confirm new domain. Create new baseline. | | Major redesign detected | If > 50% of tracked URLs return 404 or different structure → 🟠 WARNING "Major site changes detected — recommend full re-audit" | | CMS changed | Detect via cms_detected mismatch. Flag in delta report. | | robots.txt disappeared | 🔴 CRITICAL alert — all crawlers may be blocked | | Score dropped but fixes were applied | Check if fixes are still in place (could be overwritten by CMS update). Flag specifically. | | Baseline is > 6 months old | ℹ️ INFO "Baseline is aging — consider running a full re-audit to reset" |
Best practices
Data continuity
- Never overwrite
baseline.json— it's the reference point - Each scan creates a new
scan-[date].json— full history preserved - If a full re-audit is done, offer to update the baseline (with user confirmation)
Alert fatigue prevention
- Don't alert on changes within normal variance (< 2% indexation change, < 0.5pt score change)
- Group related alerts (if 3 meta tags regressed on the same template, that's 1 alert, not 3)
- Distinguish between "fix not applied yet" (expected) and "fix was applied but broke" (critical)
Comparison accuracy
- Always compare against the same data points
- If the collector methodology changed between scans, note it in the delta report
- Estimations vs. real data: if baseline was estimated and current has real data, flag the methodology difference
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jgoullet
- Source: jgoullet/seo-geo-audit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.