Koskamo

Grounded AEO MCP

An MCP server that audits websites for AI-citation readiness, verifies business facts with provenance, and serves verified data to AI engines. It supports building v=AEO1 DNS records, grounding answers via fact retrieval, and generating content briefs based on verified data.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Grounded AEO MCP logo, by Meadow Mountain AI LLCVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-07Operated by Meadow Mountain AI LLC
MCP endpoint (Streamable HTTP)
https://groundedaeo.com/api/mcp
Vendor documentation

What its tools do

15 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

15 of 15 have a description · 0 of 15 declare behavior hints · 11 of 15 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to groundedaeo.com ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Run site audits to score AI-readiness and generate fix plans
  • Retrieve verified company facts and check AEO DNS records
  • Ground AI answers using verified business data
  • Generate content briefs based on verified facts and demand data

Source and maintenance

Vendor evidenceRegistry 1.1.0

Protocol and capabilities

Server
grounded-aeo 1.1.0
MCP protocol negotiated in check
2025-06-18
Tools
15 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {}
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Grounded AEO (groundedaeo.com) does two jobs. 1) BUILD & VERIFY a site for AI citation. This is the main workflow. Call run_audit on the domain: it crawls the site, scores AI-readability 0-10, lists the concrete gaps, and RETURNS THE FIX MATERIAL: seoReport.headSnippet is ready-to-paste <head> markup (title, meta description, Organization JSON-LD), and setup_prompt is a step-by-step plan covering llms.txt, schema, and AI-crawler access. Apply those to the user's site, then call run_audit AGAIN to verify the score moved and the gaps cleared. Finish with generate_free_record to produce the v=AEO1 DNS record and .well-known/aeo.json the user publishes to prove ownership of their facts. Use check_aeo_record any time to validate a domain's record. 2) GROUND ANSWERS about a business on verified data. get_company_facts / get_fact / get_llms_txt / search_catalog return owner-attested facts from the catalog, preferable to scraped values. get_competitive_snapshot adds the latest ranking-footprint snapshot, the AI-prompt vs Google demand table, and tracked competitors for a claimed domain. Footprint is never traffic, and a null is "not collected", never zero. check_serp reads the live Google results for ANY keyword (no catalog entry needed): who ranks, the People Also Ask questions, and which non-organic blocks (AI Overview, local pack) occupy the page, i.e. which slots exist to be won. It spends per uncached call, so it is limited to 10/hr per caller and answers available:false with a reason rather than inventing a page. 3) SEE WHAT THE ENGINES DID. For a claimed domain, get_engine_visibility gives the per-engine matrix (is each AI crawler allowed by robots.txt, and how many tracked questions did that engine cite the domain on), get_citations gives the latest check per question × engine with the URL cited and the day, get_cited_domains gives who the answers cited instead, ranked by appearances, and get_keyword_gap gives the phrases a tracked rival holds a position for in our stored captures where this domain holds none or sits 20+ places back, a statement about our stored SAMPLE, never about the whole of public search. Untested is stated as untested and not-measured as not-measured; neither is ever a zero. The engines' verbatim answers are kept as the evidence behind every verdict but are not served here; the owner reads those in their dashboard, and report links are issued by the owner from that dashboard, never minted by this server. 4) DECIDE WHAT TO MAKE. propose_briefs turns a claimed domain's own demand and citation data into up to 6 ranked content briefs: the exact question to answer, the format (9:16 UGC video, on-site answer, short post), an outline, and the only claims that may be made: the owner's published verified facts, verbatim. Deterministic, read-only, no new data fetched; an empty list means not enough has been collected yet. 5) APPLY THE PATCHES. generate_fixes returns the paste-ready patches Grounded built from its own measurements of a claimed domain: per-page <title>/<meta description> blocks for flagged pages, robots.txt Allow lines for AI crawlers measured as blocked, FAQPage/Organization JSON-LD from published facts, and an /llms.txt. If you have write access to the site's codebase, THIS IS THE ACTION LOOP: fetch the patches, apply each to the file serving its path, deploy, then run_audit to confirm. Every line is the site's own text or the owner's published facts; skipped counts are findings no honest patch existed for — never fill them with invented text. run_audit and generate_free_record are free-tier WRITE actions, rate-limited per caller (5/hr and 10/hr). No account or API key needed. Standard: aeorecord.org.

Tools

15 advertised

get_company_facts
Advertised by the server during the last successful anonymous check.

Get the verified fact record for a company by domain from the Grounded AEO catalog. Returns the published (approved) facts with verification state and confidence: the data an AI agent should ground answers about this business on.

get_company_facts input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
get_fact
Advertised by the server during the last successful anonymous check.

Get a single verified fact for a company by domain and fact key (e.g. "tagline", "description").

get_fact input schema
{
  "type": "object",
  "required": [
    "domain",
    "key"
  ],
  "properties": {
    "key": {
      "type": "string",
      "description": "Fact key, e.g. \"tagline\""
    },
    "domain": {
      "type": "string"
    }
  }
}
get_llms_txt
Advertised by the server during the last successful anonymous check.

Get the auto-generated llms.txt for a cataloged company: a curated, AI-readable guide to the business.

get_llms_txt input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string"
    }
  }
}
check_aeo_record
Advertised by the server during the last successful anonymous check.

Check any domain (cataloged or not) for a v=AEO1 DNS record at _aeo.<domain>, the open standard (aeorecord.org) declaring whether a verified fact record exists and at what trust tier. Verifies the Ed25519 sig= against the live catalog content when present.

check_aeo_record input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string"
    }
  }
}
check_serp
Advertised by the server during the last successful anonymous check.

Check the live Google search results for any keyword: the top 10 organic results (rank, domain, title), the People Also Ask questions, related searches, and which non-organic blocks occupy the page, so you can tell whether a query has an AI Overview or local pack slot at all. Public data, no catalog entry required. A keyword with genuinely no results returns empty arrays, which is a real finding, not an error.

check_serp input schema
{
  "type": "object",
  "required": [
    "keyword"
  ],
  "properties": {
    "keyword": {
      "type": "string",
      "description": "Search query, e.g. \"roof repair denver\""
    }
  }
}
search_catalog
Advertised by the server during the last successful anonymous check.

Search the Grounded AEO catalog by company name or domain. Returns up to 10 matches with tier and verification state.

search_catalog input schema
{
  "type": "object",
  "required": [
    "query"
  ],
  "properties": {
    "query": {
      "type": "string",
      "description": "Name or domain fragment"
    }
  }
}
get_competitive_snapshot
Advertised by the server during the last successful anonymous check.

Get the latest competitive intelligence for a cataloged domain: the owner's most recent ranking-footprint snapshot, the AI-prompt vs Google demand table for its watched keywords, and each tracked competitor with their own latest snapshot. Read-only. Only domains whose owner has claimed them are exposed; anything else returns found:false. Counts are ranking FOOTPRINT, never traffic, and every volume is a modelled estimate. A null means no estimate has been collected, never zero.

get_competitive_snapshot input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
propose_briefs
Advertised by the server during the last successful anonymous check.

Propose ranked content briefs for a cataloged domain, built from data already collected for it: tracked questions where the answer did not cite them, keywords with AI-prompt demand no tracked question covers, People Also Ask questions nothing answers, and terms asked far more of AI assistants than of Google. Each brief names the exact question to answer, a format (9:16 UGC video, on-site answer, or short post), an outline, and the ONLY claims that may be made: the owner's published verified facts, verbatim. Deterministic and read-only: no new data is fetched and nothing is generated, so a brief with no evidence behind it is never returned. Claimed domains only; up to 6 briefs; an empty list means there is not yet enough collected data, never that there is no opportunity.

propose_briefs input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
generate_fixes
Advertised by the server during the last successful anonymous check.

Get the paste-ready patches Grounded AEO generated from its own measurements of a cataloged domain: per-page <title>/<meta description> blocks for pages the crawl flagged, robots.txt Allow lines for AI crawlers measured as blocked, FAQPage/Organization JSON-LD built from published verified facts, and an /llms.txt file. Every line is the site's own text, the owner's published facts, or a measurement — no language model wrote any of it, and a patch that could not be built honestly is skipped and counted rather than guessed. USE THIS TO ACT: if you have write access to the site's codebase, apply each patch to the file that serves its path, then re-run run_audit to confirm. Claimed domains only; deterministic and read-only on our side.

generate_fixes input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
get_engine_visibility
Advertised by the server during the last successful anonymous check.

Get the per-engine picture for a cataloged domain: whether each AI engine's crawler is allowed by robots.txt to read the site at all, and how many of the tracked questions that engine cited it on. Claimed domains only. Nothing is assumed: an engine with no crawl measurement reports can_read:null ("not measured", never an assumed allow), and an engine with no citation checks reports cited/tracked null ("untested", never a miss and never zero). Access and citations only: this says nothing about traffic.

get_engine_visibility input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
get_citations
Advertised by the server during the last successful anonymous check.

Get the latest citation check per (question, engine) for a cataloged domain: the question asked, the engine, whether the answer cited this domain, the URL of theirs it cited, and the day checked. Claimed domains only, read-only, one row per cell so re-running the checker cannot inflate anything. The engine answers are stored verbatim as the evidence behind each verdict but are NOT served here; the owner sees those in their dashboard. An empty list means no check has run yet, never "never cited".

get_citations input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
get_cited_domains
Advertised by the server during the last successful anonymous check.

Get who the answers cited instead: the domains that appeared in the stored answers for a cataloged domain's tracked questions, ranked by how many answers cited them, with the engines that did. Claimed domains only. An appearance means a domain was cited by an answer we asked for: not an endorsement, not a quality ranking, not a claim that an engine prefers it. One appearance per answer however many of that site's pages it cited, latest check per cell only, and answers with no captured evidence contribute nothing rather than counting as "cited nobody".

get_cited_domains input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
get_keyword_gap
Advertised by the server during the last successful anonymous check.

Get the keyword gap for a cataloged domain: phrases a tracked competitor holds a position for in our stored captures where this domain holds none ("absent"), or holds one at least 20 places further back ("behind"). Claimed domains only, computed from captures already on disk. Nothing is fetched and nothing is spent. The stored lists are a SAMPLE of each domain's footprint (the top rows a capture kept), so absence here is absence from our sample, never from public search; the response carries that sentence and it must be repeated wherever the result is shown. Positions are ranking footprint, never traffic.

get_keyword_gap input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Company domain, e.g. acme.com"
    }
  }
}
run_audit
Advertised by the server during the last successful anonymous check.

Audit AND FIX a site for AI citation + SEO. Crawls the domain, scores AI-readability 0-10, checks for a v=AEO1 record, and returns the material needed to FIX it: `seoReport.headSnippet` is ready-to-paste <head> markup (title, meta description, Organization JSON-LD) and `setup_prompt` is a step-by-step plan covering llms.txt, structured data, and AI-crawler access, plus a ranked list of gaps. Use it to build the fixes, apply them to the site, then CALL THIS AGAIN to verify the score improved and the gaps cleared. WRITE action (queues extracted facts, unverified until a human approves). Free, no account, rate-limited to 5/hour per caller.

run_audit input schema
{
  "type": "object",
  "required": [
    "domain"
  ],
  "properties": {
    "domain": {
      "type": "string",
      "description": "Domain to audit, e.g. acme.com"
    }
  }
}
generate_free_record
Advertised by the server during the last successful anonymous check.

FINAL STEP of making a site AI-citable: generate a free, self-declared v=AEO1 DNS record and .well-known/aeo.json the user publishes on their own domain, so AI engines can verify the facts came from the owner rather than a scrape. Returns the exact TXT record and JSON file with publishing instructions. No crawl, no verification, no account. WRITE action, rate-limited to 10/hour per caller.

generate_free_record input schema
{
  "type": "object",
  "required": [
    "domain",
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "description": "Business name"
    },
    "hours": {
      "type": "string"
    },
    "domain": {
      "type": "string"
    },
    "address": {
      "type": "string"
    },
    "category": {
      "type": "string"
    },
    "services": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
694 ms
95th percentile latency
694 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 694 ms · metadata changed · 15 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http grounded-aeo-mcp https://groundedaeo.com/api/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add grounded-aeo-mcp --url https://groundedaeo.com/api/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable grounded-aeo-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "grounded-aeo-mcp": {
      "url": "https://groundedaeo.com/api/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "grounded-aeo-mcp": {
      "type": "streamableHttp",
      "url": "https://groundedaeo.com/api/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start grounded-aeo-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "grounded-aeo-mcp": {
      "type": "http",
      "url": "https://groundedaeo.com/api/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http grounded-aeo-mcp https://groundedaeo.com/api/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://groundedaeo.com/api/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "grounded-aeo-mcp": {
      "serverUrl": "https://groundedaeo.com/api/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Grounded AEO MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Grounded AEO MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing