| 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"] |
| writes | ["brand/keyword-plan.md"] |
| env_vars | ["OPENSEO_API_KEY","OPENSEO_API_BASE"] |
| triggers | ["keyword difficulty","search volume","keyword opportunities","striking distance keywords","measured keyword research"] |
| allowed-tools | ["Bash(mktg catalog *)","Bash(mktg run *)"] |
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
- Catalog check:
mktg catalog info openseo --json --fields configured — if not configured, stop spending: state the gap and hand off to Exa-backed keyword-research with metrics marked unknown.
- Project binding: read
.seo/openseo.json for projectId. Missing → run openseo-project-setup first (or ask the user for the project id).
- Brand grounding: read
brand/positioning.md + existing brand/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. 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.
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: ONLY after explicit user 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_keywords per angle; to hydrate; if a domain is in the brief.