AgentStack
SKILL verified MIT Self-run

Seo Page

skill-amirjahfar1-automate-seo-with-claude-seo-page · by amirjahfar1

URL-level SEO intelligence — which keywords this page ranks for, traffic captured, position history, SERP context, and AI Search citation status. Produces a keep / refresh / consolidate / kill verdict for one page. Distinct from `seo-technical-audit` (which checks technical health, not keyword/traffic performance) and from `seo-content-brief` (which produces a NEW article from a topic). Use when…

No reviews yet
0 installs
2 views
0.0% view→install

Install

$ agentstack add skill-amirjahfar1-automate-seo-with-claude-seo-page

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Seo Page? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

> Example output: [examples/seo-page-notion-keyboard-shortcuts-20260514/PAGE.md](../../examples/seo-page-notion-keyboard-shortcuts-20260514/PAGE.md)

Page Intelligence

Show what a single URL ranks for, what traffic it captures, where its weak and strong points are, and what to do about it. The deliverable is an opinionated verdict — KEEP, REFRESH, CONSOLIDATE, or KILL — anchored in objective signals from DataForSEO's URL-level data.

Prerequisites

  • DataForSEO MCP server connected.
  • Claude's WebFetch tool available (for the page-level HTML sense-check).
  • User provides: (a) a target URL, optionally (b) target market country (default: us), (c) primary topical keyword (auto-inferred from ` + ` if not supplied).

Process

  1. Validate target & preflight. See skills/seo-firecrawl/references/preflight.md for the canonical 3-stage preflight (cost note, Firecrawl availability, Google APIs). Skill-specific notes:
  • Confirm the URL is fetchable; derive parent domain. If the user supplied a primary keyword, use it; otherwise infer it in step 3.
  • DataForSEO bills per call; this run issues ~6–10 calls typical (URL overview, ranking keywords, backlink rank, SERP context for top 3–5 keywords). Use the documented limit/ceiling params to cap.
  • Firecrawl: optional with WebFetch fallback, ~1 Firecrawl credit if available. When available, step 6 recovers og:*, twitter:*, canonical, robots meta, JSON-LD types, and hreflang count from raw ` — WebFetch returns markdown only and strips those fields. Without Firecrawl, the affected lines in PAGE.md emit (skipped — Firecrawl not installed). Pass --no-firecrawl` to treat Firecrawl as unavailable even when installed (credit conservation).
  • Google APIs: tier 1 (GSC available) unlocks step 4b (GSC URL performance + URL Inspection) after the page-authority step. See skills/seo-google/references/cross-skill-integration.md § "seo-page" for the full recipe.
  1. URL-level overview mcp__dataforseo__dataforseo_labs_google_relevant_pages (with target = URL) + mcp__dataforseo__dataforseo_labs_bulk_traffic_estimation
  • Pull keyword count, organic traffic estimate, top regions.
  • Note: traffic estimates are directional — they don't replace Google Search Console.
  1. Ranking keywords mcp__dataforseo__dataforseo_labs_google_ranked_keywords (set target = URL for exact-match URL-level results)
  • Pull every keyword the URL ranks for in the target country, with positions.
  • Sort by traffic-weighted score: volume × CTR-by-position (use a standard CTR curve: 1=28%, 2=15%, 3=11%, 4=8%, 5=7%, 6=5%, 7=4%, 8=3%, 9=2%, 10=2%, 11+=1%).
  • Take the top 3–5 as the URL's "primary keywords" for SERP work in step 5.
  1. Page authority mcp__dataforseo__backlinks_bulk_pages_summary (page-level rank) + mcp__dataforseo__backlinks_timeseries_summary
  • Current page rank (DataForSEO rank, 0–1000) and its 12-month trajectory.
  • Flag any drop > 5 points in the last 90 days.

4b. GSC URL performance + URL Inspection (only if google-api.json is present, tier ≥ 1)

  • Replaces the directional traffic estimate from step 2 with first-party Google data for the exact URL.
  • Pull GSC search analytics for the URL (last 28 days, by query and page):

python3 scripts/gsc_query.py --property "{config.default_property}" --url "{target_url}" --days 28 --json

  • Pull URL Inspection (real indexation status, canonical Google sees, last crawl date):

python3 scripts/gsc_inspect.py "{target_url}" --site-url "{config.default_property}" --json

  • If the URL's domain isn't a verified GSC property: surface "GSC: {target_domain} not verified — add it in Search Console" and continue with DataForSEO data only.
  • Surface in PAGE.md "## Snapshot": GSC last 28d: {clicks}/{impressions}/{ctr}% CTR / pos {position} and Google sees: {INDEXED|EXCLUDED} · canonical {userCanonical} → {googleCanonical} · last crawled {date}.
  • Feed into the verdict heuristic: INDEXED + impressions > 100 + position 4–10 → harden REFRESH (clear quick-win). EXCLUDED (any reason) → harden KILL or CONSOLIDATE. userCanonical ≠ googleCanonical → flag as critical issue regardless of verdict.
  • See skills/seo-google/references/cross-skill-integration.md § "seo-page" for the full recipe.
  1. SERP context mcp__dataforseo__serp_organic_live_advanced
  • For each of the 3–5 primary keywords:
  • Top 10 organic results (URL, title, snippet).
  • SERP features present (PAA, image carousel, video, shopping, etc.).
  • AIO presence and citations (read the AI Overview block from the same serp_organic_live_advanced response) — is this URL cited in the AIO?
  1. HTML sense-check WebFetch (always) + mcp__firecrawl-mcp__firecrawl_scrape (when available)
  • WebFetch first (free, instant): extract `, meta description, all , lang, word count, internal-link count, image count. WebFetch returns markdown so anything in beyond ` is lost — the next bullet recovers it.
  • Firecrawl second (1 Firecrawl credit; pass formats: ["rawHtml"]) — recovers what WebFetch can't see. Pin the format to rawHtml; the default html is post-processed and silently strips canonical, hreflang, and ` blocks on many sites. If those head fields come back zero on a site that obviously has them (any major SaaS homepage), you forgot the rawHtml` flag — re-run.
  • From metadata: og:title, og:description, og:image, twitter:card, viewport, robots meta, canonical URL.
  • From the returned rawHtml: every ` block. Parse each as JSON, list detected @type`s (Article, BreadcrumbList, Organization, Product, etc.). Note any block that fails to parse.
  • hreflang: count ` occurrences in rawHtml`.
  • If Firecrawl unavailable: the WebFetch portion still runs; populate Page basics' OG / Twitter / canonical / robots / JSON-LD / hreflang lines as (skipped — Firecrawl not installed). Don't infer from markdown.
  • Sense-check: does the page actually talk about its top-ranking keyword in title and H1? If a page ranks for keywords it doesn't address textually, that's a strong consolidation signal.
  1. Domain context mcp__dataforseo__dataforseo_labs_google_domain_rank_overview (parent domain)
  • Light-weight: parent domain rank, total keywords, total traffic. Used to contextualise the page's rank against its domain.
  1. Cannibalization check mcp__dataforseo__dataforseo_labs_google_relevant_pages
  • Pull the parent domain's pages ranked by organic traffic. Cap at the top 50 — that's where the cannibalization risk concentrates.
  • For the candidate URL's top-3 traffic-weighted keywords (from step 3), scan the peer-page list: does any other URL on the same domain rank in the top 20 for any of those keywords?
  • Cannibalization signal: any peer URL ranking ≤ 20 for the candidate's top-3 keywords. Record peer URL, keyword, peer position vs candidate position, peer traffic.
  • Cheaper than the old approach. Previous versions cross-checked via the full domain ranked-keywords endpoint on the parent domain — that can return tens of thousands of rows on large sites and is unnecessarily heavy for this question. dataforseo_labs_google_relevant_pages ranked by traffic surfaces the high-impact peers directly (cap with limit).
  • If no peer URL competes, this signal is "no cannibalization detected" — pass through to step 9.
  1. Synthesise verdict
  • Apply the verdict heuristic (see Tips) to produce KEEP / REFRESH / CONSOLIDATE / KILL.
  • For REFRESH, identify the top 3 specific changes (e.g., "add an H2 on 'alternatives' which 7 of 10 SERP winners use").
  • Write PAGE.md (output spec below).

Output format

Create a folder seo-page-{target-slug}-{YYYYMMDD}/ with:

seo-page-{target-slug}-{YYYYMMDD}/
├── PAGE.md                       (synthesised verdict + plan — primary deliverable)
├── keywords.csv                  (full keyword list with positions — load-bearing CSV the auditor walks through row-by-row)
├── 04-serp-context.md            (top 10 + AIO for top 3–5 keywords — load-bearing reference for SERP-driven REFRESH discussions)
└── evidence/
    ├── 01-url-overview.md        (raw relevant-pages + traffic-estimation output)
    ├── 02-keywords.md             (raw ranked-keywords output filtered)
    ├── 03-authority.md            (page rank + history)
    ├── 05-page-snapshot.md        (HTML extracts)
    └── 06-cannibalization.md      (peer pages on the same domain competing for the top-3 keywords)

Top-level: PAGE.md + keywords.csv + 04-serp-context.md. The other step files preserve raw API/HTML extracts in evidence/ for reproducibility — auditors lean on the CSV and SERP context, not the per-call dumps.

PAGE.md follows this shape:

# Page Intelligence: {URL}

> Snapshot dated {YYYY-MM-DD} · Country: {country} · Primary keyword: {keyword}

## Snapshot
- Ranking keywords: {n}
- Estimated monthly organic traffic: {n}
- Page rank: {rank} ({↑/↓ trajectory over 90 days})
- Primary topic: {topic}
- AIO citations: {n} of {checked} primary-keyword AIOs cite this URL
- GSC last 28d: {clicks} clicks / {impressions} impressions / {ctr}% CTR / avg position {n}  *(or `not configured` / `property not verified`)*
- Google sees: {INDEXED|EXCLUDED|...} · canonical {userCanonical} {→ googleCanonical if differ} · last crawled {YYYY-MM-DD}

## Page basics
- ``: {value}
- meta description: {value | absent}
- `og:title`: {value | absent | skipped — Firecrawl required}
- `og:description`: {value | absent | skipped}
- `og:image`: {url | absent | skipped}
- `twitter:card`: {summary | summary_large_image | absent | skipped}
- ``: {URL | self-referential | absent | skipped}
- meta robots: {index,follow | noindex,nofollow | absent | skipped}
- JSON-LD types detected: {Article, BreadcrumbList, Organization | none | skipped}
- hreflang variants: {n | skipped}

## What this page wins
- {keyword} — position {n}, ~{volume} monthly searches, ~{traffic} monthly clicks.
- ... (top 3–5)

## Almost-wins (page-2 refresh opportunities)
- {keyword} — position {n}, ~{volume} monthly searches. The top 3 SERP winners all do {pattern} that this page doesn't.
- ... (top 3 examples)

## What this page misses
- {keyword} — competitors {comp1}, {comp2} rank in top 5; this page is absent.
- ...

## Same-domain cannibalization
- {peer URL} — ranks position {n} for "{keyword}" (candidate ranks position {m}). Peer estimated traffic: {n}/mo.
- ... (only list rows where a peer URL ranks ≤ 20 for one of the candidate's top-3 keywords; if none, write "No same-domain cannibalization detected on top-3 keywords.")

## AI Search angle
- {n} of {checked} AIO queries on the URL's keywords cite this page.
- The AIOs that DON'T cite this page tend to cite {pattern} (e.g., comparison tables, step-by-step how-tos).
- Recommended GEO move: {one specific change}.

## Verdict: {KEEP | REFRESH | CONSOLIDATE | KILL}

Reasoning: {1–2 sentences anchored in objective signals from above}.

### If REFRESH — top 3 changes
1. {Specific change}
2. {Specific change}
3. {Specific change}

## Raw data
- keywords.csv — full enriched ranking-keyword list
- 04-serp-context.md — per-keyword SERP top-10 with AIO
- evidence/05-page-snapshot.md — HTML extracts

keywords.csv columns: keyword,volume,kd,position,intent,traffic_estimate,url

Tips

  • DataForSEO allows up to 2,000 calls/min, 30 concurrent. Skills pace sequentially — the 3–5 SERP queries in step 5 run one at a time.
  • DataForSEO bills per call; one URL is ~6–10 calls. Use the documented limit/ceiling params to cap.
  • Verdict heuristic:
  • KEEP: rank stable or up; traffic stable or up; top 3 keywords held in their positions; AIO citations present where AIO appears.
  • REFRESH: any of (page rank dropped >5 in 90 days; traffic dropped >20%; a top-3 keyword fell to position 11+; AIO citations missing while competitors get cited). Hardens when GSC data (step 4b) shows INDEXED + impressions > 100 + average position 4–10 (clear quick-win territory).
  • CONSOLIDATE: cannibalization detected (step 8) — a peer URL on the same domain ranks ≤ 20 for one or more of the candidate's top-3 keywords. CONSOLIDATE harden when the peer outranks the candidate AND captures higher traffic; otherwise CONSOLIDATE recommendation is "merge into the candidate" rather than "kill the candidate."
  • KILL: page rank <10 AND traffic <50/mo AND no top-10 keyword AND no internal links pointing to it. Hardens when JSON-LD schema is also absent (Firecrawl detected zero blocks) — the page has no signals for any crawler, organic or AI. Also hardens when URL Inspection (step 4b) returns EXCLUDED for any reason.
  • GSC canonical mismatch (any verdict): if step 4b detects userCanonical ≠ googleCanonical, flag this as a critical issue in PAGE.md regardless of the verdict — it points at indexing instability that the verdict on its own can't resolve.
  • Don't invent reasons. Anchor every claim in PAGE.md to a number from the raw data files.
  • When between KEEP and REFRESH, default to REFRESH — small refreshes compound.
  • The keywords.csv is the auditable trail. If a stakeholder questions the verdict, walk them through the CSV row by row.
  • For pages with very low data (new pages, <5 ranking keywords), the verdict is unreliable. Flag as "insufficient data — re-run after 60 days" rather than forcing a verdict.
  • Page-rank history all-zeros caveat: if backlinks_timeseries_summary returns rank: 0 (or equivalent) for every date in the history window, treat as "insufficient history" — don't claim a drop or recommend REFRESH based on it. Often happens for very high-authority pages where the metric is saturated, or for URLs that haven't accumulated enough longitudinal data. Cross-check with backlinks_bulk_pages_summary (current value) — if current page rank is meaningful but history is flat-zero, flag the gap explicitly in PAGE.md rather than synthesising a trajectory.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.