seo-ops
seo-ops checks a site's SEO foundation — the machine-readable structure search engines and AI retrieval need to fetch, read, index, and cite it.
Give it a URL. The checker fetches the site the way a crawler does and returns a pass/fail report with evidence for every check. No code access, no framework integration, no LLM.
The page looks fine. Can a crawler read it?
A site can look finished in a browser and still be invisible to the machines that decide whether it gets indexed or cited: a robots.txt that blocks AI crawlers, a body that only exists after JavaScript runs, a canonical that points somewhere else, a sitemap full of dead entries.
seo-ops reads only the final HTTP and HTML output. It does not matter who produced it — backend templates, frontend code, or third-party scripts — so React, Vue, Next.js, WordPress, and plain static sites are all tested the same way.
| System | What it answers |
|---|---|
| Rank tracker | Where do my pages rank? |
| Analytics | Who visited, and from where? |
| Content review | Is the writing accurate and good? |
| seo-ops | Can search engines and AI retrieval fetch, read, index, and cite this site at all? |
How it works
The whole repo is three pieces. The checker is deterministic: the same site gives the same report, and every red item carries the evidence that made it red.
The C set.
30 SEO and GEO structural checks, each with a permanent ID, a priority, and its own doc: why the check exists, how to fix it, and the authoritative reference behind it.
The checker.
One script. It fetches like a crawler and reports against the C set — zero LLM, no frontend-framework dependency, because it only reads the live HTTP and HTML output.
The T set.
A supply checklist for the content team: which inputs SEO needs content to provide — titles and descriptions, the H2 outline, image alt text, the YMYL judgment, OG copy — each mapped to the checks it feeds.
What it checks
Checks are grouped by where they apply, never by page type, and ranked by what breaks if they fail.
| Group | Checks | Examples |
|---|---|---|
| Site-level, once per site | 10 | robots.txt allows AI crawler user agents · sitemap reachable with truthful lastmod · www/apex, http/https, and trailing-slash variants all 301 to one host · no Accept-Language redirects · llms.txt |
| Per indexed page | 18 | self-referencing canonical · full body served without JavaScript · no noindex · unique title and description within limits · JSON-LD parses with required fields · exactly one h1 with no skipped levels · complete Open Graph set |
| Conditional | 2 | YMYL trust block when a page is flagged ymyl · hreflang reciprocal pairs when the site is multi-language |
| Priority | Meaning |
|---|---|
| P0 | Existence layer: uncrawlable, unindexable, or a compliance and privacy risk — it hurts the whole site. |
| P1 | Performance layer: ranking and citation are discounted. |
| P2 | Optimization. |
All green does not mean fully compliant. Styling, UX, content truthfulness, ranking, and traffic are out of scope, and the prohibitions a machine cannot judge — buying links, cloaking, fake structured data — live in a separate red-line list guarded by people.
Get started
Let your agent install it — copy this to your agent:
Install https://github.com/tigerless-labs/seo-ops as a skill.Or install it as a plugin. Claude Code, typed in the Claude Code input box:
/plugin marketplace add tigerless-labs/seo-ops
/plugin install seo-ops@seo-opsCodex, run in your terminal:
codex plugin marketplace add tigerless-labs/seo-ops
codex plugin add seo-ops@seo-opsThen type /seo-ops in the agent's input box, or just describe the task:
/seo-ops check example.comThe agent asks one question — a URL, live or localhost, or the code in this repo — then runs the checker and explains the red items by priority, reading each check's own doc rather than guessing from the evidence. The checker needs Python 3.9+ with requests and PyYAML, and network access to the target site; no configuration is required to run it.
More in the works — built in the open, shipped fast.