Semrush baseline
Skill mkreindel/seo-toolkit-template/.claude/skills/semrush-baseline
Claude Code workspace template for running consistent SEO across a portfolio of managed websites.
npx -y skills add mkreindel/seo-toolkit-template --skill semrush-baselineAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Refresh a site's SEMrush snapshot — domain authority, organic traffic, keyword count, top keywords, top competitors, backlink snapshot — and append the result as a dated baseline file in the site folder. Use when the user types `/semrush-baseline {site}` or when the quarterly cron fires.
SKILL.md
5.6 KB, as published. Nobody here has run it
/semrush-baseline — SEMrush quarterly snapshot
Pulls a refreshed SEMrush snapshot for a given site and writes it as sites/{site}/semrush-baseline-YYYY-MM-DD.md for trend comparison over time. The 7th skill in the toolkit — targeted by the 3 quarterly-semrush-baseline cron entries in .claude/schedules.yml.
Inputs
Required (asked at start if not given):
- Site — must match a folder under
sites/[name]/. The skill reads itssite-info.mdKeyword tool default + SEMrush Position Tracking campaign ID.
Optional:
--cronflag — cron mode (no AskUserQuestion; escalate to_inbox/on errors).
Workflow
Step 0 — Cron-mode detection (if invoked with --cron)
If the invocation contains --cron, this skill runs in cron mode (no user available). Required behavior:
- Idempotency check: if
sites/{site}/semrush-baseline-YYYY-MM-DD.mdfor today already exists, exit cleanly withexit: "idempotent-skip". - Escalation contract: any decision that would normally prompt the user (missing site-info, SEMrush API errors that persist, missing API key) MUST be escalated by writing an item to
sites/{site}/_inbox/viascripts/lib/cron-mode.mjswriteInboxItem(...)and exiting withexit: "escalated". Do NOT useAskUserQuestionin cron mode. - Defaults: when a choice would normally be asked, default to
site-info.mdvalues. If site-info is silent, escalate per (2). - Audit log: ALWAYS write one line to the audit log on exit — success (
shipped), escalation (escalated), idempotent skip (idempotent-skip), or failure (failed). - Backoff: at the start of every cron-mode run, call
checkBackoff({ routine })fromscripts/lib/audit-log.mjs. If true, the routine has hit the 3-strike threshold — write_inbox/routine-disabled-{site}-quarterly-semrush-baseline.md, runscripts/sync-schedules.mjs --pause-routine={site}-quarterly-semrush-baseline, and exit.
Step 1 — Read context
CLAUDE.mdsites/{site}/site-info.md— Keyword tool + SEMrush Position Tracking campaign IDsites/{site}/notes.mdCurrent state- Previous baseline (if any) — most recent
sites/{site}/semrush-baseline-*.mdfor comparison
If site-info.md Keyword tool (default) is not SEMrush (case-insensitive), skip with exit: "idempotent-skip" and audit log entry "site not configured for SEMrush."
If SEMRUSH_API_KEY is not set in .env, escalate to _inbox/ and exit.
Step 2 — Pull SEMrush data
Via scripts/semrush.mjs helper (if exists) or direct SEMrush API:
- Domain overview (
domain_ranksendpoint): Authority Score (AS), organic traffic, organic keywords count, paid traffic, total backlinks - Top 10 organic keywords (
domain_organicendpoint): sorted by position × volume - Top 5 organic competitors (
domain_organic_organicendpoint) - Position Tracking campaign delta (if campaign ID present in site-info): current rankings vs. previous fetch
Step 3 — Write baseline file
Save to sites/{site}/semrush-baseline-YYYY-MM-DD.md:
# SEMrush baseline — {site} — YYYY-MM-DD
routine_version: 1.0
Generated: YYYY-MM-DDThh:mm:ssZ
## Overview
| Metric | Current | vs. previous baseline |
|---|---|---|
| Authority Score | N | ±N |
| Organic traffic / mo | N | ±N% |
| Organic keywords | N | ±N |
| Backlinks (total) | N | ±N |
| Referring domains | N | ±N |
## Top 10 organic keywords
| Rank | Keyword | Volume | Position | URL |
| ... |
## Top 5 organic competitors
| Domain | Common kws | Competition % | AS |
| ... |
## Position Tracking campaign delta
(if campaign ID present in site-info.md)
| Keyword | Position now | Position last quarter | Δ |
| ... |
## Notable changes vs. previous baseline
- {one-line summary of biggest moves, e.g., "AS 0 → 5 (+5)"}
- {ranking moves >5 positions}
- {keyword count delta}
## Notes
Cron next fire: {next Q-start date from schedules.yml}
Step 4 — Update site-info.md Backlinks section
In cron mode: append a one-line note to the ## Backlinks (snapshot) section with the new date + AS + RD count. Do NOT overwrite existing content; this is an append-only audit trail.
Step 5 — Audit log
Call appendRun({ routine: "{site}-quarterly-semrush-baseline", routineVersion: "1.0", site, durationSec, exit: "shipped", filesTouched: [baseline-file-path, "sites/{site}/site-info.md"], escalations: [] }).
Call recordSuccess({ routine: "{site}-quarterly-semrush-baseline" }).
Routine versioning + idempotency contract
This skill participates in cruise-control via --cron mode. When invoked by cron:
-
Stamp
routine_versionin every output (semrush-baseline-YYYY-MM-DD.mdfrontmatter line + audit log line +_inbox/item frontmatter if escalating). Currentroutine_version: 1.0. -
Idempotency: safe to run twice on the same day — if today's
semrush-baseline-YYYY-MM-DD.mdexists, exit withidempotent-skip. SEMrush API costs apply per call, so this matters.
Reference: docs/specs/2026-05-16-agents-cruise-control-design.md § Operational hardening O3.
Refusal conditions
- Site folder doesn't exist
site-info.mdmissingKeyword toolin site-info is notSEMrushSEMRUSH_API_KEYmissing in.env- (Cron mode only) backoff threshold reached — auto-pause + exit per Step 0