| name | openseo-keyword-clustering |
| description | Cluster keywords by search intent and map each cluster to an existing or proposed page, with cannibalization detection from Search Console. Use this skill when the user has a keyword list (saved set, brand/keyword-plan.md, GSC export, or seed topic) and needs page targets, content briefs, or a site map for SEO pages — especially before seo-content or seo-machine page generation. Triggers: "cluster keywords", "keyword mapping", "map keywords to pages", "keyword cannibalization", "which page should target". |
| category | seo |
| tier | nice-to-have |
| layer | strategy |
| reads | ["brand/keyword-plan.md"] |
| writes | ["brand/keyword-plan.md"] |
| env_vars | ["OPENSEO_API_KEY","OPENSEO_API_BASE"] |
| triggers | ["cluster keywords","keyword mapping","map keywords to pages","keyword cannibalization","which page should target"] |
| allowed-tools | ["Bash(mktg catalog *)","Bash(mktg run *)"] |
OpenSEO Keyword Clustering
Group keywords into page-level clusters and assign each to an existing URL, a new page proposal, or a do-not-target bucket. Output lands in marketing/seo/clusters/*.md (per-cluster briefs) and feeds seo-content / seo-machine with measured page targets.
On Activation
- Catalog + binding:
mktg catalog info openseo --json --fields configured and .seo/openseo.json for projectId. No binding → openseo-project-setup first. No OpenSEO at all → do lexical clustering with Exa context but label every cluster "SERP-unvalidated."
- Keyword source: prefer (a)
brand/keyword-plan.md populated sections, (b) list_saved_keywords with a tag, (c) GSC live data, (d) seed discovery via research_keywords. Under 10 usable terms → simple map, no clustering ceremony.
OpenSEO MCP Tools
get_search_console_performance with dimensions: ["query","page"]: the cannibalization truth source — one query splitting impressions across multiple URLs means existing cannibalization, not theoretical risk.
get_ranked_keywords: domain/page-driven clustering from exact ranking rows + URLs.
get_serp_results: SERP-overlap validation for borderline terms (small batches, ≤10).
list_saved_keywords / research_keywords: source sets.
save_keywords: apply cluster tags ONLY after confirmation.
Workflow
- Assemble the candidate set from the source hierarchy above; dedupe and drop off-strategy terms.
- Cluster by intent and page type: same SERP intent + similar ranking pages belong together; different intent/buyer stage/SERP format splits. Lexical similarity is NOT evidence of same-page fit.
- Borderline terms: small
get_serp_results overlap check.
- Assign each cluster: existing URL (if supplied and fitting), new-page proposal, or do-not-target/later.
- Cannibalization check: GSC query+page data first; otherwise flag where two proposed pages share one intent.
- Write per-cluster briefs to
marketing/seo/clusters/<cluster-slug>.md: page type, searcher problem, required sections, internal-link targets, priority.
- Optionally tag clusters with
save_keywords after confirmation.