geo-check-mcp
geo-check-mcp
An MCP server that checks whether a website is technically ready to be read and cited by AI search (ChatGPT search, Perplexity, Copilot, Gemini, Claude). It runs over stdio and has no API keys.
AI answers change over time; this tool does not and cannot guarantee that a site will be recommended. It checks the technical factors a site owner controls.
Tools
Tool | Network | What it does |
| no | Lists the 16 crawler user-agents checked (GPTBot, OAI-SearchBot, ChatGPT-User, PerplexityBot, Perplexity-User, ClaudeBot, Claude-SearchBot, Claude-User, Google-Extended, Googlebot, Bingbot, Applebot-Extended, Amazonbot, Meta-ExternalAgent, CCBot, Bytespider) with operator and purpose. |
| no | Evaluates pasted robots.txt text for each crawler and path. Follows RFC 9309: user-agent group merging, a specific group beating |
| yes | Full check of a public site: AI-crawler access, homepage JSON-LD types, |
check_site is polite. It makes about 4 GET requests 1 second apart, sends a declared User-Agent
(GeoCheckBot/0.1 (+mailto:...), which you can change in geo_check.py), obeys robots.txt for its own
user-agent, and fetches only the homepage. It does not spoof crawler user-agents, so CDN or firewall bot
blocking (for example Cloudflare "Block AI bots") is reported as "not checked".
Related MCP server: aeo-mcp
Install and run
pip install -e . # needs Python 3.10+, mcp>=1.2 (works with SDK 1.x FastMCP and 2.x MCPServer)
geo-check-mcp # stdio server
# or: python -m geo_check_mcpClaude Desktop / Cursor config:
{
"mcpServers": {
"geo-check": { "command": "geo-check-mcp" }
}
}Try it with MCP Inspector:
npx @modelcontextprotocol/inspector --cli geo-check-mcp --method tools/list
npx @modelcontextprotocol/inspector --cli geo-check-mcp --method tools/call --tool-name check_site --tool-arg url=https://example.comThe checker also works without MCP: python src/geo_check_mcp/geo_check.py https://example.com --md out.md --json out.json.
Tests
pip install -e '.[test]'
pytest -q # offline: robots parser + stdio protocol self-test
GEO_LIVE_URL=https://example.com pytest -q # also runs one live check_site callUse this as a template for your own MCP server
The layout keeps business logic and the MCP layer apart:
src/geo_check_mcp/
geo_check.py # plain Python, no MCP imports; unit-testable
server.py # ~60 lines: one decorated function per tool
tests/
test_robots.py # logic tests
test_server_stdio.py # starts the server, sends raw JSON-RPC: initialize, tools/list, tools/callTo wrap a REST API, a CSV or Airtable base, or an internal service instead:
Replace
geo_check.pywith a client module (read secrets from environment variables, never hard-code them).In
server.py, write one small@mcp.tool()function per action, with type hints and a docstring. The SDK builds the JSON schema from them.Run slow or blocking I/O in a thread (
anyio.to_thread.run_sync) so the stdio loop stays responsive.Update
test_server_stdio.pywith the new tool names and one offline call each.
License
MIT, see LICENSE.
Available Tools
3 toolscheck_robotsA
Evaluate robots.txt text (no network) for AI crawlers.
Args: robots_txt: full robots.txt content. path: URL path to test, e.g. "/" or "/blog/post". user_agents: crawler tokens to test; defaults to the built-in AI crawler list.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | / | |
| robots_txt | Yes | ||
| user_agents | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that no network access occurs and that a built-in AI crawler list is applied by default, but it never says what the evaluation returns (allow/deny per agent, matched rule) nor how conflicting directives are resolved.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One-line purpose statement followed by a compact Args block where every line carries information not present in the schema. No filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description should sketch the return shape, and it does not — an agent cannot tell whether it receives a boolean, a per-agent map, or matched rules. Parameter coverage is adequate, but the result contract is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate, and it does: robots_txt is defined as full file content, path gets concrete example values ("/", "/blog/post"), and user_agents is defined as crawler tokens with a stated default. Only minor ambiguity remains, such as whether tokens match case-insensitively or accept full UA strings.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: evaluate robots.txt text for AI crawlers, with the key qualifier that it performs no network fetch. This clearly differentiates it from a live site check, but the siblings (list_ai_crawlers, check_site) are never named to make the boundary explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
"no network" and "for AI crawlers" imply the usage context (testing already-fetched robots.txt content against AI crawler tokens), but there is no explicit when-to-use statement or routing to check_site for cases where the caller doesn't already have the text.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_siteA
Run the full GEO technical check on a public website (robots.txt AI-crawler access, homepage JSON-LD types, /llms.txt, sitemap, title/description/canonical/h1).
Makes about 4 polite requests (1 s apart, declared User-Agent, obeys robots.txt).
Args: url: site URL, e.g. https://example.com format: "json" (structured report) or "markdown" (adds a human-readable report).
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| format | No | json |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses request volume ('about 4 polite requests'), throttling ('1 s apart'), a declared User-Agent, and robots.txt compliance. What's missing is whether it needs credentials or works only on public sites (it says 'public website', which mostly covers this) and what happens on failures/timeouts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and behavioral notes come first, then a compact Args block. Every line adds information — the check list, the politeness profile, and the format tradeoff — with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter, no-output-schema tool, the description covers what it does, how it behaves on the network, and what the format flag controls. The only real gap is the shape of the returned report, which the agent must discover at call time, though the 'structured report'/'human-readable report' phrasing sets expectations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate, and it does: 'url' gets a concrete format example (https://example.com) and 'format' is given the two meaningful values ('json' structured report vs 'markdown' adding a human-readable report). It stops short of stating URL normalization rules or whether scheme is required, but the enum semantics are clearly conveyed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Run the full GEO technical check') on a specific resource ('a public website') and enumerates the checks performed (robots.txt AI-crawler access, JSON-LD types, /llms.txt, sitemap, head tags). An agent can tell this is a broad bundled audit, but it never explicitly contrasts itself with the sibling check_robots, so differentiation is only implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The scope implies when to use it (you want the full site audit rather than a single robots probe), and the enumeration of checks hints that check_robots is a subset. However, there is no explicit 'use this when / use X instead when' statement, so routing between check_site and check_robots is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_ai_crawlersA
List the AI / search crawler user-agents this server checks, with operator and purpose.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral burden. 'List' strongly implies a read-only, side-effect-free operation, and the description usefully discloses the returned fields and scope, but it does not explicitly state read-only behavior, permissions, ordering, or pagination.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no wasted words. It gives the resource, scope, and return fields efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter informational tool with no output schema, the description is nearly complete: it identifies the crawler list and the operator/purpose fields. Minor missing context includes output ordering or whether the list is exhaustive, but nothing essential prevents correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The description does not need to explain parameters and correctly focuses on the returned crawler list instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'List the AI / search crawler user-agents this server checks, with operator and purpose.' The scope ('this server checks') and return fields ('operator and purpose') make clear it is a reference listing of crawler identities, not a site or robots checker like the sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by explaining that the server checks these crawlers and that operator/purpose are returned, but it does not explicitly say when to call this versus check_robots or check_site, nor does it state any exclusions. The use case is inferable but not guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
check_robots - First observed
check_site - First observed
list_ai_crawlers
TDQS
Scored across 3 tools
list_ai_crawlers (reference data), check_robots (offline robots.txt evaluation) and check_site (network-based full GEO audit) each have a clearly stated purpose. The only mild overlap is that check_site also covers robots.txt AI-crawler access, so an agent could conceivably pick check_site when it only wanted the robots check, but the offline/online distinction in the descriptions resolves this.
All three names follow a consistent verb_noun snake_case pattern: list_ai_crawlers, check_robots, check_site. The check_ prefix groups the two evaluation tools logically and list_ signals the reference-data tool.
Three tools is on the small side, but the server's scope (GEO/technical crawlability checks) is narrow and each tool earns its place: one reference list, one offline evaluator, one full site audit. Slightly thin but well scoped rather than padded.
The surface covers the core GEO workflow: discovering which crawlers matter, testing robots.txt offline, and running a combined audit of robots.txt, JSON-LD, /llms.txt, sitemap and head tags. Minor gaps exist — no standalone llms.txt or JSON-LD/sitemap check, and no offline HTML inspection — but these are reachable through check_site.
Maintenance
Related MCP Connectors
Unified 15-tool SEO, SERP, clean Markdown & GEO (LLM citation Share-of-Voice) MCP server.
Open-source AI SEO over MCP: audits, ranks, keywords, backlinks + AI visibility (GEO).
6-category AI readiness, Schema.org, robots.txt, /llms.txt & 25k-token audit + auto-fix MCP server
AI search readiness MCP: score a site for ChatGPT/Claude/Perplexity crawlers. 3 free/day.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceMCP server for website SEO + GEO analysis. Scan any URL to get scores across 5 categories (SEO, GEO, Performance, Security, Accessibility) with actionable fix recommendations. Enables AI coding assistants to audit websites and implement fixes autonomously.-
- AlicenseAqualityDmaintenanceAn MCP server that gives AI agents tools to inspect a website's visibility to AI answer engines, including crawler permissions, llms.txt, structured data, on-page signals, and a full 29-check AI-readiness audit.50MIT
- AlicenseNot gradedqualityDmaintenanceMCP server exposing Generative Engine Optimization tools to any AI agent, enabling checking of llms.txt, auditing robots.txt for AI crawlers, and validating JSON-LD schema.MIT
- AlicenseNot gradedqualityDmaintenanceOpen-source MCP server that audits websites for AI search readiness, providing deterministic scoring (0-100) and prioritized fix lists for metrics like JSON-LD, llms.txt, heading hierarchy, and AI crawler access.1MIT