Deterministic AEO/GEO checks and a source-cited rulebook for AI search, for your agent.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Optional. Bearer <aeogeo Pro key> unlocks the keyed tools; the free tools need no key.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Create a private, shareable static report link for 1-2 public URLs. The report is rendered from the same scan output as scan_url — free callers get the aggregate report, Pro/Team callers get the detailed one — and the link works in any browser without an API key. Compare mode puts two URLs side by side; keyed reports add a per-rule delta. Use when: You want a link to paste into Slack, docs, email, or a pull request so a person (or link-preview bot) can read the scan without the API key. Avoid when: You need the raw scan result right now. Use scan_url and keep the JSON in context. Do not claim: A report is a snapshot of one scan — not a citation and not a live measurement. Verify: Open the returned https://aeogeo.site/r/<id> URL, or append ?format=md or ?format=json for other export formats. expires_at says when the link stops working.
One URL for a single report, or two URLs for compare mode.
single (default for one URL) or compare (two URLs, side by side).
How long the link works, in days. Default: 30 for a Pro/Team report (it shows paid detail to anyone with the link), 90 for a free one. The owner can revoke a Pro/Team link earlier at https://mcp.aeogeo.site/account.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http aeogeo https://mcp.aeogeo.site
Headers
Authorization (optional, not in the config above): Optional. Bearer <aeogeo Pro key> unlocks the keyed tools; the free tools need no key.Create a private, shareable static report link for 1-2 public URLs. The report is rendered from the same scan output as scan_url — free callers get the aggregate report, Pro/Team callers get the detailed one — and the link works in any browser without an API key. Compare mode puts two URLs side by side; keyed reports add a per-rule delta. Use when: You want a link to paste into Slack, docs, email, or a pull request so a person (or link-preview bot) can read the scan without the API key. Avoid when: You need the raw scan result right now. Use scan_url and keep the JSON in context. Do not claim: A report is a snapshot of one scan — not a citation and not a live measurement. Verify: Open the returned https://aeogeo.site/r/<id> URL, or append ?format=md or ?format=json for other export formats. expires_at says when the link stops working.
| Argument | Type | Description |
|---|---|---|
| mode | string | single (default for one URL) or compare (two URLs, side by side). |
| urls* | array | One URL for a single report, or two URLs for compare mode. |
| expires_in_days | integer | How long the link works, in days. Default: 30 for a Pro/Team report (it shows paid detail to anyone with the link), 90 for a free one. The owner can revoke a Pro/Team link earlier at https://mcp.aeogeo.site/account. |
{
"type": "object",
"required": [
"urls"
],
"properties": {
"mode": {
"enum": [
"single",
"compare"
],
"type": "string",
"description": "single (default for one URL) or compare (two URLs, side by side)."
},
"urls": {
"type": "array",
"items": {
"type": "string",
"description": "Absolute public http(s) URL to report on."
},
"maxItems": 2,
"minItems": 1,
"description": "One URL for a single report, or two URLs for compare mode."
},
"expires_in_days": {
"type": "integer",
"maximum": 90,
"minimum": 1,
"description": "How long the link works, in days. Default: 30 for a Pro/Team report (it shows paid detail to anyone with the link), 90 for a free one. The owner can revoke a Pro/Team link earlier at https://mcp.aeogeo.site/account."
}
},
"additionalProperties": false
}Fetch a stable teaser sample of up to 20 public rules (no evidence or remediation). Optionally filter by category. Use when: You have no API key and need to see what a public rule looks like. Avoid when: You have a key and need the full rule. Use fetch_rules or search_rules. Do not claim: A teaser has no remediation. It is not enough to apply the rule. Verify: This is a read. Nothing on the page changes until you edit and scan or lint.
| Argument | Type | Description |
|---|---|---|
| category | string | Optional category name from list_categories. |
{
"type": "object",
"properties": {
"category": {
"type": "string",
"description": "Optional category name from list_categories."
}
},
"additionalProperties": false
}Return a ready-to-paste snippet that hooks this rulebook into your agent: AGENTS.md instructions, Cursor rules, or a Claude Code skill. Use when: You are onboarding a repo and need the install text for that client. Avoid when: The snippet is already installed and you are checking a page. Do not claim: Installing the snippet does not scan the site. Verify: Call tools/list. A free snippet names only free tools; a keyed snippet names the lint chain.
| Argument | Type | Description |
|---|---|---|
| client* | string | Target client: agents_md, cursor, or claude. |
{
"type": "object",
"required": [
"client"
],
"properties": {
"client": {
"enum": [
"agents_md",
"cursor",
"claude"
],
"type": "string",
"description": "Target client: agents_md, cursor, or claude."
}
},
"additionalProperties": false
}List the rulebook categories with the number of active rules in each. Use when: You need a category name before reading rules. Avoid when: You are grading a page. Use scan_url or a lint tool. Do not claim: A category count is not a coverage score for any site. Verify: Pass a name from this list to fetch_sample_rules, or to fetch_rules when you have a key.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Start here for any audit or research task. Give your goal, the target and your limits; get back an ordered list of aeogeo tool calls with the quota each costs, which steps are semantic (judge: agent), what was deferred to fit your budget, your tier's daily limits, and the semantic-review rubric for the page type. Deterministic: no inference, no fetch, same input gives the same plan. The semantic review and report steps are never dropped to fit a budget. Use when: You are about to audit a page, a draft or a site, or answer a research question, and want the right calls for your goal, effort and remaining quota. Avoid when: You already know the single tool you need, such as scan_url on one URL. Do not claim: A plan is not a finding. Nothing was scanned or evaluated. Verify: Run the steps in order; the semantic review step is yours to do.
| Argument | Type | Description |
|---|---|---|
| goal* | string | fix_errors: engine defects first, cheapest path. pre_publish: lint a draft, then scan after deploy. citation_readiness: adds evidence and changelog lookups. site_audit: whole site, sampled semantic review. research: rulebook questions, no scan. |
| budget | object | Optional limits. calls: tool calls you will spend. rules: rules you can still draw today. pages: site-scan pages left today. |
| effort | string | quick (default): fewest calls. standard: two rule lookups. thorough: three, plus insights. |
| page_count | integer | Pages on the site, when known; sizes the scan_site step. |
| target_kind | string | What is being audited: a live url, a whole site, draft html, draft text, a json-ld block, or none (research). |
Run this on your own domain first: run the AI-search hygiene checks on a public URL. A grade is not a citation and does not measure AI mentions. Free callers get per-group grades plus every failed fundamental (readiness levels L0-L3) with how to fix it; Pro/Team callers also get rule IDs, severity and evidence for every check, plus a work list. Do the highest weight first. propose is always true: draft the change, a person applies it. Free results may be cached for up to an hour; keyed scans always fetch the page fresh. Batched callers pass detail=failures to drop passing checks. A page whose robots.txt disallows it for aeogeo-scanner is not fetched (blocked_url). A scan is step 1 of an audit, not the audit. Before you report on a page: (1) fetch the rules behind every failed check and every judge: agent check with fetch_rules or search_rules; (2) read the page's actual copy and judge it yourself against those rules (claims supported, sources real, answers the query, fits the page genre, false positives); (3) report engine defects, agent semantic findings and evidence confidence separately. Say plainly if you skipped the semantic pass. Use when: The page is already public and you want the bytes a crawler receives. Avoid when: The draft is only local. Use lint_html for HTML, lint_text for markdown, or audit_schema for JSON-LD. content_type is an argument on those tools and on scan_url, not a separate tool. Do not claim: A grade or a pass is not a citation. The check says the page matches the rulebook. Verify: Deploy the edit, then call scan_url again. A keyed scan fetches fresh. judge: engine — trust the pass/fail from the deterministic check (access, rendering, and mechanical structure). judge: agent — your agent re-reads the rule text and decides; the label comes from the deterministic judgeForCheck mapping, not an LLM on our side.
| Argument | Type | Description |
|---|---|---|
| url* | string | Absolute public http(s) URL to scan. |
| detail | string | Keyed callers only; a free scan already lists failures alone and ignores it. full (default): every check. failures: only failed and skipped checks plus the page and group grades, grade_basis and the do-not-claim guidance — use it for batched calls or when a full response would be truncated. |
We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 7, 2026.
No readOnlyHint / destructiveHint annotations, so clients can't tell a read from a write without asking.
Fix: Add annotations to each tool, e.g. { readOnlyHint: true } for tools that only read.
| content_type | string | Content type used to select applicable checks. |
{
"type": "object",
"required": [
"goal"
],
"properties": {
"goal": {
"enum": [
"fix_errors",
"pre_publish",
"citation_readiness",
"site_audit",
"research"
],
"type": "string",
"description": "fix_errors: engine defects first, cheapest path. pre_publish: lint a draft, then scan after deploy. citation_readiness: adds evidence and changelog lookups. site_audit: whole site, sampled semantic review. research: rulebook questions, no scan."
},
"budget": {
"type": "object",
"properties": {
"calls": {
"type": "integer",
"minimum": 0
},
"pages": {
"type": "integer",
"minimum": 0
},
"rules": {
"type": "integer",
"minimum": 0
}
},
"description": "Optional limits. calls: tool calls you will spend. rules: rules you can still draw today. pages: site-scan pages left today.",
"additionalProperties": false
},
"effort": {
"enum": [
"quick",
"standard",
"thorough"
],
"type": "string",
"description": "quick (default): fewest calls. standard: two rule lookups. thorough: three, plus insights."
},
"page_count": {
"type": "integer",
"minimum": 1,
"description": "Pages on the site, when known; sizes the scan_site step."
},
"target_kind": {
"enum": [
"url",
"site",
"html",
"text",
"jsonld",
"none"
],
"type": "string",
"description": "What is being audited: a live url, a whole site, draft html, draft text, a json-ld block, or none (research)."
},
"content_type": {
"enum": [
"blog",
"landing",
"product",
"faq",
"docs",
"general"
],
"type": "string",
"description": "Content type used to select applicable checks."
}
},
"additionalProperties": false
}| content_type | string | Optional. What the page is, for pages that declare no schema.org @type or og:type. Without it the scanner infers the type and, when it cannot, skips the type-specific checks with a reason. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"description": "Absolute public http(s) URL to scan."
},
"detail": {
"enum": [
"full",
"failures"
],
"type": "string",
"description": "Keyed callers only; a free scan already lists failures alone and ignores it. full (default): every check. failures: only failed and skipped checks plus the page and group grades, grade_basis and the do-not-claim guidance — use it for batched calls or when a full response would be truncated."
},
"content_type": {
"enum": [
"blog",
"landing",
"product",
"faq",
"docs",
"general"
],
"type": "string",
"description": "Optional. What the page is, for pages that declare no schema.org @type or og:type. Without it the scanner infers the type and, when it cannot, skips the type-specific checks with a reason."
}
},
"additionalProperties": false
}