Skip to content
Back to skills

Content Decay Detector

ASecurity

Use this skill when the user asks to detect content decay, find declining pages, audit SEO performance drops, identify pages losing organic traffic, run a content decay audit, check which blog posts or landing pages are losing clicks or sessions, or surface pages with falling rankings and engagement. Requires Google Search Console and Google Analytics 4. Produces a severity-scored decay report with root cause diagnosis (visibility loss, SERP issue, tracking mismatch, or engagement decay) plus...

  • 9 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added June 5, 2026
content-marketinggoperformance

Works with

  • cli
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned June 5, 2026

npx -y skills add twominutereports/marketing-skills --skill content-decay-detector --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Content Decay Detector?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Content Decay Detector
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/twominutereports-content-decay-detector/badge)](https://www.skillsdirectory.com/skills/twominutereports-content-decay-detector)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tmr-content-decay-detector
description: Use this skill when the user asks to detect content decay, find declining pages, audit SEO performance drops, identify pages losing organic traffic, run a content decay audit, check which blog posts or landing pages are losing clicks or sessions, or surface pages with falling rankings and engagement. Requires Google Search Console and Google Analytics 4. Produces a severity-scored decay report with root cause diagnosis (visibility loss, SERP issue, tracking mismatch, or engagement decay) plus an HTML dashboard artifact with a prioritized action table.
version: 1.0.0
---

# Content Decay Detector

## Purpose

Detect content decay across your website by combining Google Search Console (GSC) and Google Analytics 4 (GA4) data. The skill compares the last 30 days against the prior 30-day period, identifies candidate pages with meaningful organic decline, scores each page by severity, diagnoses the root cause using a structured case-matching framework (visibility loss, SERP issue, tracking mismatch, or engagement decay), and surfaces a prioritised action list — inline in chat plus a full HTML dashboard.

This is not a simple traffic comparison. The skill uses explicit decay logic: a page must fail a threshold test on clicks OR organic sessions to enter the candidate list, and root cause is inferred from the pattern of clicks vs impressions vs CTR vs sessions vs engagement — not from any single metric in isolation.

## Connectors required

This skill uses the following TMR connectors:
- Google Search Console
- Google Analytics 4

Both are mandatory. The skill will not proceed if either is unavailable. GSC reveals SEO visibility trends (ranking, impressions, CTR); GA4 reveals business impact (sessions, engagement, conversions). Together they enable real insight; neither alone is sufficient.

---

## Runtime procedure

Follow these steps in order. Do not skip steps. Do not rearrange.

### 1. Check that TMR's tools are available

Inspect your available tools. The Two Minute Reports MCP exposes these tool names: `verify_team_details`, `list_connectors`, `get_ad_accounts`, `generate_query`, `get_data_insights`. The prefix may vary — users name their MCP connections differently (e.g., "Two Minute Reports", "TMR", "TwoMinuteReports", or a custom name). Match by tool function and the Two Minute Reports MCP server (URL: `https://mcp.twominutereports.com/mcp`), not by exact prefix.

**If none of these tools are present**, tell the user:

> *"This skill needs Two Minute Reports to be connected to your Claude account, but I don't see it in your available tools.*
>
> *Two Minute Reports is an analytics platform that lets you query your marketing data (ads, analytics, e-commerce, etc.) from inside Claude. You'll need to connect it once, then this skill will work.*
>
> *Here's the setup guide: https://twominutereports.com/help/mcp/claude*
>
> *Once it's connected, run this skill again."*

If a `suggest_connectors` capability is available, use it to surface a one-tap connect option. Then stop.

If the tools ARE present, hold the resolved prefix internally and continue.

---

### 2. Verify team details and authentication

Call `verify_team_details`.

- **Success** → note the team name, continue.
- **Auth / session failure or empty team** → tell the user:

  > *"Two Minute Reports is connected, but I couldn't verify your team — your session may have expired. Please reconnect Two Minute Reports, then run this skill again. Setup reference: https://twominutereports.com/help/mcp/claude"*

  If `suggest_connectors` is available, trigger it for Two Minute Reports. Stop.

- **Any other failure** → *"Couldn't reach Two Minute Reports right now — please try again in a moment."* Stop.

---

### 3. Verify both required connectors are provisioned in TMR

Call `get_ad_accounts` with `selected_connectors: ["Google Search Console", "Google Analytics 4"]`.

- **Both return accounts** → continue.
- **Either is missing or empty** → tell the user which connector is missing and ask them to add it inside Two Minute Reports, then stop. Do not attempt a partial run.

---

### 4. Locate skill folder and load configuration

Look for this skill's install folder:
1. `/mnt/skills/user/tmr-content-decay-detector/`
2. If not found, `find /mnt/skills -name "tmr-content-decay-detector" -type d 2>/dev/null`, use first result.
3. If still not found, skip all config read/write and fall through to interactive account selection.

Hold the resolved path as `<install-path>`.

Try to read `<install-path>/config.json`.

**If `saved: true`:**
- Tell the user: *"Using your saved configuration: [list account labels]. Say 'change config' to update."*
- Use stored accounts and `auto_confirm_query`.

**If `saved: false`, file missing, or unreadable:**
- Reuse the `get_ad_accounts` response from step 3.
- Present accounts grouped by connector. Ask:

  > *"Which Google Search Console property and GA4 property would you like to analyse? Pick one each — ideally matching the same website."*

  Wait for selection.

---

### 5. Choose the decay window

Ask the user:

> *"Which comparison window would you like?*
> *• Last 30 days vs previous 30 days (default)*
> *• Last 60 days vs previous 60 days*
> *• Last 90 days vs previous 90 days"*

Use the chosen window for all queries. If the user says nothing or presses ahead, default to 30 days.

---

### 6. Run the two data-collection prompts

#### Prompt A — GSC page-level decay signals

**Prompt text:**
> For each landing page, show clicks, impressions, CTR, and average position for the last [WINDOW] days vs the previous [WINDOW] days, broken down by page URL.

a. Call `generate_query` with the user's selected GSC property and the prompt above (substituting the chosen window).

b. Unless `auto_confirm_query` is `true`, present the query summary and wait for explicit user confirmation.

c. Call `get_data_insights` with `user_confirmed: "true"`.

d. Hold the returned data as **GSC_DATA**.

---

#### Prompt B — GA4 organic session and engagement decay

**Prompt text:**
> For each landing page, show organic sessions, engaged sessions, and key events for the last [WINDOW] days vs the previous [WINDOW] days, broken down by full page URL, filtered to organic traffic only.

a. Call `generate_query` with the user's selected GA4 property and the prompt above.

b. Unless `auto_confirm_query` is `true`, confirm with the user.

c. Call `get_data_insights` with `user_confirmed: "true"`.

d. Hold the returned data as **GA4_DATA**.

---

### 7. Apply the Content Decay Detection logic

Once both datasets are in hand, execute the following logic in your reasoning before producing any output. Do not show this working to the user — only surface the conclusions.

#### Step 7A — Build the candidate list

Join GSC_DATA and GA4_DATA on page URL (use fuzzy matching if trailing slash or protocol differs).

Flag a page as a **decay candidate** if **either** of the following is true:
- GSC clicks dropped **> 20%** period-over-period, OR
- GA4 organic sessions dropped **> 20%** period-over-period.

Discard pages with fewer than 50 combined clicks in either period (too low-traffic to score reliably).

#### Step 7B — Score each candidate

Calculate a **Decay Score** (0–100) using this weighted formula:

```
Decay Score =
  (click_drop_pct * 0.40) +
  (session_drop_pct * 0.30) +
  (impression_drop_pct * 0.20) +
  (position_decline_pct * 0.10)
```

Where each value is the percentage decline (0–100 scale; use 0 if the metric improved). Cap the score at 100.

Map the score to a **severity tier**:
- **Critical** — score ≥ 60, or any single metric dropped > 60%
- **High** — score 40–59, or any single metric dropped 40–60%
- **Medium** — score 20–39, or any single metric dropped 20–40%

Sort the candidate list: Critical first, then High, then Medium; within each tier, sort by Decay Score descending.

#### Step 7C — Diagnose root cause for each candidate

Apply the following case logic, in order. Assign the **first matching case**.

| Case | Condition | Label | Likely causes |
|---|---|---|---|
| **A — Visibility Loss** | Impressions down AND clicks down (both >15%) | Ranking decline | Algorithm update, competitor overtook, indexation issue, seasonality |
| **B — SERP Issue** | Impressions stable (< 10% change) AND CTR down > 15% | Click-through problem | Weaker title/meta, SERP feature stealing clicks, intent mismatch |
| **C — Tracking Mismatch** | GSC clicks stable (< 10% change) AND GA4 sessions down > 20% | GA4 / tracking issue | GA4 misconfiguration, attribution change, UTM stripping, tag firing issue |
| **D — Engagement Decay** | Sessions stable or only mildly down (< 20%) AND engaged sessions OR key events down > 25% | Traffic quality problem | Irrelevant queries landing, content–intent mismatch, UX regression |
| **E — Mixed / Unclear** | Doesn't cleanly match A–D | Needs investigation | Review multiple signals manually |

For Case C, explicitly flag this to the user in the insights and dashboard — it suggests a measurement problem, not a content problem, and should be investigated before taking content action.

---

### 8. Produce the dual output

#### Insights (inline chat)

Write a 200–350 word insights summary in chat. Structure:

1. **Headline** — total pages analysed, total candidates flagged, breakdown by severity tier.
2. **Top 3 decaying pages** — URL (shortened), severity, decay score, root cause label, and the single most telling signal (e.g. "CTR fell [X%] while impressions held steady → Case B").
3. **Pattern observation** — is there a dominant root cause across candidates? Any cluster (e.g. blog posts from a specific period, a URL pattern)?
4. **Priority action** — one concrete next step based on the most severe case.

Match the tone and structure of this template (fill `[brackets]` with the user's actual data):

---
*[N] pages analysed across [property]. [N] decay candidates identified: [N] Critical, [N] High, [N] Medium.*

*Top decliners this period:*
*• [Page URL] — [Severity]. Decay score [X]. [Root cause label]. Key signal: [most telling metric change].*
*• [Page URL] — [Severity]. Decay score [X]. [Root cause label]. Key signal: [most telling metric change].*
*• [Page URL] — [Severity]. Decay score [X]. [Root cause label]. Key signal: [most telling metric change].*

*Pattern: [observation about whether Case A/B/C/D dominates, or whether decay is spread across types. Note any URL cluster or content type pattern.]*

*Priority action: [one specific, actionable recommendation tied to the highest-severity finding — e.g. "Audit the title tag and meta description for [page] — impressions held but CTR collapsed, suggesting a SERP presentation issue (Case B)." or "Investigate GA4 tracking on [page] before taking content action — GSC clicks are stable but GA4 sessions dropped [X%] (Case C tracking mismatch)."]*

---

#### Dashboard (HTML artifact)

Produce a **new artifact** for this run. Do not update or replace any prior run's artifact. Title format:

`Content Decay Detector — [YYYY-MM-DD HH:MM] — [GSC property label]`

The dashboard must include:

**Metadata header** (top of page): Run date/time · GSC property · GA4 property · Comparison window · Total pages analysed

**KPI tile row** (4 tiles):
- Pages Analysed
- Decay Candidates
- Critical Pages
- Dominant Root Cause

**Decay Candidate Table** — one row per candidate page, columns:
| Page URL | Severity | Decay Score | Click Δ% | Session Δ% | Impression Δ% | Position Δ | CTR Δ% | Engaged Session Δ% | Key Events Δ% | Root Cause | Likely Cause |

- Severity tiers use colour coding: Critical = red (#EF4444), High = orange (#F97316), Medium = amber (#F59E0B).
- Root cause labels display as a pill/badge.
- Sort: Critical → High → Medium, then by Decay Score descending within each tier.
- Rows with Case C (Tracking Mismatch) display a ⚠️ icon and a tooltip: *"Clicks are stable in GSC but sessions dropped in GA4 — investigate tracking before taking content action."*

**Root Cause Breakdown chart** — horizontal bar chart showing count of candidates by root cause (Case A / B / C / D / E).

**Recommended Actions panel** — for the top 3 Critical/High pages, show a one-line recommended action based on the diagnosed root cause.

Use this colour palette and typography:
- Background: `#0F172A` (dark navy)
- Card/tile background: `#1E293B`
- Primary accent: `#6366F1` (indigo)
- Text primary: `#F1F5F9`
- Text muted: `#94A3B8`
- Font: Inter or system-ui
- Severity colours: Critical `#EF4444`, High `#F97316`, Medium `#F59E0B`
- Root cause pill colours: Case A `#3B82F6`, Case B `#8B5CF6`, Case C `#EAB308`, Case D `#10B981`, Case E `#6B7280`

---

### 9. Save configuration (first run only, if no saved config existed)

After producing the dual output, ask:

> *"Want to save your settings for future runs? This skill can remember your accounts so you don't have to pick them every time.*
>
> *• Save accounts and comparison window? (yes / no)*
> *• Auto-confirm queries on future runs? (yes / no — saves a step but you won't see the query before it runs)"*

If yes, write to `<install-path>/config.json`:

```json
{
  "version": "1.0.0",
  "saved": true,
  "accounts": {
    "Google Search Console": [{ "label": "...", "value": "..." }],
    "Google Analytics 4": [{ "label": "...", "value": "..." }]
  },
  "decay_window_days": 30,
  "currency": null,
  "auto_confirm_query": false,
  "saved_at": "<ISO 8601 timestamp>"
}
```

If the write fails, tell the user: *"Couldn't save your settings to disk — they'll be remembered for this conversation only. You'll be asked again next time."* Continue normally.

If no install folder was resolved in step 4, skip silently.

---

## Decay logic quick-reference (for runtime reasoning)

```
CANDIDATE THRESHOLD
  Flag if: clicks_drop > 20% OR organic_sessions_drop > 20%
  Exclude if: combined clicks in either period < 50

DECAY SCORE (0–100)
  = (click_drop% × 0.40)
  + (session_drop% × 0.30)
  + (impression_drop% × 0.20)
  + (position_decline% × 0.10)

SEVERITY TIERS
  Critical  → score ≥ 60 OR any single metric dropped > 60%
  High      → score 40–59 OR any single metric dropped 40–60%
  Medium    → score 20–39 OR any single metric dropped 20–40%

ROOT CAUSE CASES
  A — Visibility Loss     → impressions ↓ AND clicks ↓ (both > 15%)
  B — SERP Issue          → impressions stable AND CTR ↓ > 15%
  C — Tracking Mismatch   → GSC clicks stable AND GA4 sessions ↓ > 20%  ⚠️ flag
  D — Engagement Decay    → sessions stable AND engaged sessions OR key events ↓ > 25%
  E — Mixed / Unclear     → no clean match
```

Files in this skill

  • readme.md3.2 KB
  • skill.md14.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.