x-eo

Audit a site for search and AI answers, and know which points are real

Four Claude Code skills measure a site, fix the source, and prove that nothing else changed. Every finding carries an evidence tier, and the score is reported with and without the points that no engine has been shown to use.

audit.sh on a live site, 2026-10-07 (lines shortened)
$ bash audit.sh https://one-scroll-bible.com/
== https://one-scroll-bible.com/   (geo-optimizer-skill 4.18.3)
   score 90/100 (excellent)   excluding Tier C: 68/76 = 89%
   robots=18/18, llms=16/18, schema=16/16, meta=14/14, content=12/12,
   signals=3/6, ai_discovery=6/6, brand_entity=5/10, penalty=0
   [B] Add sameAs links in Organization schema to Wikipedia, Wikidata, ...
   [C] Add RSS/Atom feed and link it in <head> ...
   [C] Add potentialAction (SearchAction) to WebSite schema ...
   [SEC] This page exposes user-generated content ('respond' region) ...

Evidence tiers

AI search checkers mix three kinds of advice in one list: documented crawler behavior, plausible practice, and conventions such as llms.txt that no major engine has been shown to read. Google's AI optimization guide (updated 2026-07-10) says Google Search ignores AI text files and special markup.

x-eo labels every finding with a tier. A score that rose only through Tier C points is reported as such.

TierMeaningExamplesTreatment
ADocumented by the engine or directly observableHTTP 200, content in raw HTML, canonical, hreflang, sitemap, JSON-LD that parses and matches the pageFix first
BSupported only by third-party or correlational studiesAnswer-shaped passages, freshness, consistent entity name and sameAsDo it when it also helps readers
CConvention without demonstrated usellms.txt, ai.txt, /ai/*.json, WebMCPOnly if free; never counted as a result
SECSecurity findingPrompt-injection surface, exposed secretsConfirm a real write path before reporting

Four skills, one loop

  1. x-eo-auditMeasure the live site
  2. x-eo-fixChange the source, not the output
  3. x-eo-verifyBuild diff, JSON-LD, JavaScript on and off
  4. deployThen audit the live URL again

After deploy, the loop starts again from x-eo-audit with the same tool and version.

x-eo holds what the other three share: the tiers, honesty rules, report template, 13 pitfalls, a Korea guide (Naver, Daum, KakaoTalk), and 12 topic guides from claude-seo (MIT).

SkillScripts
x-eo-auditaudit.sh (score with and without Tier C, --threshold for CI), host-root-check.sh, site-sample.py, ai-recall.mjs (citations of your URLs by search-enabled AI APIs)
x-eo-fixgen-robots.py, JSON-LD templates, root files for sub-path sites, html-to-llms-full.mjs, gen-ai-files.mjs, indexnow.mjs
x-eo-verifydiff-builds.sh, jsonld-lint.py, render-diff.mjs (Playwright), local-audit.py

Install

Copy all four skills; they reference each other. There is no installer, hook or background agent.

  1. Clone and copy the skills

    git clone --depth 1 https://github.com/jungrok5/x-eo.git
    mkdir -p ~/.claude/skills && cp -r x-eo/skills/* ~/.claude/skills/
  2. Ask Claude Code

    Audit https://example.com with x-eo, fix the Tier A findings, and verify.

Requirements: bash, git, python3 3.10 or later. render-diff.mjs also needs playwright-core and a Chromium path in PLAYWRIGHT_CHROMIUM. ai-recall.mjs needs an Anthropic or OpenAI API key and costs one search-enabled request per question and engine.

Run the scripts without an agent

S=x-eo/skills
bash    $S/x-eo-audit/scripts/audit.sh --threshold 80 https://example.com/
bash    $S/x-eo-audit/scripts/host-root-check.sh https://example.com/blog/
python3 $S/x-eo-audit/scripts/site-sample.py https://example.com/ --max 8
node    $S/x-eo-verify/scripts/render-diff.mjs https://example.com/
python3 $S/x-eo-verify/scripts/jsonld-lint.py ./dist --require WebSite --strict
python3 $S/x-eo-fix/scripts/gen-robots.py --sitemap https://example.com/sitemap.xml --out robots.txt

Example: a 214-language static site, 62 to 90

12 of the 28 points were Tier C. Without them the score moved from 52/76 to 68/76.

The change with measurable value was prerendering the Korean root page: text visible without JavaScript rose from 11% to 53% of the rendered page, and the JavaScript-on DOM stayed byte-identical.

CategoryBeforeAfterTier
robots1518A
llms1016C
ai_discovery06C
schema716B
content1112A
penalty-30A/B
Total6290

Full write-up

Limits