Best for
- Use when the user says 'SEO machine', 'build organic traffic', 'rank on Google', 'we need traffic', 'alternatives pages', 'comparison pages', '/for/ pages', 'programmatic SEO', or 'build an SEO engine'.
MoizIbnYousaf/marketing-cli/skills/seo-machine/SKILL.md
Build an organic-traffic operating system for any site or app: a multi-phase, resumable engine that ships programmatic landing pages (alternatives, comparisons, use-cases, playbooks) on top of real keyword research. Use when the user says 'SEO machine', 'build organic traffic', 'rank on Google', 'we need traffic', 'alternatives pages', 'comparison pages', '/for/ pages', 'programmatic SEO', or 'build an SEO engine'. Distinct from `seo-audit` (one-off diagnostic) and `seo-content` (single-article
Decision brief
End-to-end engine for building organic search traffic. Ships dozens of programmatic landing pages — alternatives, comparisons, use-cases, playbooks — backed by real keyword research, with a persistent roadmap the user resumes across sessions.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/MoizIbnYousaf/marketing-cli --skill "skills/seo-machine"Inspect the Agent Skill "seo-machine" from https://github.com/MoizIbnYousaf/marketing-cli/blob/f12fbcbe4929584697b309b9096c9427b0cfce8e/skills/seo-machine/SKILL.md at commit f12fbcbe4929584697b309b9096c9427b0cfce8e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Read references/stacks/detection.md. Identify framework family, routing convention (file-based vs controller-based), component language, and existing marketing pages (git ls-files | grep -iE 'marketing|landing|pages/(home|about|pricing)'). Resolve ambiguity with AskUserQuestion.…
Read every signal first, propose .seo/brand.md, then ask only about gaps. Signals: CLAUDE.md, README.md, package.json / Gemfile.lock, tailwind.config. or design-token CSS, app/views/marketing/ or pages/index., pricing page.
Follow references/exa-recipes.md — 7 Exa-native recipes that replace the Ahrefs cookbook:
Run scripts/techaudit.py (sitemap, robots, meta-tag uniqueness, schema). Whatever it finds becomes Phase 0 in the roadmap. Day-0 crawl shapes Google's understanding of the site for months — retroactive fixes are harder.
Fill assets/roadmap-template.md with:
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 92/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 27 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
End-to-end engine for building organic search traffic. Ships dozens of programmatic landing pages — alternatives, comparisons, use-cases, playbooks — backed by real keyword research, with a persistent roadmap the user resumes across sessions.
Conversion-first (alternatives + comparisons before blogs). Publish-early (a thin page indexed today beats a perfect page indexed in three weeks). Stack-native (writes into the user's framework — Next.js, Astro, Rails+Inertia, or a portable markdown fallback).
| Mode | When | What it produces |
|---|---|---|
| Initialize | docs/seo-machine.md does not exist | Stack detection → brand context → keyword research → tech audit → roadmap + link inventory |
| Resume | docs/seo-machine.md exists | Reads the tracker, picks the next pending phase (or one the user names), executes end-to-end through the quality gates |
Detection rule on every invocation: check docs/seo-machine.md at repo root (or the path recorded in .seo/config.json). No file → Initialize. File exists → Resume. The user does not need to remember which mode they're in.
The roadmap orders patterns by conversion intent first, traffic intent second. This is the single most important decision the skill makes — it's why the alternatives + comparison pages ship before the playbooks + blog posts.
| Order | Pattern | Why | Cost |
|---|---|---|---|
| 1 | /alternatives/[competitor] (Pattern A) | Highest conversion intent — the reader is already in market | ~4 hours per page |
| 2 | /compare/[a]-vs-[b] (Pattern D) | Be the third option in any two-vendor comparison | ~3 hours per page |
| 3 | /for/[use-case] and /for/[audience] (Pattern B/C) | JTBD without competitor name in query — high TP/volume ratio | ~4-5 hours per page |
| 4 | /playbooks/[topic] (Pattern E) | Authority + AI-citation surface area + inbound link draw | ~2-3 days per page |
| 5 | /blog/... (out of scope here) | Lowest conversion intent; defer until ~10 indexed pages exist | — |
Why this order matters: alternatives pages convert 5–20× blog posts at 1/10 the search volume. Shipping one alternatives page is worth ten generic blog posts on the same topic. The roadmap should reflect this — Phase 0 (tech audit) → Phases 1–N (alternatives, then comparisons, then use-cases) → late phases (playbooks) → never (blogs, unless explicitly requested by the user).
Striking-distance boosts (pages already ranking pos 5–20 in GSC) jump the queue when they exist — fastest wins per hour of work.
brand/keyword-plan.md, positioning.md, competitors.md, audience.md, stack.md. Missing files are fine.Validate KD/competition with OpenSEO get_keyword_metrics / get_serp_results before generating pages; consume openseo-keyword-clustering outputs when present. Qualitative research uses Exa-stack (or manual) per the shared ordered resolver — record research_backend in .seo/config.json. Full contract: skills/openseo/references/backend-contract.md.
Brand context loaded:
├── Keyword Plan ✓/✗ (seeds the roadmap; ✗ → generate during Initialize)
├── Positioning ✓/✗ (drives /compare and /alternatives angles)
├── Competitors ✓/✗ (target list for /alternatives pages)
├── Audience ✓/✗ (intent buckets for /for/<persona> pages)
└── Stack ✓/✗ (selects references/stacks/<framework>.md)
Progressive enhancement: with zero brand files the skill still works — it derives signal from the repo during Initialize Step 2. With full brand context it skips re-discovery and goes straight to research + roadmap.
Exa recipes: references/exa-recipes.md + references/api-stack-recipes.md. Manual fallback: references/manual-research.md. Ahrefs is an optional paid overlay only (see Exa recipes appendix).
| # | Check | Failure mode |
|---|---|---|
| 1 | git rev-parse --is-inside-work-tree succeeds | Stop. Tell the user this skill writes a persistent roadmap; initialize git or run from a repo. |
| 2 | A stack is detectable — one of package.json, Gemfile, composer.json, requirements.txt, astro.config.*, next.config.*, nuxt.config.*, gatsby-config.*, _config.yml, config.toml, pyproject.toml | Ask the user what stack they're on before continuing. |
| 3 | Research backend resolved (skills/openseo/references/backend-contract.md) | Never refuse to run — fall through to manual mode. |
Goal: end the run with a written docs/seo-machine.md containing keyword research, a phase tracker grouped by pattern, and technical-audit findings — plus .seo/brand.md and .seo/link-inventory.md.
Read references/stacks/detection.md. Identify framework family, routing convention (file-based vs controller-based), component language, and existing marketing pages (git ls-files | grep -iE 'marketing|landing|pages/(home|about|pricing)'). Resolve ambiguity with AskUserQuestion. Persist to .seo/config.json.
Read every signal first, propose .seo/brand.md, then ask only about gaps. Signals: CLAUDE.md, README.md, package.json / Gemfile.lock, tailwind.config.* or design-token CSS, app/views/marketing/* or pages/index.*, pricing page.
If brand/voice-profile.md and brand/positioning.md already exist (mktg-native project), read them and skip 80% of the questions — those files already say who the buyer is and what the brand sounds like.
Otherwise use a single AskUserQuestion (3–4 questions max) to fill gaps. Required to know:
Write to .seo/brand.md using assets/brand-template.md as the skeleton.
Follow references/exa-recipes.md — 7 Exa-native recipes that replace the Ahrefs cookbook:
| Recipe | Purpose | Primary API |
|---|---|---|
| A. Domain baseline | DR estimate from indexed-page count + brand mentions + GitHub stars (OSS) | Exa company_research_exa + web_search_advanced_exa + gh |
| B. Competitor reverse-lookup | What competitors rank for | Exa web_search_advanced_exa site:<competitor> + AI summary |
| C. Use-case sweep | /for/ and /playbooks/ topic discovery | Exa deep_search_exa + Firecrawl autocomplete + /last30days |
| D. Comparison volume | Validate demand for /compare/[a]-vs-[b] before writing | Exa web_search_advanced_exa + Firecrawl SERP scrape |
| E. SERP saturation | Replaces Ahrefs KD with SERP-composition-derived signal | Exa search + per-result company_research_exa |
| F. Backlink prospecting | Referring-domain proxy via Exa | Exa search + DR proxy (see off-page-seo skill) |
| G. Content gap | Their indexed keywords − ours, ranked by DR-cap fit | Recipes B + own-site Exa lookup |
Then pull cross-API compound recipes from references/api-stack-recipes.md for moves Ahrefs alone can't do — pain-point cluster discovery (/last30days + mktg-x + Exa deep search), OSS competitor teardown (gh + DeepWiki + Exa), outreach prospect discovery (Exa Websets + people-research), newcomer surveillance (Exa Websets cron).
When Exa is unavailable, fall back to references/manual-research.md (paste-from-UI workflow). When the user has paid Ahrefs, layer it on top per the appendix in exa-recipes.md — don't replace.
Cache the raw output to .seo/keyword-research.json. Curate the decision-ready summary into the Keyword Research Appendix section of docs/seo-machine.md.
Run scripts/tech_audit.py (sitemap, robots, meta-tag uniqueness, schema). Whatever it finds becomes Phase 0 in the roadmap. Day-0 crawl shapes Google's understanding of the site for months — retroactive fixes are harder.
Fill assets/roadmap-template.md with:
traffic_potential desc → volume desc → KD ascWrite to the configured path (default docs/seo-machine.md). Print the path back and recommend a human review pass before Phase 0.
.seo/link-inventory.mdEvery phase reads this file to pick internal links. Use assets/link-inventory-template.md. Pre-populate from existing routes (features, tools, pricing, blog posts). Each phase appends to it as new pages ship.
✓ Initialize complete
Roadmap: docs/seo-machine.md
Brand context: .seo/brand.md
Keyword cache: .seo/keyword-research.json
Link inventory: .seo/link-inventory.md
Config: .seo/config.json
Next: review docs/seo-machine.md, then run me again to execute Phase 0.
Do not auto-execute Phase 0. Pattern priorities and competitor lists are decisions worth a human pass.
Goal: pick the next phase from the tracker, execute end-to-end with quality gates, hand back so the user can commit/PR.
Load docs/seo-machine.md, .seo/brand.md, .seo/link-inventory.md, .seo/config.json. Find the Phase Status Tracker, identify the next pending phase with the lowest number, print it back along with the two phases that follow.
Single AskUserQuestion:
"Different" → list pending phases. "Re-audit" → loop back into Initialize steps 3–5. "Show" → print tracker and stop.
Pattern → reference mapping:
| Phase type | Reference |
|---|---|
| Phase 0 — technical foundations | references/technical-audit.md |
Pattern A — /alternatives/[competitor] | references/patterns/alternatives.md |
Pattern B/C — /for/[use-case] or /for/[audience] | references/patterns/use-case.md |
Pattern D — /compare/[a]-vs-[b] | references/patterns/compare.md |
Pattern E — /playbooks/[topic] long-form | references/patterns/playbooks.md |
| Striking-distance boost | references/striking-distance.md |
| Off-page checklist phase | references/off-page.md |
| Internal-link spine audit | references/quality-bars.md (link-audit section) |
For page-generating phases, the flow is always:
references/stacks/<framework>.md) or references/stacks/markdown-fallback.md.scripts/word_count.py and scripts/link_audit.py. If a check fails, fix it — don't ship under-spec work..seo/link-inventory.md with the new page.docs/seo-machine.md — status completed, PR ref or commit SHA. Same edit batch as the page work so reviewers see both in one diff.✓ Phase N complete: [title]
Files changed:
app/controllers/marketing_controller.rb (added entry)
app/frontend/pages/Alternatives/Show.tsx (no change — uses existing layout)
docs/seo-machine.md (tracker updated)
.seo/link-inventory.md (new page registered)
Quality gates:
✓ Word count: 712 / 600 min
✓ Internal links: 2 alts, 1 feature, 1 tool
✓ FAQ JSON-LD attached
✓ Honesty section present (3 rows)
Suggested commit: "SEO Phase N: ship /alternatives/[slug]"
Next phase pending: Phase N+1 — [title]
Open a PR only if the user has expressed they want that cadence. Otherwise let them drive git.
| Rule | Why |
|---|---|
| Ask before you guess on positioning calls | The user's gut on which competitor or use-case to ship next often beats the data |
| Show the numbers, not the conclusion | "vol 400, KD 12, TP 1,800" builds more trust than "the data is good" |
| Be honest about what won't work | KD 80 at DR 8 = doomed. Say so, offer the closest winnable alternative |
| One-sentence theory max per phase | The user doesn't need a recap of SEO theory every run |
| Surface tradeoffs, not opinions | "5 thin alternatives or 2 deep ones first?" — state the tradeoff, ask |
| Skill | When | When NOT |
|---|---|---|
seo-audit | One-off diagnostic on an existing site | Forward execution — use this skill |
seo-content | Writing a single rankable article | A whole sprint — use this skill |
competitor-alternatives | One /alternatives/<x> page, ad-hoc | Pattern A as part of a sprint — use this skill |
keyword-research | Producing brand/keyword-plan.md | This skill consumes that artifact — chain them |
ai-seo | LLM-citation optimization for a few pages | Run after this skill ships ~10 indexed pages |
| Don't | Why |
|---|---|
| Target head terms when DR is low | "Social media management tool" at DR 8 is wasted work. KD ≤ DR+10 while DR is low. |
| Ship pages with no inbound internal links | A new page nobody links to is an island. ≥2 inbound links from existing pages, same phase. |
Ship /alternatives pages without an "honesty" section | Three honest tradeoffs (where the competitor wins) is non-negotiable. Brand signal AND Google quality signal. |
| Skip schema markup | FAQPage JSON-LD captures snippets. Article for playbooks. SoftwareApplication for homepage + use-case. Quality gate fails without them. |
| Auto-commit | Always show diff summary; let the user commit (local conventions, hooks, branch naming). |
| Restart Initialize when partial state exists | If .seo/config.json exists without the roadmap, prompt before wiping — they may have aborted mid-run. |
| File | Purpose |
|---|---|
references/methodology.md | Why-this-works theory + lessons from real phases |
references/exa-recipes.md | 7 Exa-native research recipes (replaces the old Ahrefs cookbook). Ahrefs appendix at the bottom for paid-precision escalation. |
references/api-stack-recipes.md | Cross-API compound recipes — pain-point mining, OSS competitor teardown, outreach prospect discovery, newcomer surveillance. Uses Exa + Firecrawl + gh + mktg-x + DeepWiki + last30days. |
references/manual-research.md | L0 fallback when no MCP available |
references/patterns/alternatives.md | Pattern A spec, data shape, quality bar, example |
references/patterns/use-case.md | Pattern B+C spec |
references/patterns/compare.md | Pattern D spec |
references/patterns/playbooks.md | Pattern E spec (2,500-word bar) |
references/stacks/detection.md | Stack-detection signal table |
references/stacks/rails-inertia.md | Rails + Inertia adapter (reference implementation) |
references/stacks/nextjs.md | Next.js App Router adapter |
references/stacks/astro.md | Astro content-collection adapter |
references/stacks/markdown-fallback.md | Universal markdown output format |
references/technical-audit.md | Phase 0 recipes (sitemap, robots, meta, schema) |
references/striking-distance.md | GSC pos 5–20 audit + boost recipe |
references/off-page.md | Backlink checklist + Ahrefs referring-domains research |
references/quality-bars.md | Verification spec per pattern |
scripts/word_count.py | Strip markup → word count |
scripts/link_audit.py | Verify internal-link minimums per page |
scripts/tech_audit.py | Sitemap.xml + robots.txt + meta-tag scanner |
assets/roadmap-template.md | docs/seo-machine.md skeleton |
assets/brand-template.md | .seo/brand.md skeleton |
assets/link-inventory-template.md | .seo/link-inventory.md skeleton |
The skill writes to project paths, not brand/. This is why writes: in skills-manifest.json is [] — the manifest declares only brand/*.md writes, and seo-machine's outputs live in the user's repo, not in brand memory.
| Output | Mode | Purpose |
|---|---|---|
docs/seo-machine.md | Initialize (write), Resume (update phase row) | Persistent sprint roadmap — Phase Status Tracker + Reference Data + Keyword Research Appendix. Single source of truth across sessions. |
.seo/brand.md | Initialize | Product context derived from repo + user answers (one-liner, persona, competitors, voice tags, anti-positioning). |
.seo/link-inventory.md | Initialize (create), Resume (append per phase) | Every internal-link target the skill can use. Each phase appends new pages. |
.seo/keyword-research.json | Initialize | Cached raw output from Ahrefs / Exa / manual research. Read by every phase, refreshed every 30 days. |
.seo/config.json | Initialize | Stack info, research backend choice, project IDs. Persists machine-readable state. |
| Phase-specific page files | Resume (per phase) | Stack-native page files (e.g. app/controllers/marketing_controller.rb + app/frontend/pages/Alternatives/Show.tsx for Rails+Inertia; app/[pattern]/[slug]/page.tsx for Next.js App Router; etc.). Paths follow references/stacks/<framework>.md. |
This follows the Long-Arc Sprint Persistence Pattern documented in AGENTS.md — docs/seo-machine.md is the canonical doc that survives session interruption.
/cmo routes here under Playbook #9 — SEO Authority Build, Path B (programmatic sprint). On a cold project /cmo first spawns mktg-brand-researcher, mktg-audience-researcher, mktg-competitive-scanner in parallel (foundation), runs keyword-research to populate brand/keyword-plan.md, then hands off here. After every phase, /cmo spawns mktg-content-reviewer + mktg-seo-analyst in one message to score the page batch before the user commits.
See skills/cmo/rules/playbooks.md and skills/cmo/rules/sub-agents.md for the full handoff contract.
Alternatives
MoizIbnYousaf/marketing-cli
Backlink + distribution checklist that expands a site's KD ceiling beyond what on-page work alone can earn. Use when the user mentions 'backlinks', 'off-page SEO', 'directory submissions', 'guest posts', 'outreach targets', 'link building', 'submit to directories', 'get listed in listicles', 'Product Hunt launch backlinks', or asks 'how do I get more domain authority'. Generates a prioritized, researched target list across directories, listicles, and guest-post candidates — does NOT submit anyth
github/awesome-copilot
Use this skill when the user asks to analyze, tear down, or reverse-engineer a competitor's paid ads. Trigger for prompts like "what ads is [competitor] running", "tear down their ad strategy", "competitor ad analysis", "find ad angles we haven't tried", or "reverse-engineer their paid funnel". Do not trigger for organic/SEO competitor research or website positioning analysis.
MoizIbnYousaf/marketing-cli
Creates high-converting 'X vs Y' and 'X alternatives' SEO pages that capture comparison search traffic. Researches competitors, writes honest comparison content, and adds schema markup (FAQPage, ItemList). Use when someone needs alternatives pages, comparison content, or says 'alternatives page', 'vs page', 'comparison', 'competitor alternatives', 'X vs Y page', or wants to capture competitor brand search traffic with SEO content. Also trigger when someone wants to rank for competitor brand name
MoizIbnYousaf/marketing-cli
Strategic keyword research powered by web search and brand context. Use this skill whenever the user mentions keywords, keyword research, SEO topics, content topics, 'what should I write about', content strategy, blog ideas, search traffic, or content planning. Also trigger when the user wants to plan what content to create, when existing content isn't attracting search traffic, when any skill needs keyword-plan.md but it doesn't exist, or when the user asks about SEO in the context of content c