OpenSEO Keyword Research
Openseo keyword research

Discover keyword opportunities with MEASURED volume, keyword difficulty, CPC, and intent from OpenSEO, then write them into brand/keyword-plan.md. Use this skill whenever someone asks for keyword difficulty, KD, search volume, keyword…
--- name: openseo-keyword-research description: >- Discover keyword opportunities with MEASURED volume, keyword difficulty, CPC, and intent from OpenSEO, then write them into brand/keyword-plan.md. Use this skill whenever someone asks for keyword difficulty, KD, search volume, keyword ideas with metrics, striking-distance opportunities from Search Console, or SERP-validated keyword priorities. For qualitative research without an OpenSEO connection, use mktg's keyword-research instead (metrics will be unknown). Triggers: "keyword difficulty", "search volume", "keyword opportunities", "striking distance keywords", "measured keyword research". category: seo tier: nice-to-have layer: strategy reads: - brand/keyword-plan.md - brand/positioning.md
Overview
Turn seed topics into a prioritized, MEASURED keyword opportunity set and land it in brand/keyword-plan.md. mktg's keyword-research is the playbook (methodology); this skill is the measured-data engine behind it when OpenSEO is configured.
Manual install (npx, ZIP)
npx skills add MoizIbnYousaf/marketing-cli --skill openseo-keyword-research -g -a claude-codenpx degit MoizIbnYousaf/marketing-cli/skills/openseo-keyword-research#main ~/.claude/skills/openseo-keyword-researchConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md6.0 KB
Read SKILL.md here
Show the full text100 lines
OpenSEO Keyword Research
Turn seed topics into a prioritized, MEASURED keyword opportunity set and land it in brand/keyword-plan.md. mktg's keyword-research is the playbook (methodology); this skill is the measured-data engine behind it when OpenSEO is configured.
On Activation
- Readiness check:
mktg seo status --json --fields readiness,catalog.endpointError,project— if readiness isnot_configured, stop spending: state the gap and hand off to Exa-backedkeyword-researchwith metrics markedunknown. For a ready state, verify live access with the freewhoamiMCP tool before paid calls. - Project binding: read
.seo/openseo.jsonforprojectId. Missing → runopenseo-project-setupfirst (or ask the user for the project id). - Brand grounding: read
brand/positioning.md+ existingbrand/keyword-plan.md(tolerate templates). Business-fit beats volume-fit — the positioning file is the filter.
OpenSEO MCP Tools
get_search_console_performance: when GSC is connected, START here. HighrowLimit, filter average position ~5–20 client-side (the API sorts by clicks, not position). These striking-distance terms are the fastest wins — and zero extra credit cost.get_keyword_metrics: hydrate up to 700 keywords per call with volume, KD, intent, CPC, trends. Use on striking-distance terms and every candidate set.research_keywords: discovery from 1–5 seeds per call; prefer ~150 results unless exhaustive research was requested.get_ranked_keywords: when the brief includes a domain/page — exact ranking rows (near-misses, competitor-owned terms).get_serp_results: inspect SERPs for top candidates when intent is ambiguous. Keep batches small (≤10 queries).list_saved_keywords: avoid re-researching what's already saved.save_keywords: a free shared-state mutation. Use only after confirmation, with concise tags (topic:<t>,intent:<i>,page:<slug>).
Workflow
- Normalize seeds into 2–5 distinct research angles filtered by positioning.
- GSC connected? Pull striking-distance terms first and hydrate with
get_keyword_metrics. Work that list before broad discovery. research_keywordsper angle;get_keyword_metricsto hydrate;get_ranked_keywordsif a domain is in the brief.- Remove irrelevant, duplicate, branded-only, and off-intent terms.
- Prioritize by practical opportunity: business fit → clear intent → reasonable KD → volume/CPC signal → winnable SERP.
get_serp_resultsfor high-potential or ambiguous terms when SERP intent would change the call.- Write the shortlist into
brand/keyword-plan.md(preserve its required sections perbrand/SCHEMA.md; confirm before overwriting populated sections). - Present: best opportunity theme, top keywords now, keywords to save, SERP caveats. Then next actions:
openseo-keyword-clustering,seo-content, or save.
Cost Discipline
- State estimated call counts before bulk pulls (>200 keywords) and get confirmation.
- Small exploratory batches are fine without asking.
- GSC-first ordering exists precisely to avoid spending credits on data the user already owns.
Anti-Patterns
- Inventing metrics when OpenSEO returns nothing — because a hallucinated KD of "about 35" silently becomes the foundation of a content plan. If OpenSEO doesn't return a value, write
unknown. - Volume-first prioritization — because a 10k-volume term that doesn't match the product converts nobody and burns months. Positioning filters the list before metrics rank it.
save_keywordswithout explicit confirmation — saves do not burn provider credit, but they mutate shared OpenSEO account state and broad tags can disrupt other workflows. Ask, state the count and tag change, then save.- Skipping the GSC-first pass when GSC is connected — because striking-distance terms (positions 5–20) are provably the cheapest wins in SEO and they're free to read. Discovery research before first-party data is wasted spend.
- Overwriting a populated
keyword-plan.mdwithout confirmation — because that file is brand memory other skills build on (seo-content,seo-machine). Merge; confirm destructive rewrites.
Close the loop
After writing files, log completion so mktg plan / mktg status count the work (bare mktg run only logs loaded):
mktg run openseo-keyword-research --complete --writes <paths written> --result success --json
Progressive Enhancement
| Level | Behavior |
|---|---|
| L0 (no OpenSEO) | Hand off to Exa-backed keyword-research; metrics unknown |
L1 (OPENSEO_API_KEY) |
Metrics via available calls; MCP steps deferred |
| L2 (MCP connected) | Full workflow incl. SERP validation |
| L3 (GSC connected) | Striking-distance-first ordering; highest-signal path |
Adapted from every-app/open-seo .agents/skills/keyword-research (MIT). Workflow and tool guidance upstream; mktg brand-memory writes, positioning filter, and cost discipline added here.
| 1 | |
| 2 | name openseo-keyword-research |
| 3 | description >- |
| 4 | Discover keyword opportunities with MEASURED volume, keyword difficulty, |
| 5 | CPC, and intent from OpenSEO, then write them into brand/keyword-plan.md. |
| 6 | Use this skill whenever someone asks for keyword difficulty, KD, search |
| 7 | volume, keyword ideas with metrics, striking-distance opportunities from |
| 8 | Search Console, or SERP-validated keyword priorities. For qualitative |
| 9 | research without an OpenSEO connection, use mktg's keyword-research |
| 10 | instead (metrics will be unknown). Triggers: "keyword difficulty", |
| 11 | "search volume", "keyword opportunities", "striking distance keywords", |
| 12 | "measured keyword research". |
| 13 | category seo |
| 14 | tier nice-to-have |
| 15 | layer strategy |
| 16 | reads |
| 17 | - brand/keyword-plan.md |
| 18 | - brand/positioning.md |
| 19 | writes |
| 20 | - brand/keyword-plan.md |
| 21 | env_vars |
| 22 | - OPENSEO_API_KEY |
| 23 | - OPENSEO_MCP_URL |
| 24 | triggers |
| 25 | - keyword difficulty |
| 26 | - search volume |
| 27 | - keyword opportunities |
| 28 | - striking distance keywords |
| 29 | - measured keyword research |
| 30 | allowed-tools |
| 31 | - Bash(mktg catalog *) |
| 32 | - Bash(mktg run *) |
| 33 | |
| 34 | |
| 35 | # OpenSEO Keyword Research |
| 36 | |
| 37 | Turn seed topics into a prioritized, MEASURED keyword opportunity set and land it in `brand/keyword-plan.md`. mktg's `keyword-research` is the playbook (methodology); this skill is the measured-data engine behind it when OpenSEO is configured. |
| 38 | |
| 39 | ## On Activation |
| 40 | |
| 41 | **Readiness check**: `mktg seo status --json --fields readiness,catalog.endpointError,project` — if readiness is `not_configured`, stop spending: state the gap and hand off to Exa-backed `keyword-research` with metrics marked `unknown`. For a ready state, verify live access with the free `whoami` MCP tool before paid calls. |
| 42 | **Project binding**: read `.seo/openseo.json` for `projectId`. Missing → run `openseo-project-setup` first (or ask the user for the project id). |
| 43 | **Brand grounding**: read `brand/positioning.md` + existing `brand/keyword-plan.md` (tolerate templates). Business-fit beats volume-fit — the positioning file is the filter. |
| 44 | |
| 45 | ## OpenSEO MCP Tools |
| 46 | |
| 47 | `get_search_console_performance`: when GSC is connected, START here. High `rowLimit`, filter average position ~5–20 client-side (the API sorts by clicks, not position). These striking-distance terms are the fastest wins — and zero extra credit cost. |
| 48 | `get_keyword_metrics`: hydrate up to 700 keywords per call with volume, KD, intent, CPC, trends. Use on striking-distance terms and every candidate set. |
| 49 | `research_keywords`: discovery from 1–5 seeds per call; prefer ~150 results unless exhaustive research was requested. |
| 50 | `get_ranked_keywords`: when the brief includes a domain/page — exact ranking rows (near-misses, competitor-owned terms). |
| 51 | `get_serp_results`: inspect SERPs for top candidates when intent is ambiguous. Keep batches small (≤10 queries). |
| 52 | `list_saved_keywords`: avoid re-researching what's already saved. |
| 53 | `save_keywords`: a free shared-state mutation. Use only after confirmation, with concise tags (`topic:<t>`, `intent:<i>`, `page:<slug>`). |
| 54 | |
| 55 | ## Workflow |
| 56 | |
| 57 | Normalize seeds into 2–5 distinct research angles filtered by positioning. |
| 58 | GSC connected? Pull striking-distance terms first and hydrate with `get_keyword_metrics`. Work that list before broad discovery. |
| 59 | `research_keywords` per angle; `get_keyword_metrics` to hydrate; `get_ranked_keywords` if a domain is in the brief. |
| 60 | Remove irrelevant, duplicate, branded-only, and off-intent terms. |
| 61 | Prioritize by practical opportunity: business fit → clear intent → reasonable KD → volume/CPC signal → winnable SERP. |
| 62 | `get_serp_results` for high-potential or ambiguous terms when SERP intent would change the call. |
| 63 | Write the shortlist into `brand/keyword-plan.md` (preserve its required sections per `brand/SCHEMA.md`; confirm before overwriting populated sections). |
| 64 | Present: best opportunity theme, top keywords now, keywords to save, SERP caveats. Then next actions: `openseo-keyword-clustering`, `seo-content`, or save. |
| 65 | |
| 66 | ## Cost Discipline |
| 67 | |
| 68 | State estimated call counts before bulk pulls (>200 keywords) and get confirmation. |
| 69 | Small exploratory batches are fine without asking. |
| 70 | GSC-first ordering exists precisely to avoid spending credits on data the user already owns. |
| 71 | |
| 72 | ## Anti-Patterns |
| 73 | |
| 74 | **Inventing metrics when OpenSEO returns nothing** — because a hallucinated KD of "about 35" silently becomes the foundation of a content plan. If OpenSEO doesn't return a value, write `unknown`. |
| 75 | **Volume-first prioritization** — because a 10k-volume term that doesn't match the product converts nobody and burns months. Positioning filters the list before metrics rank it. |
| 76 | **`save_keywords` without explicit confirmation** — saves do not burn provider credit, but they mutate shared OpenSEO account state and broad tags can disrupt other workflows. Ask, state the count and tag change, then save. |
| 77 | **Skipping the GSC-first pass when GSC is connected** — because striking-distance terms (positions 5–20) are provably the cheapest wins in SEO and they're free to read. Discovery research before first-party data is wasted spend. |
| 78 | **Overwriting a populated `keyword-plan.md` without confirmation** — because that file is brand memory other skills build on (`seo-content`, `seo-machine`). Merge; confirm destructive rewrites. |
| 79 | |
| 80 | ## Close the loop |
| 81 | |
| 82 | After writing files, log completion so `mktg plan` / `mktg status` count the work (bare `mktg run` only logs `loaded`): |
| 83 | |
| 84 | |
| 85 | mktg run openseo-keyword-research --complete --writes <paths written> --result success --json |
| 86 | |
| 87 | |
| 88 | ## Progressive Enhancement |
| 89 | |
| 90 | | Level | Behavior | |
| 91 | |---|---| |
| 92 | | L0 (no OpenSEO) | Hand off to Exa-backed `keyword-research`; metrics `unknown` | |
| 93 | | L1 (`OPENSEO_API_KEY`) | Metrics via available calls; MCP steps deferred | |
| 94 | | L2 (MCP connected) | Full workflow incl. SERP validation | |
| 95 | | L3 (GSC connected) | Striking-distance-first ordering; highest-signal path | |
| 96 | |
| 97 | |
| 98 | |
| 99 | *Adapted from [every-app/open-seo] `.agents/skills/keyword-research` (MIT). Workflow and tool guidance upstream; mktg brand-memory writes, positioning filter, and cost discipline added here.* |
| 100 |
Details
- License
- MIT
- Stars on the repo
- ★ 31
- Checked
- Source
- MoizIbnYousaf/marketing-cli ↗
- Creator
- MoizIbnYousaf · 5 listings
Similar skills
See all →
SkillAgent Browsing Auditor
SkillBacklink Profile Analysis
SkillCMS Configuration Helper
SkillBacklink Comparison Tool
SkillWeb Vitals Auditor
SkillSEO Publishing LoopMore from MoizIbnYousaf
SkillAnswer Engine Optimization Program
SkillLink Building Campaign
SkillOpenSEO Data Platform
SkillOpenSEO Link Prospecting