
aieo
io.github.web-casaPublished by GitHub account web-casav1.3.0Updated Oct 29, 2026
SEO and AI-search checks for a website's build output, fixed in the source files
Overview
Read-only MCP tools that run aieo's SEO and AI-search checks on a site's build output, so an assistant can inspect findings and plans.
- What you can do
- Run build checks and baseline diffs, and inspect a single page's findings
- Look up rule metadata and explanations for finding ids
- Report on access-log coverage, crawler gaps and search-engine results
- Show plans for IndexNow submission and for uploading a bundle to aieo.ee, without sending anything
- Scope any tool to one site in a monorepo with an optional project directory
- When to use it
- Useful when an assistant helps maintain a site built with a supported framework (Astro, Next.js, Nuxt, Hugo, VitePress, Docusaurus and others) and should diagnose SEO, structured-data, sitemap, robots or AI-crawler problems from the build before it ships, or review what a deploy changed.
- Requirements
- The aieo binary must be installed and on PATH; the server runs locally over stdio, started in the project directory. Optional features need their own credentials: a Google Cloud OAuth client or GOOGLE_APPLICATION_CREDENTIALS for Search Console, BING_WEBMASTER_API_KEY for Bing, CLOUDFLARE_API_TOKEN for log pulls, and an aieo.ee organisation API key for push. Network access is needed for crawler IP verification and search data unless run offline.
Installation
In SourceWeft
- Open aieo in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
aieo-cli
SEO/GEO checks for a site's build output, before it ships — the inside view for aieo.ee.
aieo.ee checks what a site serves over HTTP. aieo reads what the build
produced (dist/), what the framework declares and what the deployment
config adds (_redirects, _headers, vercel.json, netlify.toml,
Next.js manifests), and checks that the pieces agree with each other:
sitemap ↔ robots.txt ↔ canonical ↔ hreflang ↔ internal links ↔ llms.txt ↔
redirects ↔ framework settings. With a baseline it fails a build only on
what the change made worse.
Install
Static binaries for Linux (x86_64, aarch64), macOS (Apple silicon, Intel)
and Windows are attached to each GitHub release,
with a .sha256 next to each; install.sh verifies it and installs to
~/.local/bin (AIEO_VERSION=1.0.0 pins a release, AIEO_INSTALL_DIR
changes the directory). From source: cargo install --git https://github.com/web-casa/aieo-cli aieo-cli
(Rust 1.88+).
Frameworks
The preset is detected from package.json and config files (--preset to
force one). Findings point at the source file a page was built from.
Server builds (Next.js .next/, Nuxt and TanStack Start with a server
bundle) are served as production would: prerendered HTML, public/, the
redirects/rewrites/headers of routes-manifest.json, and every other route
as rendered on request — links to it count as working, its HTML is not
checked, and a server-rendered homepage makes the homepage modules
unverified (exit 2 unless --allow-incomplete). Client-rendered SPAs are
checked for what crawlers without JavaScript see (K-SPA-SHELL).
fixtures/presets/ holds a real build of the same site per framework with
its snapshot (cargo test -p aieo-cli --test presets).
What it checks
Every rule has an id, a tier and a source: aieo rules, aieo explain <id>.
Tiers: error = a deterministic defect (fails the default gate),
warning = high risk (fails a diff when new), notice = advice. Rules
without an official source are marked heuristic and are never errors by
default; length-based title rules are off unless enabled.
Exit codes: 0 gate passed · 1 gate failed · 2 incomplete evidence
(no homepage, origin unknown, undecodable HTML) or a usage error — a check
that could not see enough never reports "all clear".
Same rules as aieo.ee
The rule metadata, crawler catalog and bundle schema in spec/ are exported
from @aieo/rules, the package aieo.ee's scanner reads. F02–F18 are
implemented twice (TypeScript in aieo.ee, Rust here) and held together by
the conformance fixtures in spec/fixtures/conformance: the same tiny sites,
the same module status, ratio and reason (cargo test -p aieo-rules --test conformance). F01 (HTTPS, redirects) needs a live origin; F15 reads a .md
twin of the homepage instead of content negotiation.
Access logs
- Who: user agents are matched against the shared crawler catalog
(
spec/crawlers.json: OAI-SearchBot, ChatGPT-User, GPTBot, Claude-*, PerplexityBot, Googlebot, Bingbot, Applebot, …) and classed assearch_index,user_fetch,training,classic_search, other automation or people. Visits whose referrer (orutm_source) is an AI answer platform are AI referrals. - Verified or not: a claimed crawler is checked against its
operator's published IP ranges (downloaded, cached a day under
.aieo/cache/, listcreationTimerecorded), then by forward-confirmed reverse DNS where the operator documents it.mismatch= spoofed; a crawler without a published method isunverifiable, never called fake.--offlineskips the network. - Kept locally:
.aieo/logs.db(SQLite). A file is recognised by its first bytes, so a growing log resumes and a rotated copy is not counted twice. Crawler requests keep a salted IP hash (.aieo/salt), people only per-day counts — no IPs, no browser user agents..aieo/.gitignorekeeps the salt, database and caches out of git. - Findings (L): a crawler mostly answered 401/403/429 (WAF / bot protection), crawler 5xx, robots.txt unavailable (5xx/429), a crawler 404 spike, spoofed crawlers, verified crawlers on disallowed paths, AI search crawlers reaching few indexable pages. With a build next to the logs, coverage is measured against its indexable pages.
- Cloudflare GraphQL returns sampled hourly counts without IPs: rows
carry their count, verification stays
unchecked, and the plan's limits are read from the zone'ssettings. aieo exportadds the log aggregates (logsinaieo-bundle/v1) when.aieo/logs.dbexists.
Search engines
Everything runs with your own credentials, stored in your config
directory (~/.config/aieo/credentials.json, owner-only) or taken from
the environment in CI. Data lands in .aieo/search.db.
- CI: set
GOOGLE_APPLICATION_CREDENTIALSto a service account key whose e-mail is a user of the Search Console property (the device flow does not allow Search Console scopes). - URL Inspection keeps a local quota ledger (2,000 per property a day, 600 a minute) and inspects the URLs it looked at longest ago first.
- Findings (S), read against the build: an indexable page Google has not indexed, a canonical Google overrode, a page the build serves that Google could not fetch / found blocked / saw noindexed (production is not what was built), clicks halved against the previous period, an IndexNow key the build does not serve.
- Bing's AI Performance and Google's AI Overviews report have no API; the Bing overview export is imported with the same rules as aieo.ee.
IndexNow
Changes are found by comparing page hashes with the baseline
(aieo snapshot), so only what a deploy touched is sent. Nothing is
sent without --yes, and every request is recorded in
.aieo/audit.jsonl.
aieo.ee
aieo push uploads to [aieo] project in aieo.toml (or --to <id>).
The same commit and kinds uploaded twice are recognised as one run. The
bundle carries findings, page inventory and aggregates — no page source,
raw logs or IP addresses — and can also be dropped on the project's
"Inside view" page.
Configuration (aieo.toml)
[[hosting.*]] rules apply after the ones the build and the host config
declare; use them when routing lives in code (Next.js middleware, an edge
function) so that links into rewritten paths are not reported as broken.
CI
Findings appear as annotations on the pull request, a Markdown summary is
added to the job summary, SARIF and the evidence bundle are written next to
the project. Without the action:
aieo diff --format github --report sarif=aieo.sarif --report bundle=.aieo/bundle.json.gz.
GitLab: include ci/gitlab-ci.yml and extend .aieo;
findings show as a JUnit test report on the merge request.
AI agents (plugin, skills, MCP)
The aieo binary must be on PATH (see Install). Then:
The same directory is a Cursor plugin (.cursor-plugin/), for the Cursor
Marketplace; until it is listed there, use the skills and MCP rows above.
The plugin brings five skills — aieo (check → edit the source file →
rebuild → check), aieo-ci, aieo-crawlers, aieo-indexing,
aieo-llms-txt (plugins/aieo/skills) — and the MCP
server.
aieo mcp serves read-only tools over stdio: check, diff, page,
explain_rule, list_rules, logs_report, logs_gaps, search_report,
indexnow_plan, push_plan. Each takes an optional project (a directory
relative to where the server runs) for one site in a monorepo. Nothing
that writes outside the machine is a tool — the *_plan tools show what
aieo indexnow submit --yes or aieo push would do, for the user to run.
Output and data
--format pretty | json | sarif | github | markdown | junit, plus any number of
--report FORMAT=PATH (bundle = gzip JSON). JSON and the bundle are
aieo-bundle/v1 (spec/bundle.schema.json): findings, page inventory,
readiness and multi-page scores — never page source, raw logs or IP
addresses. Configuration findings carry the config file and line
(astro.config.mjs:4, vercel.json:12), so SARIF and GitHub annotations
land on the setting to change.
Rule versions
Rules come from @aieo/rules (embedded in the binary):
a patch release changes wording or fixes a false positive, a minor release
adds rules, a major release changes what an existing rule means. Rule ids
are never reused. A finding from a rule added — or widened, see changed
in spec/rules-history.json — after the
baseline was taken is reported as unknown, not new, so upgrading aieo
alone never fails aieo diff; take a new snapshot to adopt it.
Development
Crates: aieo-core (spec, findings, config, bundle) · aieo-site (build
directory as production serves it: routes, host rules, robots, sitemaps,
HTML, framework presets) · aieo-rules (F / P / T / C / K / D) ·
aieo-report (formats) · aieo-logs (parsers, classification, IP
verification, SQLite store, Cloudflare GraphQL) · aieo-search (Search
Console, Bing Webmaster, IndexNow, credentials, aieo.ee upload) ·
aieo-cli (the aieo binary).
MIT licensed.
Source: README.md at commit c23ab55
Tools
0Version history
3- v1.3.0LatestOct 29, 2026
- v1.2.0Oct 22, 2026
- v1.1.1Oct 22, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts