ahrefs
Skill2 starsChanged 22 days agoMITView on GitHub
Pulls Ahrefs data for any domain and runs staged keyword research under a unit budget. Lookups: organic keywords, top pages, backlinks, referring domains, Domain Rating, traffic history, anchors, organic competitors, the SERP for a keyword, units left. Keyword research: expand seed topics, price keywords, pull top-10 SERPs, cluster the keywords one page can rank for, read which page type each SERP rewards, join your Google positions from Search Console, and suggest improve / new article / landing page / skip. Works through the Ahrefs MCP tools (any paid plan from Lite) or an API v3 key for scripts. Use when someone asks for a domain's SEO metrics, a competitor's organic traffic or backlinks, keyword volumes, or what to write about. Triggers: "check in Ahrefs", "organic traffic of X", "backlinks of X", "competitor SEO metrics", "keyword research", "keyword clustering", "what should we write about", "keywords for the German market", "content gap", "how much traffic does X get".
- Reads credentials
4 other projects use a version of this.
Adopted by
Most recently taken up by
- tymoshenko-dmytro/claude-marketing-skillsword for word, first seen Nov 1, 2026
- joelhooks/joelclawtheir own version, first seen Oct 8, 2026
- LARIkoz/ahrefs-api-knowledge-basetheir own version, first seen Jul 1, 2026
- vijaychauhanseo/seo-skills-packtheir own version, first seen Mar 20, 2026
Other versions4 projects use a version of this.
Word for word · 1
- tymoshenko-dmytro/claude-marketing-skills★ 2100% same
Edited · 0
None found.
Wrote their own version · 3
- joelhooks/joelclaw★ 65same name
- vijaychauhanseo/seo-skills-pack★ 1same name
- LARIkoz/ahrefs-api-knowledge-base★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository19 other files it gives its agents.
- ads-parserSkill
- ads-video-librarySkill
- competitor-researchSkill
- connectSkill
- funnel-screenshotsSkill
- ga4-reportsSkill
- gsc-insightsSkill
- image-genSkill
- parallel-researchSkill
- plain-copySkill
- seoSkill
- seo-tech-auditSkill
- video-3dSkill
- video-buildSkill
- video-checkSkill
- video-generatedSkill
- video-movesSkill
- video-soundSkill
- video-studioSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
13 rules. 0 are common, 4 are distinctive, and 9 are very specific to this project.
0
Common
Most of the 3 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
Use the MCP tools. If they are not loaded, search for them (for example "ahrefs organic keywords").
- Very specific: line 36
Call the doc tool before the first use of any tool.
- Distinctive: line 37
Every money value is in USD cents.
- Very specific: line 38
If a response carries render_with metadata, call that render tool with the data.
- Very specific: line 97
Use --dry-run on price and serp first.
- Very specific: line 111
Run the stage, e.g. kw.py price --project de-dubbing --country de.
- Distinctive: line 136
Existing page first: if you rank 4–20 for the cluster in GSC, improve that page.
- Distinctive: line 137
One cluster, one page: Do not split keywords that share a SERP.
- Distinctive: line 141
Never present a keyword list as research without the SERP check.
- Very specific: line 145
Read references/unit-costs.md before pricing more than a few dozen keywords.
- Very specific: line 153
Put your own domains, hosts and markets into the site config ([site] hosts, [keywords] default_country, markets) so SERPs mark your pages …
- Very specific: line 157
Keep a domains.json with your domain and your usual competitors, so "compare us with the usual three" needs no lookups.
- Very specific: line 161
If you run the same SEO snapshot every month, turn the lookups into a fixed ahrefs_api.py script (API v3) and keep the agent for …
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Ahrefs
Two jobs: quick lookups for any domain, and staged keyword research. Every Ahrefs call spends API units from the
plan, so both keep a log of what was spent. Setup: connections/ahrefs-mcp.md, or run the connect skill.
Two ways in, and they are not interchangeable:
- The Ahrefs MCP server (default, any paid plan from Lite). Tools are named
mcp__ahrefs__*. The agent calls them. Do not write scripts against the MCP endpoint: Ahrefs' terms do not permit custom scripts, bridges or standalone JSON-RPC clients there. - API v3 with
AHREFS_API_KEY(an API v3 key; Ahrefs lists "direct access to API v3" from the Lite plan up, checked 2026-10-21; generate it under Account settings → API keys). Scripts use it:https://api.ahrefs.com/v3/<path>,Authorization: Bearer <key>. An MCP key on API v3, or an API key on MCP, returns 401.
The key is read from the environment first, then from ~/.config/marketing-agent-kit/.env (or MARKETING_KIT_ENV).
Mode 1: quick lookups (any domain)
Use the MCP tools. If they are not loaded, search for them (for example "ahrefs organic keywords"); if the server
is not connected, send the user to connections/ahrefs-mcp.md. Server rules:
- Call the
doctool before the first use of any tool. - Every money value is in USD cents. Divide by 100.
- If a response carries
render_withmetadata, call that render tool with the data. - Save what you will quote: write each response to
raw/seo/<name>.jsonnext to the analysis.
With an API v3 key, the same calls work from the script (repeatable, saved, units logged):
python3 ${CLAUDE_SKILL_DIR}/scripts/ahrefs_api.py site-explorer-organic-keywords target=example.com date=2026-09-30 \
select=keyword,sum_traffic,best_position limit=100 order_by=sum_traffic:desc --out raw/seo/kw.json
python3 ${CLAUDE_SKILL_DIR}/scripts/ahrefs_api.py subscription-info-limits-and-usage # units left (free)
python3 ${CLAUDE_SKILL_DIR}/scripts/ahrefs_api.py endpoints site-explorer # list endpoints (no key, no units)
python3 ${CLAUDE_SKILL_DIR}/scripts/ahrefs_api.py params site-explorer/top-pages # one endpoint's parametersThe script takes an API path or an MCP tool name. A tool name becomes <group>/<rest>
(site-explorer-top-pages → site-explorer/top-pages) with a few exceptions it knows: serp-overview →
serp-overview/serp-overview, batch-analysis → batch-analysis/batch-analysis, site-explorer-referring-domains
→ site-explorer/refdomains, site-explorer-linked-domains → site-explorer/linkeddomains. doc, render-* and
the *-entities tools exist only in MCP. Each call prints its units (response header
x-api-units-cost-total-actual) and appends them to ~/.local/share/marketing-agent-kit/seo/ahrefs_units.jsonl
(override with AHREFS_UNITS_LOG).
| Task | Tool |
| DR and summary metrics | site-explorer-domain-rating, site-explorer-metrics |
| Organic keywords (top by traffic) | site-explorer-organic-keywords (order by traffic, limit<=150) |
| Top organic pages | site-explorer-top-pages |
| Referring domains / backlink summary | site-explorer-referring-domains, site-explorer-backlinks-stats |
| Anchors | site-explorer-anchors |
| Traffic / keyword history | site-explorer-metrics-history, site-explorer-keywords-history |
| Organic competitors | site-explorer-organic-competitors |
| Organic by country | site-explorer-metrics-by-country |
| SERP for a keyword | serp-overview |
| Keyword ideas | keywords-explorer-matching-terms, keywords-explorer-related-terms |
| Keyword volume and difficulty | keywords-explorer-overview |
| AI citations of a brand | brand-radar-* |
| Units left | subscription-info-limits-and-usage (free) |
Rules: limit<=150 by default. Never pull raw backlinks by the thousand: site-explorer-all-backlinks is the most
expensive tool; start with stats and referring domains. Check units left before a long series of calls. Numbers in a
report must be checkable against the saved raw files. Do not use Ahrefs paid-traffic or ad-budget estimates in
reports: they are systematically wrong. Saying that a domain has paid keywords is fine; dollar figures are not. Ad
libraries do not disclose budgets either.
Mode 2: keyword research (staged)
scripts/kw.py STAGE --project <name> [--country xx], one project per topic and market. It reads the site config
~/.config/marketing-agent-kit/seo/<site>.toml ([keywords]: default country, markets, optional monthly unit cap;
[site] hosts to find your own pages in SERPs; format in ../gsc-insights/references/config.md). For the GSC join,
run gsc-insights' gsc_pull.py first. Project files live in <data>/keywords/<project>/.
| Stage | What it does | Cost (units) |
discover --seeds "a,b" [--related] [--from-gsc] | Candidates: matching (and related) terms, strings only; your GSC queries containing a seed in that market (free) | ~1 per row, 50 minimum per call |
price [--max N] [--fields …] [--min-volume 10] | Volume, difficulty, parent topic, intents; seeds and GSC queries first; batches of 20 (API) or 5 (MCP); via API a failing batch is split to drop the keyword Ahrefs cannot price | ~32 per keyword with data; no-data keywords are free |
serp [--top 60] | Top-10 SERP for the biggest keywords | ~50–60 each, cached 14 days |
cluster [--min-shared 3] | Keywords sharing ≥ N top-10 URLs form one cluster (one page targets them), per market | free |
prioritize [--sheet] | Joins your GSC position and page for the market, scores clusters, suggests an action; report.md, clusters.csv, optional sheet tab | free |
budget | Units this month by tool (keyword research + script lookups) and, with an API key, the account limits | free |
Use --dry-run on price and serp first. Answers are cached in <data>/ahrefs_cache.sqlite (30 days, SERPs 14);
units go to <data>/ahrefs_units.jsonl. The monthly cap ([keywords] monthly_unit_cap, 0 = log only) is checked
before each call, across parallel runs.
Transport A: API v3 (--via api)
With AHREFS_API_KEY set, discover, price and serp call API v3 themselves. Units come from the
x-api-units-cost-total-actual response header; a call without that header is logged with units_unreported. A 429
(60 requests per minute by default) is retried once after Retry-After.
Transport B: the MCP tools (--via mcp, the default without an API key)
Most plans have MCP access and no API v3 key. Then the stages do the bookkeeping and you make the calls:
- Run the stage, e.g.
kw.py price --project de-dubbing --country de. It applies every answer already in the cache, writes the calls still needed to<project>/mcp_plan.jsonand prints them with ids (price-001…). - For each planned call, one at a time (parallel calls fail): call the MCP tool (
mcp__ahrefs__<tool>) with exactly the planned arguments and save its output to a file. Keep both text blocks if there are two: the second one,apiUsageCosts, holds the real unit cost. If Claude Code already saved a long output to a file, use that file. kw.py import --project de-dubbing --call price-001 <file>. Import checks the rows, caches them under the same key the API path uses, updates the project files and logs the units (fromapiUsageCosts, or the documented estimate markedunits_estimatedwhen the file has none). Importing the same file twice does nothing.- Re-run the stage: with every answer cached it plans nothing and you go on to the next stage.
For a call that is not in the plan, pass --tool keywords-explorer-overview --args '<the JSON arguments you sent>'
instead of --call, or save a wrapper {"tool": …, "arguments": {…}, "result": <output>}. If a pricing call fails
with an internal server error, one keyword in the batch is one Ahrefs has never indexed: re-run price --batch 1
for the rest and skip the keyword that fails alone. cluster, prioritize and budget are the same for both
transports. budget without an API key shows the logged units; ask the free MCP tool
subscription-info-limits-and-usage for the account's limits.
Workflow and decision rules
Agree topic, market and language; research each language natively (seeds in the market's language;
--from-gsc shows how people there phrase it); discover → read candidates → price (dry run first) → serp for the top
30–60 → cluster → prioritize; check the SERPs of the top clusters yourself before recommending.
- SERP page type decides the format: articles → an article can rank; landing/product pages → a landing page; app stores or vendor homepages → usually skip.
- Existing page first: if you rank 4–20 for the cluster in GSC, improve that page.
- One cluster, one page. Do not split keywords that share a SERP.
- AI Overview present → fewer clicks at the same position; commercial queries get AIOs too.
- Metrics are estimates; KD is often missing for small non-English keywords. Calibrate with GSC impressions.
- score = volume × (1 − KD/100) × (1.0 commercial, 0.5 informational) ranks clusters; it does not forecast traffic.
- Never present a keyword list as research without the SERP check.
Unit costs
Read references/unit-costs.md before pricing more than a few dozen keywords. The short version: cost per call =
max(50, per-row cost × rows); volume-type fields (volume, global_volume, difficulty, traffic_potential,
parent_volume, intents) cost about 10 units per row each, keyword about 1. Discover with select=keyword first,
then price only the shortlist; put the volume floor into where (only kept rows are billed); send pricing calls
sequentially.
Adapt it
- Put your own domains, hosts and markets into the site config (
[site] hosts,[keywords] default_country,markets) so SERPs mark your pages and--from-gscuses your queries. - Set
[keywords] monthly_unit_capto the share of the plan's units that keyword research may spend, and put a cap on the Ahrefs key itself (Account settings → API keys). - Keep a
domains.jsonwith your domain and your usual competitors, so "compare us with the usual three" needs no lookups. - Change the action rules in
kw.py(action()) and the score weights if your business values informational content differently. - If you run the same SEO snapshot every month, turn the lookups into a fixed
ahrefs_api.pyscript (API v3) and keep the agent for interpreting the changes.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

