agentsclimarketplace

Seo geo

Skill sarbak/strategy-skills/seo-geo

Strategy, SEO/GEO, and analytics skills for Claude Code — by Emotion Machine (emotionmachine.com)

Install
npx -y skills add sarbak/strategy-skills --skill seo-geo

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Full SEO and GEO (Generative Engine Optimization) workflow for any project. Use when optimizing website content for search engines AND AI citation (ChatGPT, Perplexity, Google AI Overviews). Covers keyword research via DataForSEO API, competitor analysis, on-page audits, meta tag optimization, content gap analysis, GEO content optimization (quotable definitions, FAQ schema, structured data), and rank monitoring. Trigger on: SEO, GEO, keywords, search rankings, AI citations, meta tags, structured data, schema markup, content optimization, SERP analysis.

SKILL.md

14.1 KB, as published. Nobody here has run it

SEO & GEO Optimization

Run /seo-geo with an argument to jump to a specific phase, or run without arguments for the full workflow.

Arguments: research, audit, gaps, geo, content, monitor, or a specific page path like /pricing.

Setup

Before running, detect the project context automatically:

  1. Site domain: Read from the codebase (look for metadataBase, canonical URLs, or NEXT_PUBLIC_ env vars). Ask the user if unclear.
  2. Repo: Use the current working directory.
  3. Keyword data: Look for SEO_KEYWORDS.md in the project root. Create if missing.
  4. Framework: Detect from package.json (Next.js, Nuxt, Astro, etc.)
  5. DataForSEO credentials: Set DATAFORSEO_CREDENTIALS env var with your Base64-encoded email:password. Get an account at dataforseo.com. Example: export DATAFORSEO_CREDENTIALS=$(echo -n '[email protected]:yourpassword' | base64)

Ask the user for:

  • Voice/tone description (if not in CLAUDE.md)
  • Key competitors (domains)
  • Seed keywords for research
  • Brand concerns (name conflicts, etc.)

If any of these are already documented in CLAUDE.md, SEO_KEYWORDS.md, or memory, use those instead of asking.


Phase 1: Research

Read SEO_KEYWORDS.md first. If it's stale (>30 days) or doesn't exist, run these API calls.

1a. Keyword research

Pull search volume for target keywords via DataForSEO:

curl -s -X POST "https://api.dataforseo.com/v3/keywords_data/google_ads/search_volume/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keywords": [LIST], "location_code": 2840, "language_code": "en"}]'

Expand with keyword suggestions:

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/keyword_suggestions/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keyword": "SEED", "location_code": 2840, "language_code": "en", "limit": 50, "order_by": ["keyword_info.search_volume,desc"]}]'

Get difficulty scores:

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/bulk_keyword_difficulty/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keywords": [LIST], "location_code": 2840, "language_code": "en"}]'

Classify intent:

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/search_intent/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keywords": [LIST], "language_code": "en"}]'

1b. Competitor keyword theft

Pull non-brand keywords from competitors:

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"target": "COMPETITOR_DOMAIN", "location_code": 2840, "language_code": "en", "limit": 80, "order_by": ["keyword_data.keyword_info.search_volume,desc"]}]'

Filter out brand terms in post-processing.

1c. Check current rankings

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/ranked_keywords/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"target": "SITE_DOMAIN", "location_code": 2840, "language_code": "en", "limit": 50, "order_by": ["ranked_serp_element.serp_item.rank_group,asc"]}]'

1d. SERP analysis for top targets

curl -s -X POST "https://api.dataforseo.com/v3/serp/google/organic/task_post" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keyword":"TARGET","location_code":2840,"language_code":"en","depth":20}]'

Retrieve after ~60s:

curl -s "https://api.dataforseo.com/v3/serp/google/organic/task_get/advanced/TASK_ID" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS"

Output: Update SEO_KEYWORDS.md with fresh data. Summarize top opportunities.

1e. Adjacent keyword brainstorming

The steps above find keywords you already know about. This step finds keywords you haven't thought of — adjacent topics, competitor ecosystems, and broader search intents that your product intersects with but doesn't directly target.

Process:

  1. Map value props to broader intents. For each core feature, ask: what problem does this solve? What else do people searching for that problem also search for? Example: if your product adds iMessage to AI agents, the broader intents include "ai agent messaging", "chatbot platforms", "ai phone number", "conversational AI", "ai assistant framework comparison".

  2. Explore competitor ecosystems. Use DataForSEO keyword suggestions seeded with competitor brand names (not just your own):

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/keyword_suggestions/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keyword": "COMPETITOR_NAME", "location_code": 2840, "language_code": "en", "limit": 40, "order_by": ["keyword_info.search_volume,desc"]}]'

Run this for each major competitor. Look for "[competitor] alternative", "[competitor] vs", "[competitor] setup", "[competitor] pricing" patterns. These are high-intent keywords where you can insert yourself.

  1. Check "alternative to" and "vs" keywords. These are comparison shoppers — the highest-intent SEO traffic:
# Search volume for "[product] alternative" and "[product] vs [competitor]"
curl -s -X POST "https://api.dataforseo.com/v3/keywords_data/google_ads/search_volume/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keywords": ["PRODUCT alternative", "PRODUCT alternatives", "PRODUCT vs COMPETITOR1", "PRODUCT vs COMPETITOR2", "COMPETITOR1 alternative", "best CATEGORY 2026"], "location_code": 2840, "language_code": "en"}]'
  1. Explore adjacent communities. Use WebSearch to find what forums, subreddits, and communities discuss topics adjacent to your product. Look for recurring questions that nobody has a good answer for — those are content opportunities.

  2. Check non-English markets. If your product works internationally, run keyword suggestions in other languages (zh, es, ja, de, ko). Chinese, Japanese, and Korean tech communities often search in their own language for tools that only have English documentation — creating a zero-competition content opportunity:

curl -s -X POST "https://api.dataforseo.com/v3/dataforseo_labs/google/keyword_suggestions/live" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"keyword": "PRODUCT_NAME", "location_code": 2392, "language_code": "ja", "limit": 30, "order_by": ["keyword_info.search_volume,desc"]}]'

Location codes: 2156 (China), 2392 (Japan), 2410 (South Korea), 2276 (Germany), 2724 (Spain).

Output: A "lateral opportunities" section in SEO_KEYWORDS.md with:

  • Adjacent keyword clusters not covered by existing content
  • Competitor ecosystem keywords you can target
  • Non-English keyword opportunities
  • Recommended blog posts or pages for each cluster

Phase 2: Technical SEO Audit

2a. On-page crawl

curl -s -X POST "https://api.dataforseo.com/v3/on_page/task_post" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"target": "SITE_DOMAIN", "max_crawl_pages": 50, "max_crawl_depth": 3, "load_resources": true, "enable_javascript": true, "calculate_keyword_density": true, "validate_micromarkup": true, "check_spell": true}]'

Get summary:

curl -s -X POST "https://api.dataforseo.com/v3/on_page/summary" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"id": "TASK_ID"}]'

Get page-level issues:

curl -s -X POST "https://api.dataforseo.com/v3/on_page/pages" \
  -H "Authorization: Basic $DATAFORSEO_CREDENTIALS" \
  -H "Content-Type: application/json" \
  -d '[{"id": "TASK_ID", "limit": 50}]'

2b. Codebase audit (no API needed)

For each page in the codebase, check:

CheckWhat to verify
<title>50-60 chars, primary keyword + brand, unique per page
<meta description>140-160 chars, includes primary + secondary keyword
OG tagsog:title, og:description, og:image set and unique
Twitter cardtwitter:card, twitter:title, twitter:description
Canonical URLSet via alternates.canonical or <link rel="canonical">
H1Exactly one per page
JSON-LDStructured data present (Organization, FAQPage, SoftwareApplication, Article)
Internal linksBlog posts link to sign-up, pages cross-link
Image alt textAll images have descriptive alt attributes
robots.txtExists at public/robots.txt
SitemapExists or generated by framework

2c. Fix meta tags

Rules:

  • Title: 50-60 chars, primary keyword + brand. Format: [Page Name] — [Keyword Phrase] | Brand
  • Description: 140-160 chars, include primary + secondary keyword naturally
  • H1 can stay editorial — meta title does the SEO work

Phase 3: Content Gap Analysis

3a. Map keywords to pages

Read SEO_KEYWORDS.md and compare against existing pages. For each keyword cluster, identify whether a page targets it.

3b. Identify missing content

Look for high-volume, low-difficulty keywords with no targeting page. Common gaps:

  • Missing /blog index page
  • Missing /pricing page (if pricing exists but isn't a standalone page)
  • Missing comparison pages (vs. competitors)
  • Missing "how to" / tutorial content
  • Missing /about page

3c. Plan new content

For each gap, define: target keyword, page title, audience, word count, internal links.


Phase 4: GEO Optimization

GEO = Generative Engine Optimization. Making content appear in AI-generated answers (ChatGPT, Perplexity, Google AI Overviews, Claude).

4a. GEO audit of existing pages

For each page, score these factors (1-10):

FactorWhat to check
Clear definitionsKey terms defined in 25-50 word standalone blocks?
Quotable statementsSpecific, citeable facts with sources?
Factual densityStats with numbers, units, sources?
Q&A formatContent answers "What is X?" / "How does X work?" directly?
Authority signalsExpert credentials, citations, first-party data?
StructureTables, numbered lists, clear headings matching query intent?

AI engine preferences:

EnginePriorities
Google AI OverviewDirect answer in first 150 words, tables, FAQ schema, JSON-LD
ChatGPT BrowseSpecific facts, expert quotes, freshness, .edu/.gov trust
PerplexityFreshness bias, quotable standalone statements, primary sources
ClaudeAuthoritative definitions, verifiable facts, reasoning transparency

4b. Add quotable definitions

Every key concept needs a standalone definition block: Template: **[Term]** is [clear category] that [primary function], [key characteristic].

4c. Add FAQ schema

For pages targeting commercial/informational keywords:

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is [term]?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "[25-50 word definition from the page]"
      }
    }
  ]
}

4d. Add Organization schema

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "BRAND_NAME",
  "url": "https://SITE_DOMAIN",
  "description": "DESCRIPTION",
  "email": "CONTACT_EMAIL"
}

4e. CORE-EEAT GEO checklist

IDStandardCheck
C02Direct answer in first 150 wordsDoes the page answer its primary query immediately?
C04Key terms defined on first useAre technical terms defined inline?
C09Structured FAQDoes the page have a Q&A section?
O02Summary box / key takeawaysIs there a TL;DR?
O03Data in tables, not proseAre comparisons in table format?
O05JSON-LD schema markupIs structured data present?
R015+ precise data points with unitsAre there specific numbers?
R04Claims backed by evidenceIs every claim sourced?
R07Full entity namesNo "a company" — always use the brand name
E01Original first-party dataAre own benchmarks/stats shared?
Exp10Limitations acknowledgedIs scope stated honestly?
Ept08Reasoning transparencyAre choices explained?

Phase 5: Content Creation

Writing SEO+GEO optimized content

  1. First 150 words: Direct answer to the primary query. Include target keyword and standalone definition.
  2. Body: H2 headings matching question-format queries. Each section 3-5 sentences. Comparisons in tables, processes in numbered lists.
  3. Quotable blocks: Every 300 words, include a bold statistic or definition AI can extract.
  4. Citations: At least 1 external citation per 500 words.
  5. FAQ section: 3-5 questions matching long-tail keywords.
  6. Internal links: Descriptive anchor text (not "click here").

Phase 6: Monitor

6a. Track rankings

Re-run ranked_keywords query monthly. Compare against previous SEO_KEYWORDS.md.

6b. Check AI citations

Search for the brand in ChatGPT, Perplexity, Google AI Overviews using target keywords.

6c. Iterate

  1. Update SEO_KEYWORDS.md with fresh data
  2. Identify keywords moving up/down
  3. Find new long-tail opportunities
  4. Refresh stale content (update dates, stats)
  5. Write new content targeting gaps

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.