Technical SEO, assistant visibility, content strategy, earned-distribution planning, and claim-provenance tooling for AI coding agents.
Status: v2.2.0. skill-manifest.json is the machine-readable source of truth for the shipped capability inventory. The previous seo-skill name and /seo command remain compatibility aliases.
The package combines:
- read-only search and performance connectors;
- deterministic technical auditors;
- higher-level diagnostics and Markdown reports;
- confirmation-gated external actions;
- evidence-based knowledge for Google Search and assistant discovery;
- normalized project profiles and context diagnostics;
- bounded robots/link/sitemap discovery;
- repeated assistant-visibility benchmarking;
- organic traffic measurement through the GA4 Data API (sessions, landing pages, device and country splits, read-only);
- keyword demand estimates through the Google Ads Keyword Planner API (bucketed volumes, competition, top-of-page bid ranges);
- audit drift monitoring: append-only JSON snapshots of one run, compared against a stored baseline;
- dated Google rich-result deprecation findings backed by Google primary sources;
- topic/content-portfolio planning and pure briefs;
- a content gap pipeline from Search Console gaps to ranked post candidates, evidence-gated drafts, and a human review queue;
- claim-provenance and YMYL evidence governance.
- evidence-led distribution fit, earned-source gaps, launch and video briefs;
- App Store discovery, organic experiment, referral, and earned-mention measurement;
- a hard human-only boundary for community posts, outreach, and review solicitation.
It does not claim a universal “GEO ranking” formula. Assistant API probes are labeled as proxies, structured data is not treated as authority, and llms.txt is optional documentation infrastructure rather than a search lever. GA4 sessions are not Search Console clicks, and Keyword Planner volumes are bucketed advertiser estimates rather than organic demand. Drift deltas are observations about what two runs reported, not causal claims. External communication modules do not exist: the skill can prepare evidence and human-reviewed drafts, but cannot post, send outreach, or solicit reviews.
See INSTALL.md. The installation directory keeps the legacy seo-skill name for compatibility:
git clone https://github.com/dominikmartn/organic-discovery-skill ~/.claude/skills/seo-skill
npx tsx ~/.claude/skills/seo-skill/actions/setup-auth.tsCredentials remain under ~/.config/seo-skill/ to avoid breaking existing installations.
project context
→ discovery and observations
→ applicable auditors
→ diagnostics and opportunities
→ reports
→ confirmed mutations
→ later measurement
→ drift comparison against a stored baseline
The stable module conventions are:
connectors/(14 modules): external read/write provider adapters, includinggsc,ga4,google-ads-keywords,psi,crux,openai-search,anthropic-search,perplexity,bing-webmaster,indexnow, andchrome-devtools;auditors/(14 modules): deterministic checks over supplied evidence;jsonldalso reports retired and restricted Google rich results;diagnostics/(18 modules): workflows combining observations and findings, includingdriftfor snapshot comparison andcontent-gapsfor query-gap clustering;actions/(17 modules): generators and confirmation-gated mutations, includingdrift-baselinefor append-only snapshot history andgenerate-post-drafts/review-queuefor the content gap pipeline;reports/(14 modules): pure Markdown builders, includingdrift-report;knowledge/(20 files): dated, sourced operational guidance, includingschema-deprecations.md;examples/(11 files): reference patterns with explicit limitations.
See the decision tree and browser operations.
The answer to auto-blogging tools, built so that it cannot become one.
GSC query rows (+ optional Keyword Planner volume)
→ content-gaps: gap selection, clustering, intent x volume x site fit ranking
→ content-gap-candidates: what each candidate answers, title, slug, content type
→ generate-post-drafts: markdown with required evidence slots, claim provenance, author
→ review-queue: draft → approved → published, approval by a named human
→ publish handoff: the approved markdown is written into the profile's publish directory
Every candidate passes through the same topic-opportunities evidence rules as any other planned asset, so a cluster with no distinctive contribution comes back as research, not as a post. Each draft carries three required evidence slots (benchmark number, product screenshot reference, first-party data point). A draft with no filled first-party slot fails validation and is never written to the queue. Author attribution comes from entity.owner in the project profile, and every filled slot runs through the claim-provenance auditor.
Human review is the feature, not a limitation. The pipeline stops at writing a file. There is no deploy step, no CMS integration, no scheduler, and no announcement, for the same reason the community-safety auditor blocks automated posting: the moment publishing is automatic, the review becomes theatre and the output becomes the scaled content Google's spam policies describe. That policy names no numeric threshold, so neither does this skill; the batch-size guidance in knowledge/content-gap-pipeline.md is labeled as the skill's own convention, sized to what a human can actually read in one sitting.
The right-hand column describes the two categories in general terms and not any specific product. Only the middle column is verifiable from this repository.
| Area | organic-discovery-skill | Prompt-pack skills and hosted audit suites |
|---|---|---|
| Form | Typed TypeScript modules with 440 passing tests across 87 test files (npm test) |
Prompt markdown, or a closed hosted product |
| Assistant citation data | Direct probes against the OpenAI, Anthropic, and Perplexity APIs with your own keys, labeled as API proxies rather than consumer-product measurements | Model-generated estimates, or a vendor-specific feature |
| Data dependency | Google, Bing, and assistant provider APIs directly; no paid SEO-data middleman | A vendor index and subscription, or no data source at all |
| Claim policy | Time-sensitive platform claims carry a primary source and a verification date; claims no primary source confirms are labeled unconfirmed and must not be reported as fact | Vendor rule sets and model priors, sources not always attached |
| Mutations | Sitemap submission, Indexing API notifications, Bing batches, and IndexNow run only through confirm()-gated actions |
Dashboard-triggered, or absent |
| Community and outreach | Blocked as an action surface; posts, partner outreach, and review requests can only become named-human-reviewed drafts | Often a separate automation or outreach product |
| Cost model | MIT source, you pay only your own provider usage | Subscription or seat pricing |
What it does not have:
- no local SEO modules (Google Business Profile, citations, map-pack tracking);
- no e-commerce modules (product feeds, merchant listings, variant or faceted-catalog handling);
- no PDF or slide report export; every report is Markdown;
- no keyword-difficulty score; the Keyword Planner connector returns competition levels and bid ranges as the advertiser-side proxies they are;
- no rank tracking against a scraped SERP index.
- Time-sensitive platform claims must include a primary source and verification date.
- Observational or anecdotal results must be labeled as such.
- No fixed uniqueness, recrawl, E-E-A-T, title-length, or impact formula is represented as a Google requirement.
- A provider API response is not automatically equivalent to its consumer assistant product.
- High-risk health and financial claims require source and reviewer evidence, not merely visible trust elements.
Real output from reports/drift-report.ts, produced by comparing two snapshots built from fixture data. The site, findings, and metrics below are invented for this example and describe no real property. First 30 lines:
# SEO Drift: https://example.com
> Baseline 2026-07-24T09:00:00.000Z → current 2026-08-07T09:00:00.000Z
> 2 regressions, 1 improvements, 0 unchanged.
> Deltas describe what the two runs reported. A finding that disappeared was not reported again; that is an observation, not proof it was fixed or that anything caused it.
## Regressions (2)
**New findings (1)**
- **[P0]** `robots` — https://example.com/pricing: noindex on a money page
**Escalated findings (1)**
- **[P0]** `canonical` — https://example.com/pricing: P1 → P0. canonical points off-host
## Improvements (1)
**No longer reported (1)**
- **[P2]** `jsonld` — https://example.com/pricing: no Organization node on the page
## Unchanged
0 findings were reported identically in both runs.
## Severity totalsA skill package that an AI coding agent loads to work on unpaid discovery: technical search eligibility, structured data, indexing, assistant and AI-answer visibility, content and distribution planning, and evidence governance for the claims a site makes. It is source code plus dated knowledge files, not a hosted service.
Node 22 and nothing else for the first run. The local crawler, deterministic auditors, project and content diagnostics, report builders, and all pure generators work with zero credentials. Keys unlock specific surfaces: a Google service account for Search Console analytics, URL inspection, and sitemap submission; a GA4 property for organic sessions and landing pages; a Google Ads developer token for Keyword Planner ideas; PSI and CrUX keys for performance data; OpenAI, Anthropic, and Perplexity keys for assistant-citation probes; Bing Webmaster and IndexNow keys for submissions. Each credential, its exact shipped use, and what it does not prove is listed in docs/auth-setup.md. Setup is npx tsx actions/setup-auth.ts, and every prompt can be skipped.
Yes, with a browser. The render-mode auditor and ChromeDevtools.renderCheck() compare raw HTML against rendered HTML through an injected browser client, so client-rendered main content is visible as a finding instead of an assumption. knowledge/nextjs-app-router.md and knowledge/svelte5-spa.md carry the framework-specific guidance. The adapter contracts and their limits are in docs/browser-operations.md.
Scope and evidence posture. Suites like the claude-seo family cover a wider marketing surface, including areas this package deliberately leaves out such as local SEO, e-commerce, and outreach execution. This package stays on organic discovery and adds two constraints: every time-sensitive platform claim carries a primary source and a verification date, and any claim a primary source does not confirm is labeled unconfirmed. Both approaches are legitimate; pick by whether you want breadth or a narrower surface with checkable sourcing.
It never posts, sends outreach, or asks for reviews. Community posts, partner outreach, and review solicitation are a human-only boundary enforced by the community-safety auditor and asserted in the test suite. The only external writes it can perform are sitemap submission, eligible Indexing API notifications, Bing URL batches, and IndexNow pings, and each of those requires an explicit confirm() call after the exact scope has been shown.
skill-manifest.json. The manifest-consistency test verifies package metadata and the existence of every declared path, so the manifest cannot drift from the shipped files without failing npm test.
MIT. See LICENSE.
npm test
npx tsc --noEmitRead skill-manifest.json for the authoritative lists. The manifest-consistency test verifies package metadata and every declared path.
Historical anonymized observations are retained in docs/reference-results.md as anecdotes with limitations. They are not causal validation or portable performance promises.
MIT. See LICENSE.