Over the last few weeks, I’ve been deep in the weeds of “Building AI-Accessible Infrastructure” It’s a fascinating architectural challenge: how do we shift from optimizing for eyeballs to optimizing for context-hungry agents?

As I was documenting the various layers of “AI-accessible” infrastructure—from llms.txt files to Model Context Protocol (MCP) endpoints—I kept hitting the same wall: I wish there was a quick, automated way to check all these signals at once. Not just “does this file exist,” but “is it implemented in a way that an LLM agent can actually consume it?”

So, I built one.

Today, I’m launching GEO Score (Generative Engine Optimization Score), a free, no-login scanner at javatask.dev/geo/ that audits your site for AI readiness across 13 technical signals.

What GEO Score Measures

The scanner focuses on the “technical plumbing” required for an AI agent to discover, parse, and trust your content. It breaks these down into three distinct layers, each representing a different stage of the agent-to-site interaction:

1. The Discovery Layer (Head Checks)

Before an agent can read your content, it needs to know where it lives. We perform rapid HEAD requests to verify the existence of these roadmap files:

  • llms.txt (15pts): The emerging standard for LLM-friendly documentation. It provides a human-readable and machine-parsable entry point for agents.
  • llms-full.txt (5pts): The expanded version for comprehensive context, often containing the full text of documents.
  • sitemap.xml (10pts): While built for search engines, modern AI agents use sitemaps to build their initial crawl frontier.
  • robots.txt AI Policy (8pts): We check if you have explicitly defined a policy for agents. Are you explicitly allowing (or blocking) AI bots like GPTBot, ClaudeBot, or Google-Extended?

2. The HTML Layer (Homepage Parse)

Can an agent extract semantic meaning and metadata from your raw HTML without relying on fragile scrapers?

  • JSON-LD Schema (10pts): We specifically look for Article or TechArticle schema. Structured data is the highest-signal way to tell an agent what your content is actually about.
  • Meta Description (8pts): We look for 50-160 characters of clean context. If it’s too short, it’s useless; too long, and it gets truncated.
  • Meta Author (5pts): Essential for attribution. Agents need to know who wrote the content to weigh its authority.
  • Canonical Link (8pts): Preventing duplicate content confusion by telling the agent which URL is the source of truth.
  • OpenGraph (OG) Tags (10pts): Standardized titles, descriptions, and URLs that provide a fallback for agents when custom schema is missing.
  • Performance (5pts): TTFB (Time to First Byte) < 800ms. Agents have time budgets too; slow sites get skipped or deprioritized in real-time search.
  • Payload Size (3pts): Page size < 500KB. Large payloads are expensive for LLMs to tokenize and process.
  • Security Headers (12pts): We check for HSTS, CSP, X-Content-Type, and Referrer-Policy. High-trust agents prioritize secure sites to avoid hallucinating based on injected or insecure content.

3. The MCP Layer (Conditional)

This is the “next gen” of site-agent interaction, moving beyond static files to interactive capabilities.

  • .well-known/mcp.json (10pts): The discovery endpoint for Model Context Protocol servers. This allows your site to provide dynamic “tools” or “resources” directly to an agent.
  • Markdown Mirror (Fail/Pass): Does /index.md respond with text/markdown? Providing a clean Markdown version of your HTML allows agents to bypass the noise of navigation, ads, and scripts.

⚠️ Important: What GEO Score is NOT

Before we look at some results, let’s be crystal clear about the scope. GEO Score measures TECHNICAL IMPLEMENTATION signals only.

  • A site like mozilla.org or wikipedia.org might score low on this tool because they haven’t implemented llms.txt yet, but they are still heavily cited by AI because of their massive domain authority and content quality.
  • The tool does not measure domain authority, backlink profile, content quality, or citation history.
  • It does not read your content to see if it’s “good.” It only checks if the delivery mechanism is “correct.”

Think of it this way: GEO Score tells you, “Have you implemented the plumbing?” It does not guarantee, “Will AI cite you?” Technical signals are necessary for long-term discoverability, but they aren’t a replacement for quality writing.


Dogfooding: Scanning javatask.dev

Of course, the first thing I did after finishing the scanner was point it at my own site. I was confident I’d see a straight ‘A’.

I was wrong. I got a Grade B.

Here is the breakdown of what the scanner found:

  • llms.txt / llms-full.txt: Pass (20pts) - My Hugo setup generates these automatically as part of the build process.
  • sitemap / mcp.json: Pass (20pts).
  • robots.txt: Warn (4pts) - I actually block GPTBot and Google-Extended on some subdirectories to protect draft content and internal tools. The scanner gave me half credit for having a policy, but flagged the blocks as a warning since it limits the agent’s reach.
  • meta_author: Fail (0pts) - I was shocked to find that while I had og:author in my OpenGraph tags, I was missing the standard <meta name="author"> tag. This is a classic example of “shadow metadata”—info that humans see (via the site UI) but machines miss. I fixed this on the spot.
  • JSON-LD: Warn - When scanning the homepage, the tool found WebSite and Person schema, but not Article.

A Note on Scanning Homepages vs. Posts

One key insight from dogfooding: two “fails” or “warnings” are often expected when you scan a site’s root domain rather than a specific article.

The scanner checks the specific URL you provide. If you scan javatask.dev/, the tool won’t find an Article schema because the homepage is a list of summaries, not a single post. Similarly, my site only serves a Markdown mirror for individual blog posts to keep the homepage lightweight.

Pro-tip: To see your true score, scan a specific blog post URL. That’s where the Article schema and Markdown mirror checks will actually shine.

Technical Brief: Rust, Axum, and Lambda

I wanted GEO Score to be fast—like, really fast. When a user enters a URL, they shouldn’t be staring at a spinner for 10 seconds. I built the backend in Rust using the Axum framework, deployed as an AWS Lambda function.

  • Concurrency: The scanner doesn’t run checks sequentially. It uses a three-round parallel orchestrator. Round one handles HEAD requests for discovery files. Round two fetches the main HTML and parses it using the scraper crate. Round three probes any discovered MCP endpoints.
  • Performance: The average scan takes ~200ms of actual compute time. The rest is just network latency as we wait for the target site to respond. By using Rust on Graviton2 (ARM64) Lambdas, I can keep the cold starts minimal and the execution cost nearly zero.
  • Security: Building a tool that fetches arbitrary user-provided URLs is an SSRF (Server-Side Request Forgery) nightmare. The backend includes a robust validator.rs module that resolves the hostname and rejects private IPv4/IPv6 ranges, loopbacks, and non-HTTPS schemes before the request is ever dispatched.
  • Rate Limiting: To prevent abuse while remaining “no-login,” I implemented an in-memory rate limiter that tracks IP addresses, allowing 5 scans per hour. It’s a balance between preventing bot-on-bot violence and keeping the tool accessible.

Try it Yourself

You can run a scan right now at javatask.dev/geo/.

It’s completely free, requires no login, and performs no tracking. It’s just a tool for builders who want to make sure they aren’t leaving technical performance on the table in the AI era.

What would you like me to add? I’m considering adding checks for specialized AI-agent headers or deeper Sitemap validation. Let me know your thoughts.

Happy building, Andrii Melashchenko