agentleFS
keuperakeupera/seo-skills/skills/search-console-analysis/SKILL.md

search-console-analysis

Skill0 starsChanged 2 months agoMITView on GitHub

Extract decisions from Google Search Console data — striking distance pages, CTR gaps, decay, index coverage problems and query analysis. Use whenever the user mentions Search Console, GSC, search analytics, impressions, clicks, average position, CTR, the Pages or Coverage report, indexing status, the Performance report, or exports query data. Also use when the user asks what to work on next, why traffic changed, or which pages are underperforming.

  • Sends data out

The file

We split this skill into the rules it gives an agent

4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈4

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Search Console is the only free source of truth for how Google actually sees a site, and most people look at the total-clicks line and …

    line 8
  2. Distinctive:

    Are the pages still indexed?: Check the Pages report before theorising about quality.

    line 103
  3. Distinctive:

    Search Console now reports on AI Overviews and AI Mode, and it's the only accurate source for those surfaces.

    line 109
  4. Distinctive:

    AI Overview impressions are counted: when your link appears in the overview, and clicks when someone clicks it.

    line 111

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Search Console Analysis

Search Console is the only free source of truth for how Google actually sees a site, and most people look at the total-clicks line and close it. Everything useful is one filter deeper.

Two limitations to hold in mind throughout. Data is sampled and anonymised, so long-tail queries are omitted and the numbers won't reconcile with analytics. And average position is an average of averages — a page averaging position 8 might rank 3 for one query and 40 for another, which is a completely different situation and needs a completely different fix.

The five queries that produce work

1. Striking distance

Pages averaging position 5 to 20 with real impressions. Already judged relevant, one improvement from real traffic. Best return on the list.

Performance → Pages → filter position 5-20, sort by impressions

For each: run the query, read what beats you, and fix the specific gap. Usually it's an unanswered sub-question or a format mismatch, not writing quality.

2. CTR gaps

Pages whose CTR is well below what their position should deliver. Rough expectations, and they vary enormously by query type:

PositionTypical CTR
125-35%
2-310-18%
4-64-8%
7-101-3%

A page at position 3 with 2% CTR has a title problem, a description problem, or something above it eating the click. Check the SERP before rewriting anything. If an AI Overview, a video carousel or a shopping block sits above the results, the clicks aren't there to win and the answer is a different query, not a better title.

3. Decay

Compare the last 90 days against the same period a year prior, sorted by clicks lost. This is the input to content-refresh and it's usually the highest-value list on a mature site.

4. Queries you rank for but didn't target

Filter a page to its queries and read past the top five. There are almost always terms you didn't intend to rank for, some with more commercial intent than the one you did target. Two actions: strengthen the page for that term, or split it into its own page if it deserves one.

5. Index coverage

The Pages report tells you exactly which URLs Google excluded and why. Read the reason strings literally, they're precise:

ReasonMeansAction
Crawled, currently not indexedGoogle saw it, judged it not worth indexingQuality or duplication problem. Usually thin content
Discovered, currently not indexedNever crawledCrawl budget, or the page looks low value from links alone
Duplicate, Google chose different canonicalYour canonical was overriddenSee canonical-duplicate-content
Alternate page with proper canonicalWorking as intendedNothing
Excluded by noindexIntentional, or a bugCheck it's intentional
Soft 404Thin or empty page returning 200Add content or return a real 404
Blocked by robots.txtCan't be crawledCheck it's intentional

"Crawled, currently not indexed" growing over time is the signal that matters most on content-heavy sites. It's Google saying the pages aren't worth the index space, and the answer is fewer, better pages.

Pulling the data

The UI caps exports at 1,000 rows, which is the main reason people miss things. The API doesn't.

# Requires an OAuth token with the webmasters.readonly scope
curl -s -X POST \
  "https://searchconsole.googleapis.com/webmasters/v3/sites/https%3A%2F%2Fexample.com%2F/searchAnalytics/query" \
  -H "Authorization: Bearer $GSC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "startDate": "2026-06-01",
    "endDate": "2026-09-01",
    "dimensions": ["page", "query"],
    "rowLimit": 25000,
    "dataState": "final"
  }' > gsc.json

# Striking distance: position 5-20, sorted by impressions
python - <<'PY'
import json
rows = json.load(open('gsc.json'))['rows']
hits = [r for r in rows if 5 <= r['position'] <= 20 and r['impressions'] >= 100]
for r in sorted(hits, key=lambda r: -r['impressions'])[:40]:
    page, query = r['keys']
    print(f"{r['impressions']:>7.0f} imp  pos {r['position']:>4.1f}  ctr {r['ctr']*100:>4.1f}%  {query}  →  {page}")
PY

Set dataState: "final" for analysis. The default includes fresh, unfinalised data that shifts under you.

Pull 16 months, which is the maximum retained, and store it. The single most useful thing you can do in Search Console is start exporting monthly now, because the 16-month window is a rolling one and the data is gone afterwards. The BigQuery bulk export is the durable version of this and it's free to turn on.

Diagnosing a traffic change

Order matters. Each step rules out a category.

  1. Impressions or position? Impressions down with position flat means demand changed or the SERP changed. Position down means ranking changed. Completely different problems.
  2. Sitewide or a section? Filter by URL path. Sectional drops are usually technical.
  3. One query or many? A single query dropping is competitive. All queries dropping is site-level.
  4. Which device and country? Mobile-only drops point at rendering or performance. Country-specific drops point at hreflang or a local competitor.
  5. What's the date? Compare against known update dates, and against your own deploy log. Deploys cause more traffic drops than algorithm updates do, and they're much easier to fix.
  6. Are the pages still indexed? Check the Pages report before theorising about quality.

Seasonality accounts for a lot of what gets diagnosed as an algorithm hit. Always compare year over year, not month over month.

The AI surfaces

Search Console now reports on AI Overviews and AI Mode, and it's the only accurate source for those surfaces. Two things to know:

  • AI Overview impressions are counted when your link appears in the overview, and clicks when someone clicks it. Expect low CTR by nature.
  • A page can lose clicks without losing rankings because the answer is now given above the results. That's a real and increasingly common pattern, and no amount of title rewriting fixes it. The response is to target queries where the answer requires a visit, and to make sure you're the cited source when it doesn't. See featured-snippet-passages.

What Search Console doesn't cover is ChatGPT, Perplexity, Claude and Copilot, where there's no equivalent report from anyone. Keupera connects Search Console data alongside AI Brand Radar for those engines and its own analytics, over MCP, so query performance and AI citation can be read together rather than in separate tools:

claude mcp add --transport http keupera https://mcp.keupera.com/mcp -s user

Don't do these

  • Don't read average position as a rank. It's an average across queries, devices and countries.
  • Don't compare Search Console to analytics. Different definitions, different sampling. They will never match.
  • Don't act on a week of data. Two weeks minimum, four for anything seasonal.
  • Don't ignore the 1,000-row export cap. Most of the interesting data is below it.
  • Don't request indexing repeatedly. It doesn't help and it isn't a ranking action.
  • Don't chase the queries with no clicks and no position. They're usually impression noise from long-tail variants.

Related skills

content-refresh, keyword-cannibalization, technical-seo-audit, featured-snippet-passages, canonical-duplicate-content, keyword-research-briefs

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.