SEO Opportunity Matrix

One question: where does the next unit of SEO effort pay best? The answer is a ranked table, not an audit. Every row must name one action.

Render through growth-report-format. Open it alongside this skill. The ranked table below is this skill's Findings section; the format skill owns the frame, the provenance header, number formatting, and the Method block.

Tools this skill calls

Need Tool Key arguments
Impressions, clicks, CTR, position by page mcp__google_search_mcp__gsc_search_analytics dimensions: ["page"], then ["query"] per page
Sessions and conversions by landing page mcp__google_search_mcp__ga4_run_report dimensions: ["landingPagePlusQueryString"]
Which events count as conversions mcp__google_search_mcp__ga4_key_events property id

Agentman defaults: GSC sc-domain:agentman.ai, GA4 property 471838641. Any other property: resolve the target first.

Target resolution

  1. If the request names a property/site, use it.
  2. Otherwise read data/ for a registry file naming a default target. Files prefixed example- and scrubbed placeholders never bind a default.
  3. Otherwise ask which GSC property and GA4 property ID to run against.

Inputs (arguments with defaults)

Argument Default Why it's an argument
window last 28 full days shorter is noisy, longer hides trends
min_impressions 100 below this, CTR is noise
conversion_event ask, or the property's starred key events never guess what "conversion" means for a business

Step 0 — check that conversions are measured at all

Call ga4_key_events before weighting anything by conversion, and compare the starred list against events actually firing in ga4_run_report.

If the starred events are dead, or real intent events are unstarred, the conversion weight collapses to its floor for every page and the ranking silently degrades to "impressions × CTR gap" while still presenting itself as conversion-weighted. Say so in the output and rank on search signals alone rather than pretending the weighting worked.

This is not hypothetical. A verified state on this property: six events starred, five with zero occurrences in 28 days, while skill_cta_click (102), skill_try_now (70) and signup_click (10) fired unstarred. Every run before that was fixed was effectively unweighted.

Procedure

1. Pull GSC by page

gsc_search_analytics with dimension page over window: impressions, clicks, CTR, position. Keep pages ≥ min_impressions.

Segment before concluding — apply references/analysis-techniques.md: split brand vs non-brand before any CTR claim, read query shapes (typed → titles/URLs; conversational → subheads/FAQ; unserved demand → demand-test page, never a claim), and bucket by position (4–10 is the matrix's sweet spot; 11–20 high-impression terms are content-depth wins, not title wins).

Honesty rule: only totals with totals_complete: true are safe to sum. Row sets omit anonymized low-volume queries — never present a sum of rows as a site total.

2. Pull GA4 by landing page

ga4_run_report with dimension landingPagePlusQueryString, metrics: sessions and conversion_event count. Same window.

3. Join

Normalize URLs before joining (strip protocol, trailing slash, query string unless meaningful; hostnames must match). Report join coverage: "X of Y GSC pages matched a GA4 landing page." A join rate under ~70% is itself a finding (redirects, canonicals, or untagged hosts) — say so and stop ranking until explained. Then run the per-page GSC↔GA4 reconciliation check: a page whose GSC clicks and GA4 organic sessions diverge persistently has a redirect, tracking, or canonical problem, and its row is quarantined until explained.

4. Score

  • CTR gap = expected CTR at its position − actual CTR, computed on the non-brand segment. Expected-CTR defaults live in references/expected-ctr.md; they are documented defaults, not truth — override per property once it has its own curve.
  • Conversion weight = conversions / session for the page, normalized against the property median (floor 0.25 so zero-conversion pages still rank by traffic value). If Step 0 found conversion measurement broken, skip this factor and say the ranking is unweighted.
  • Opportunity = impressions × CTR gap × conversion weight.

5. Classify the action (one per row)

Signal Action Hand off to
High impressions, CTR well below position-expected title/meta rewrite seo-title-rewrite
Position 11–20, high impressions content depth + internal links content brief
Ranks and clicks but doesn't convert landing-page/CTA problem, not SEO funnel audit
Converts well, position 4–10 the priority rewrite — highest leverage in the set seo-title-rewrite
Unserved demand (impressions, nothing to click) demand-test page with its own tracked CTA seo-keyword-competitor-research

Before promising gains on any row, check that the diagnosis is a title problem and not an intent mismatch. A page can rank well and still be barely clicked because the queries feeding it are broader than anything it could satisfy; seo-title-rewrite carries the diagnosis table that separates the two. Routing an intent mismatch to a rewrite burns a baseline and produces a false LOSS.

Output — the Findings section

A markdown table, ranked by opportunity score, max 15 rows: page, impressions, position, CTR (actual vs expected, non-brand), conversions, score, action. Number formatting per growth-report-format — CTR to two decimals, position to one, counts as plain integers.

Then the provenance header (the format skill's header-block form, since one window covers the whole table):

Source: GSC property <p>, GA4 property <id>
Window: <start>–<end> · Fetched: <timestamp>
Join coverage: <x>/<y> pages · Quarantined rows: <n>
Conversion weighting: applied | UNWEIGHTED (key events dead — see Step 0)
Expected-CTR curve: default | property-specific · Brand terms: <list-file>

Save the run to data/matrix-<target>-<date>.md so the next run can diff.

Honesty rules

  • Position is an average across queries and impressions, not a rank. A page "at 7.3" may rank 2 for one query and 40 for another. When a single page drives a decision, break it down by query first.
  • Never report a blended brand+non-brand CTR; a shifting brand mix masquerades as a CTR change.
  • GSC and GA4 count differently (clicks ≠ sessions). Never present the join as reconciliation; it is correlation at page grain.
  • CTR-gap scoring compares a page to the average page at that position. SERP features (AI overviews, shopping, snippets) depress whole-query-class CTR — and this suite cannot see them. Check one high-opportunity page's SERP by hand before promising gains, and when a CTR gap is unexplained, say the explanation may be outside what these tools return.
  • If two runs disagree, re-pull before explaining. Numbers get stale; both runs carry fetch timestamps for exactly this reason.

Working copies and publishing

Public master: data/ holds fictional example-* files only. To use on a real property, clone this skill privately and write the real registry, brand term list, and run history into the clone. Never publish real property IDs, event taxonomies, or run outputs — they are an analytics-poisoning kit for GA4's unauthenticated collect endpoint and competitive intelligence besides.

SEO Opportunity Matrix

By Agentman

Rank a property's pages by where SEO effort pays best: join Search Console (impressions, CTR, position) with GA4 (conversions by landing page) and score each page by ranking gap × conversion value. Re

Marketingv1.2.0
seogscga4growthanalyticsprioritizationacquisitionmcp-bound

Included Files

  • SKILL.md(8.1 KB)— shown above

Related skills

Others that solve nearby problems.

SEO Content StrategistThis skill should be used when developing SEO content strategy, performing keyword research, creating content briefs, or optimizing existing content. It provides keyword clustering methodologies, content gap analysis frameworks, topical authority mapping, and SERP feature targeting strategies. Use for content planning, competitive SEO analysis, content brief creation, or content optimization.AEO Blog GeneratorThis skill should be used when generating blog posts optimized for AI answer engine citation and visibility. It produces content structured for extraction by ChatGPT, Google AI Overviews, Perplexity, Brand Strategy AgentDevelop comprehensive digital marketing strategy as Step 3 of the brand marketing workflow. This skill should be used when creating marketing plans from research and persona data. It takes audience analysis and personas as input and produces a strategic marketing plan that feeds into voice development. Use when users say 'create marketing strategy', 'develop go-to-market plan', 'marketing roadmap', or as Step 3 of the 6-agent brand workflow.Competitive Intelligence AnalystThis skill should be used when analyzing competitors, creating battle cards, identifying market positioning gaps, or developing competitive strategies. It provides frameworks for systematic competitor monitoring, positioning analysis, win/loss evaluation, and battle card creation. Use for competitive research, sales enablement content, strategic planning, or responding to competitive threats.

Ready to use this skill?

Attach it to your Agentman agents, or clone it and make it yours.

Free to use. Clone this and any other public skill with a free Agentman account — publishing your own is free up to 10 skills.

AgentSkills is more than a copy-paste library

  • Versioned, not pastedEdit a skill once and every agent using it follows the new version.
  • Shared with your teamOne library with per-skill access control and a record of who did what.
  • One connectionA single MCP link works across Claude, ChatGPT, Cursor and Agentman agents.
Explore AgentSkills →

Or try it in an assistant