← Back to Blog

Why MCP Server Audit Exists

· Updated October 13, 2026 · 7 min read Why MCP Server Audit Exists

TL;DR. AI search = discovery (classic SEO buys the seat) + retrieval (passage-level chunking buys the citation). AI crawlers do not execute JS, so every critical claim must live in the server-rendered HTML.

Updated October 13, 2026: I added where a current MCP server card lives and what it contains (SEP-2127), how the AI catalog points to it, and an honest note on where this audit lags that spec.

The MCP Server Audit is the audit you reach for when you already suspect a problem in this dimension and need a fast, copy-paste-able fix list. It reuses the same chrome as every other jwatte.com tool (deep-links from the mega analyzers, AI-prompt export, CSV/PDF/HTML download), but the checks it runs are narrow and specific to the dimension described above.

Probes for Model Context Protocol (MCP) server publication at /.well-known/mcp/server-card.json, /.well-known/mcp.json, the legacy /.well-known/mcp-server.json and related discovery paths (agent-card, agent-skills, api-catalog, oauth-protected-resource, ai-plugin, AGENTS.md, /mcp). Audits CORS headers when a card is found.

What it actually checks

Extract of the audit's real findings, the same strings the tool prints when a check trips. Use this as a sanity check before you run the audit live:

Fail conditions (fix these same-week):

  • no endpoint / server / base_url field
  • MCP manifest is not valid JSON

Warnings (fix these same-month):

  • manifest missing
  • no tools or capabilities declared

Info-only (context for the fix plan, not a failure):

  • No MCP / agent-card / ai-plugin manifest found
  • agent-card name
  • agent-card description

Pass signals (keep doing these):

  • tools or capabilities declared
  • endpoint declared

Where a current MCP server card lives

The Model Context Protocol now has its own discovery file: the MCP Server Card (SEP-2127, status Final). Here is what I check by hand today.

  • Address. The recommended address is your MCP endpoint plus /server-card. If your server answers at https://yourdomain.com/mcp, the card is https://yourdomain.com/mcp/server-card. A .well-known card path is allowed but listed as not recommended. Some scanners still read /.well-known/mcp/server-card.json and /.well-known/mcp.json, so I serve the same bytes there too.
  • Headers. Serve it as application/mcp-server-card+json, with Access-Control-Allow-Origin: *, Cache-Control: public, max-age=3600 and an ETag.
  • Shape. Required: $schema (exactly https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json), name in reverse DNS with one slash (like com.example/site), version, and a description of 1 to 100 characters. Optional: title, icons, repository, websiteUrl, remotes and _meta. Each entry in remotes has a type ("streamable-http" or "sse") and a url, plus optional supportedProtocolVersions.
  • No tools. The card does not list tools, resources or prompts. A client connects to the endpoint and calls tools/list to get them at runtime.
  • The catalog entry. Your AI catalog at /.well-known/ard.json should carry one entry for the server: an identifier like urn:air:yourdomain.com:mcp:site, type application/mcp-server-card+json, and url pointing at the card (not at the /mcp endpoint).

A minimal card looks like this:

{
  "$schema": "https://static.modelcontextprotocol.io/schemas/v1/server-card.schema.json",
  "name": "com.example/site",
  "version": "1.0.0",
  "description": "Search and quote tools for Example Co.",
  "remotes": [
    { "type": "streamable-http", "url": "https://example.com/mcp" }
  ]
}

The $schema URL is a name, not a link. On October 13, 2026 it answered 404, so validate against schema.json in the ext-server-card repository instead.

This audit lags that spec in a few places. It probes the two .well-known card paths and /mcp, but not /mcp/server-card or the AI catalog. It still expects tools and an endpoint, server or base_url field, so a correct card (which uses remotes and lists no tools) gets a "no endpoint" fail and a "no tools" warning. Its fix prompt still suggests /.well-known/mcp-server.json with a tools list. Until I update it, treat those two findings as noise on a SEP-2127 card, and use the Agent Endpoint Inspector to check the catalog and the card together.

Why this dimension matters

AI search runs in two stages: DISCOVERY (the LLM queries a classic search engine to get ~20 candidate URLs) and RETRIEVAL (it fetches those pages, chunks them into ~150-token passages, and cites whichever chunk best matches the query). Classic SEO buys the seat; paragraph-level structure buys the citation. AI crawlers (GPTBot, ClaudeBot, PerplexityBot, Google-Extended) do NOT execute JavaScript, so every critical claim must be in the server-rendered HTML.

Common failure patterns

  • SPA shell with empty <div id="root">: React / Vue / Angular apps that hydrate on the client look completely empty to AI crawlers. The fix is SSR (Next.js getServerSideProps, Nuxt asyncData, Svelte Kit load) or prerender / static export for content-heavy pages.
  • Missing llms.txt at the site root: the emerging standard for pointing AI crawlers at your canonical content. Absence is not catastrophic but presence makes your site noticeably easier to retrieve. Pair with llms-full.txt for full-content mirroring.
  • AI crawler-blocking in robots.txt without strategy: blocking GPTBot while allowing Googlebot is a choice; blocking all AI crawlers by default without knowing whether your audience queries ChatGPT / Claude / Perplexity is a cost. Decide deliberately; most content businesses benefit from allowing retrieval crawlers while blocking training crawlers.
  • Paragraphs over 300 words: each <p> is a retrieval unit for the chunker. Target 40 to 150 words per paragraph. Thinner = no answer match; thicker = split mid-thought and lose coherence at citation time.

How to fix it at the source

Start with llms.txt + llms-full.txt at the site root. Audit your robots.txt stance per bot deliberately. Restructure long paragraphs into 40 to 150 word chunks that each contain a complete claim + evidence pair. Track LLM referral visits via a custom Referrer segment (chatgpt.com, perplexity.ai, claude.ai, gemini.google.com, copilot.microsoft.com). That is the canonical AEO KPI.

Thresholds that matter

Scroll to compare columns and rows when the table extends beyond the box.

Signal Target
Paragraph length (retrieval unit) 40 to 150 words. Thinner fails to answer; thicker gets split mid-thought.
JSON-LD blocks 2+ per page (site-wide Org + page-specific type).
llms.txt byte size < 50 KB for fast ingestion; llms-full.txt can be larger (1 to 2 MB).
robots.txt per-bot directive Explicit for GPTBot, ClaudeBot, PerplexityBot, Google-Extended, CCBot, Bytespider, Applebot-Extended.

Example fix

llms.txt starter at site root:

# Your Business

> One-sentence "what this site is", used by LLM retrievers as the authoritative site description.

## Core content

- [About](https://yoursite.com/about): who you are, why you do this
- [Products](https://yoursite.com/products): catalog with stable URLs
- [Documentation](https://yoursite.com/docs): technical references

## Policies

- [Privacy](https://yoursite.com/privacy)
- [Terms](https://yoursite.com/terms)
- [AI-crawler policy](https://yoursite.com/ai.txt)

## Optional: full content mirror

- [llms-full.txt](https://yoursite.com/llms-full.txt): full canonical content for long-form retrieval

When to run the audit

  • After a major site change: redesign, CMS migration, DNS change, hosting platform swap.
  • Quarterly as part of routine technical hygiene; the checks are cheap to run repeatedly.
  • Before an investor / client review, a PCI scan, a SOC 2 audit, or an accessibility-compliance review.
  • When a downstream metric drops (rankings, conversion, AI citations) and you need to rule out this dimension as the cause.

Reading the output

Every finding is severity-classified. The playbook is the same across tools:

  • Critical / red: same-week fixes. These block the primary signal and cascade into downstream dimensions.
  • Warning / amber: same-month fixes. Drag the score, usually don't block.
  • Info / blue: context only. Often what a PR reviewer would flag but that doesn't block merge.
  • Pass / green: confirmation. Keep the control in place.

Every audit also emits an "AI fix prompt". Paste it into ChatGPT / Claude / Gemini for exact copy-paste code patches tied to your specific stack.

Related tools in this family

  • Mega AEO Analyzer: the AEO orchestrator, with 10 dimensions (citation, attribution, retrievability, freshness, tokenizer, prompt-injection, fair-use).
  • AI Posture Audit: cross-references robots.txt, ai.txt, meta robots, X-Robots-Tag per bot and flags disagreements.
  • llms.txt Quality Scorer: audits llms.txt structure against the llmstxt.org spec.
  • AI Crawler Access Auditor: simulates each major AI bot's crawl permissions on your site.
  • RAG Readiness Audit: tests how cleanly your pages chunk for enterprise RAG pipelines.

Fact-check notes and sources

Related reading

This post is informational and not a substitute for professional consulting. Mentions of third-party platforms in the tool itself are nominative fair use. No affiliation is implied.

← Back to Blog

Accessibility Options

Text Size
High Contrast
Reduce Motion
Reading Guide
Link Highlighting
Accessibility Statement

J.A. Watte is committed to ensuring digital accessibility for people with disabilities. This site conforms to WCAG 2.1 and 2.2 Level AA guidelines.

Measures Taken

  • Semantic HTML with proper heading hierarchy
  • ARIA labels and roles for interactive components
  • Color contrast ratios meeting WCAG AA (4.5:1)
  • Full keyboard navigation support
  • Skip navigation link
  • Visible focus indicators (3:1 contrast)
  • 44px minimum touch/click targets
  • Dark/light theme with system preference detection
  • Responsive design for all devices
  • Reduced motion support (CSS + toggle)
  • Text size customization (14px–20px)
  • Print stylesheet

Feedback

Contact: jwatte.com/contact

Full Accessibility Statement • Privacy Policy

Last updated: April 2026