| name | semrush-research |
| description | Plan and execute credit-efficient Semrush API research for SEO strategy work in this repo. Use when validating a keyword before writing, profiling a competitor, finding a keyword or content gap, sizing a programmatic SEO template, running a pillar deep-dive, or tracking a trending topic cluster. Selects the cheapest report that answers the question, batches keywords with phrase_these, caps display_limit, caches results to docs/research/semrush-cache/, and returns a Ship/Skip/Refine verdict tied to a Career Hub pillar and persona — not a raw keyword dump. |
| metadata | {"family":"semrush-research","owner":"semrush-research","last_reviewed":"2026-04-30T00:00:00.000Z","version":"1.0.0"} |
Semrush Research
This skill turns ad-hoc Semrush queries into strategic, decision-ready SEO research. It exists because raw phrase_this / domain_organic_organic calls are expensive and easy to misuse: a single careless query for related keywords without a display_limit can burn 4,000 units and still not answer the actual business question. Every recipe in this skill is shaped around one strategic question and is designed to answer it with the smallest credit footprint Semrush will allow.
The skill is advisory. Other skills (content-scout, seo-audit, site-growth, ai-seo) reference it when they need fresh data. Nothing blocks on it.
Use This Skill When
- A new content topic needs to be validated before drafting (route to
recipes/validate-keyword.md).
- A competitor needs to be profiled — top traffic pages, adjacent SERP rivals (route to
recipes/competitor-snapshot.md).
- The question is "what are competitors ranking for that we don't?" (route to
recipes/keyword-gap.md).
- A programmatic template needs sizing before scaffolding routes — e.g., per-state, per-wage, per-role (route to
recipes/pseo-template-check.md).
- A full pillar (one of the 7 in
nextjs-app/docs/PILLARS.md) needs a deep review (route to recipes/pillar-deep-dive.md).
- A timely or news-driven cluster (e.g., legislation change, seasonal trend) needs to be sized (route to
recipes/trending-watch.md).
Do Not Use When
- The user just wants a quick volume number for one already-known keyword and is not making a publishing decision. Call
phrase_this once directly via CallMcpTool and stop.
- The work is purely implementation (metadata, schema, internal linking). Stay in
seo-page-rules, schema-markup, site-architecture.
- The work is editorial/factual research for a draft. Stay in
content-researcher.
- Semrush MCP is unavailable. Tell the user, do not invent volumes.
Recipe Routing
Every recipe answers one strategic question with a fixed budget. Pick the cheapest one that fits.
recipes/validate-keyword.md — "Is this keyword worth a page?" — Budget ~30-100 units
recipes/competitor-snapshot.md — "What is this competitor winning?" — Budget ~300-800 units
recipes/pseo-template-check.md — "Which slot values in this template have demand?" — Budget ~100-300 units
recipes/trending-watch.md — "What's the question cluster around this trending topic?" — Budget ~200-800 units
recipes/keyword-gap.md — "What are competitors ranking for that we don't?" — Budget ~500-2,500 units
recipes/pillar-deep-dive.md — "Is this whole pillar healthy and what should change?" — Budget ~2,000-5,000 units
If two recipes could fit, pick the cheaper one. A validate-keyword plus a competitor-snapshot is almost always cheaper and more decisive than a pillar-deep-dive.
Mandatory Workflow
Every recipe run follows this order:
- Write the hypothesis. One sentence. Example: "
bartender job description has volume worth ranking for and we already have the underlying data on the role page." If you cannot write the hypothesis, you cannot pick the right recipe — go back.
- Check the cache. Read nextjs-app/docs/research/semrush-cache/_index.json for a matching query within the recipe's freshness window (default 30 days). If it hits, skip the API call entirely and report
units_paid: 0.
- Read
reference/unit-costs.md once if you have not already this session to confirm the report cost per line. Pick the cheapest report. Always set display_limit (default 30 unless the recipe says otherwise).
- Run the queries. Use
CallMcpTool with server: user-semrush, toolName: execute_report. Batch keywords with phrase_these whenever possible.
- Score with the Career Hub formula in reference/opportunity-scoring.md. Use the persona/pillar map in reference/career-hub-baselines.md.
- Write the verdict using the recipe's required output block. Save raw JSON to the cache. Append the run to
_index.json with query, params, run_at, units_paid, cache_key.
- Hand off if needed: route to the right downstream skill (
content-scout, site-growth, etc.) with the recipe's matching template from templates/.
How To Call Semrush MCP
Always use the discovery → schema → execute pattern the MCP enforces:
CallMcpTool(server="user-semrush", toolName="<toolkit_name>", arguments={})
→ returns the list of reports in that toolkit
CallMcpTool(server="user-semrush", toolName="get_report_schema", arguments={"report": "<report_name>"})
→ returns the parameters for that report
CallMcpTool(server="user-semrush", toolName="execute_report", arguments={"report": "<report_name>", "params": {...}})
→ returns the data
Toolkits worth knowing: keyword_research, organic_research, trends. Within each, the cheapest reports are listed in reference/unit-costs.md.
Default database to us unless the user specifies otherwise. Always pass display_limit.
Cost-Saving Patterns
These patterns have outsized impact. The skill body keeps them inline because forgetting them is the most expensive failure mode.
- Batch with
phrase_these. One call with phrase: "kw1;kw2;kw3;...;kw30" costs ~300 units for 30 keywords. Thirty separate phrase_this calls cost the same in units but consume 30x the round-trips and double the agent context. Use phrase_these for any volume check of 2+ keywords.
- Always set
display_limit. phrase_questions and phrase_related cost 40 units per line. Without a limit they default to 50+ rows and burn 2,000+ units per call. Default 30 unless the recipe says otherwise.
- Use
display_filter on expensive reports. domain_domains is 80 units per line. Filter +|Nq|Gt|500 (volume > 500) before paying for low-volume gap noise. Filter syntax is documented in the schema response under display_filter.
- Sort smart.
display_sort: tr_desc (traffic descending) on domain_organic_unique puts the highest-traffic pages first, so a smaller display_limit still captures the meaningful pages.
- Reuse domain pulls across recipes. If
competitor-snapshot already cached snagajob.com.unique.json this month, keyword-gap and pillar-deep-dive should use the same file rather than re-pulling.
Anti-Patterns To Block
If you find yourself doing any of these, stop and re-plan:
- Calling
phrase_this in a loop. Use phrase_these once.
- Calling
phrase_questions or phrase_related (40 u/line) without display_limit.
- Calling
domain_domains (80 u/line) without display_filter for a volume floor.
- Re-querying without checking
_index.json first.
- Running a
pillar-deep-dive without first running cheaper recipes that already answer most of the question.
- Returning a raw keyword list as the final output. Every recipe ends with a verdict.
- Treating CPC or competition score as keyword difficulty — they are not the same. KD comes from
phrase_kdi (50 u/line) and is only worth running for the top contenders after cheaper filtering.
Output Contract
Every recipe ends with a fixed-shape block so handoffs are predictable. The exact shape is in each recipe file. At minimum every output includes:
recipe: which recipe ran
hypothesis: the one-sentence hypothesis from step 1
verdict: Ship | Skip | Refine | Watch (recipe-specific)
units_paid: integer
cache_hit: true | false
next_step: which skill (if any) to hand off to
This block is what gets pasted into the calling skill's brief, not the raw Semrush data.
Cache And Freshness
Cache lives under nextjs-app/docs/research/semrush-cache/ with subfolders keywords/, domains/, gaps/, questions/. Keys are slugged from the primary input (keyword, domain, or competitor pair).
Freshness defaults (override per recipe if needed):
- Keyword volumes: 30 days. Volumes refresh monthly in Semrush; do not re-pull within the window unless the user explicitly asks.
- Domain top pages and competitors: 30 days.
- Question keywords: 14 days for trending topics, 60 days for evergreen.
- Gap reports: 30 days.
Always update _index.json with the run metadata, even on cache hits (record the lookup so cache hit rate is measurable).
Integration Points
content-scout (Research Inputs) → semrush-keyword-validator (which wraps recipes/validate-keyword.md)
seo-audit (Audit Order, competitor questions) → recipes/competitor-snapshot.md or recipes/keyword-gap.md
site-growth (Required Output) → recipes/keyword-gap.md or recipes/pillar-deep-dive.md
ai-seo (Step 4: Citation Competitor Analysis) → recipes/competitor-snapshot.md
Reference Files
Read these only when the recipe says to or you need the underlying data.
Output Templates
KPIs This Skill Is Measured On
Tracked in _index.json. Roll-up is manual today; a future script can summarise.
- Median units per recipe run. Targets: validate-keyword < 60, competitor-snapshot < 500, gap < 1,500, pillar < 4,000.
- Cache hit rate. Target: > 40% after 60 days of regular use.
- Decision conversion rate. % of
validate-keyword Ship verdicts that became published articles within 60 days. The truest signal that the skill predicts well.