|
| 1 | +--- |
| 2 | +name: weekly-audit |
| 3 | +description: "One-shot weekly SEO audit that composes the seo-performance MCP tools into a single prioritized digest with proposed edits per URL. Triggers: 'weekly audit', 'what should I refresh this week', 'top 5 SEO actions', 'cross-signal audit', 'find my highest-leverage edits'." |
| 4 | +--- |
| 5 | + |
| 6 | +# weekly-audit |
| 7 | + |
| 8 | +Companion skill for `@automatelab/seo-performance-mcp`. Where the base `seo-performance` skill routes a single question to the right tool, **this skill runs the full weekly playbook end-to-end** and returns one ranked action list. |
| 9 | + |
| 10 | +The MCP server already exposes an `audit_cohort` prompt that runs a cohort report and emits briefs. This skill is one layer higher: it **cross-references three independent signals** (quick wins, cohort verdicts, citation losses), dedupes by URL, and ranks by how many signals agree. |
| 11 | + |
| 12 | +## When to use |
| 13 | + |
| 14 | +The user wants the answer to "what should I edit this week" in one go - not a chat-driven exploration. For single-URL questions, defer to the base `seo-performance` skill. |
| 15 | + |
| 16 | +## What it does |
| 17 | + |
| 18 | +Read-only. Proposes edits. Never applies them. Wiring the apply path is up to your CMS - keep audit and apply as separate skills. |
| 19 | + |
| 20 | +## Steps |
| 21 | + |
| 22 | +### 1. Pull three lists in parallel |
| 23 | + |
| 24 | +Issue these in a single message: |
| 25 | + |
| 26 | +- `gsc.quick_wins` with `window=90, min_position=5, max_position=15, min_impressions=50, limit=20` |
| 27 | +- `cohort.report` with `min_age_days=90, window=30, limit=20` |
| 28 | +- `posts.list` with `limit=50, min_age_days=30` (input for the citation sweep) |
| 29 | + |
| 30 | +### 2. Citation-loss sweep |
| 31 | + |
| 32 | +For the top 15 URLs from `posts.list` (oldest first), call `posts.cite_loss` per URL. Keep only URLs with `losses[].length > 0`. If `CITATION_INTELLIGENCE_URL` is unset, this step returns empty - skip it. |
| 33 | + |
| 34 | +### 3. Dedupe and rank |
| 35 | + |
| 36 | +Merge by URL. A URL appearing in multiple lists gets a priority boost: |
| 37 | + |
| 38 | +| Signal | Weight | |
| 39 | +|---|---| |
| 40 | +| `cohort.report` verdict = `refresh` or `merge` | 3 | |
| 41 | +| `gsc.quick_wins` has any query at 0% CTR | 2 | |
| 42 | +| `posts.cite_loss` has losses | 2 | |
| 43 | +| `cohort.report` verdict = `expand` or `double_down` | 1 | |
| 44 | +| `gsc.quick_wins` low-CTR only | 1 | |
| 45 | + |
| 46 | +Sort by total weight desc, then by `cohort.report` confidence desc. Take top 5. |
| 47 | + |
| 48 | +### 4. Per top-5 URL, propose one concrete edit |
| 49 | + |
| 50 | +Pick the single highest-lift edit for the dominant signal: |
| 51 | + |
| 52 | +- **Quick-win URL with 0% CTR query at position 5-15** -> rewrite `meta_title` using the query verbatim, under 60 chars. |
| 53 | +- **`refresh` verdict with `decay_30d_over_30pct`** -> propose a new H2 + intro paragraph targeting the top GSC query. |
| 54 | +- **`merge` verdict** -> name the sibling URL and recommend a 301 target. |
| 55 | +- **Citation loss** -> propose H1 + lead-paragraph phrasing that mirrors the lost query verbatim (LLMs cite phrases, not paraphrases). |
| 56 | +- **`expand` verdict** -> name 3 FAQ questions to add (pull from `posts.snapshot` top queries). |
| 57 | + |
| 58 | +### 5. Output format |
| 59 | + |
| 60 | +Markdown digest. For each of the 5: |
| 61 | + |
| 62 | +``` |
| 63 | +## <n>. <URL> -> <verdict label or "quick-win"> |
| 64 | +
|
| 65 | +**Why:** <one-sentence plain-English reason> |
| 66 | +
|
| 67 | +**Numbers:** clicks <X>, impressions <Y>, avg pos <Z>, top query "<q>" (<CTR>% at pos <P>) |
| 68 | +
|
| 69 | +**Proposed edit:** <verbatim copy of the new meta_title / H1 / FAQ block> |
| 70 | +``` |
| 71 | + |
| 72 | +End with a one-line summary: "Top 3 to ship this week: <url1>, <url2>, <url3>." |
| 73 | + |
| 74 | +## House-style rules - fill in for your site |
| 75 | + |
| 76 | +The MCP doesn't know your brand voice. Before proposing edits, the skill should enforce **your** rules. Drop a list here when adopting the skill, e.g.: |
| 77 | + |
| 78 | +- Title case vs sentence case |
| 79 | +- Em-dash policy (allowed / replace with hyphen / replace with comma) |
| 80 | +- Emoji policy (allowed in titles / body only / banned) |
| 81 | +- Canonical URL shape (e.g. `/blog/<slug>/` vs `/<slug>/`) |
| 82 | +- Forbidden words or phrases |
| 83 | +- Persona / voice notes (plain words, no jargon, etc.) |
| 84 | + |
| 85 | +If a proposed edit violates a rule, rewrite it before showing. |
| 86 | + |
| 87 | +## What this skill does NOT do |
| 88 | + |
| 89 | +- It does not apply edits. No CMS writes. The output is a digest you paste into your CMS or hand to a future apply-skill. |
| 90 | +- It does not duplicate the MCP. Tool contracts live in the MCP server. |
| 91 | +- It does not auto-publish, auto-tag, or auto-redirect. |
| 92 | + |
| 93 | +## Known limitations |
| 94 | + |
| 95 | +- **Sitemap `<lastmod>` is unreliable** if a recent deploy reset all values. For accurate age filtering, configure Ghost (or `POSTS_LIST`) so per-URL `getPostMeta` has a real source. |
| 96 | +- **Verdict engine needs >=90-day-old posts** to fire useful verdicts. New sites get mostly `hold/fresh_post_too_young`. Lean on `gsc.quick_wins` (no age filter) until the cohort matures. |
| 97 | +- **Citation-loss step is a no-op without `CITATION_INTELLIGENCE_URL`.** Set it when ready; until then the sweep contributes nothing to ranking. |
0 commit comments