Methodology
How the score works
A scan runs 62 checks across four weighted groups (28 scored, 34 informative), plus an unscored security posture badge. This page documents every rule, why it exists, and where the numbers came from.
Our own technical check
We put AIEO through it, too.
Same free scan, same published method. You can inspect the dated result.
This score measures our technical checks, not search rankings, live AI citations or revenue. Inspect the dated scan · How the score works
The four groups and their weights
The overall score is a weighted average of four group scores, each 0–100. A check that returns Info is excluded from its group's denominator entirely — it is displayed and explained, but it can never drag a score down the way a fail can. Only Pass,Warn (half credit) andFail (no credit) are scored.
Traditional SEO
40%
20 checks
AI Discoverability
25%
16 checks
Schema Coverage
15%
8 checks
Agent Interaction (WebMCP)
20%
8 checks
Pass / warn / fail bands
Two band sets are in use: a looser one for the single overall number, and a stricter one for each group score, because 100 is genuinely reachable group-by-group in a way it rarely is in aggregate.
Overall score
- Pass 75+ — Strong
- Warn 50–74 — Some gaps
- Fail below 50 — Needs work
Each group score
- Pass 90+ — Strong
- Warn 50–89 — Some gaps
- Fail below 50 — Needs work
75/50 keeps the overall band realistic against real sites — a 90/50 overall band would label well-known, well-built sites "needs improvement", which is not a useful signal for anyone reading the report.
Every check the scanner runs
The full registry: what each check is called, which group it belongs to, whether it is scored or informative, the rule it applies, and why it's there. Check IDs match the scanner engine and the report UI exactly, so a fix in one place is a fix everywhere.
| Check ID | Group | Mode | Rule | Why it matters |
|---|---|---|---|---|
| title | Traditional SEO | Scored | 50–60 characters, under ~600px rendered width. | Search engines truncate long titles and pad short ones; both cost click-through. |
| description | Traditional SEO | Scored | 150–160 characters. | Google truncates above ~160 characters and writes its own snippet when one is missing. |
| headings | Traditional SEO | Scored | Exactly one H1; at least one H2. | Search and AI systems use heading hierarchy as the primary topic and subtopic signal. |
| canonical | Traditional SEO | Scored | Self-referencing absolute canonical URL. | Without it, duplicate URL variants split ranking signals. |
| og | Traditional SEO | Scored | og:title, og:description, og:image all present. | Controls how links preview on LinkedIn, X and inside chat apps. |
| robots | Traditional SEO | Scored | File exists and references a sitemap. | robots.txt expresses crawling instructions for cooperating crawlers; it is not an access-control mechanism. |
| sitemap | Traditional SEO | Scored | Reachable, ≥1 URL; follows sitemap indexes; lastmod present and ≤90 days old. | Tells crawlers what exists and how fresh it is without them guessing via links. |
| viewport | Traditional SEO | Scored | width=device-width present. | Mobile-first indexing penalises pages that do not declare a responsive viewport. |
| img-alts | Traditional SEO | Scored | ≥70% of meaningful images carry non-empty alt text; explicitly hidden/presentational images are excluded. | Accessibility signal that also feeds AI image and multimodal understanding. |
| internal-links | Traditional SEO | Scored | ≥5 unique internal paths linked from the homepage (anchor fragments stripped; /cdn-cgi/ ignored). | Too few links starve both search and AI crawlers of a path to your content. |
| fetch-error | Traditional SEO | Informative | Records that AIEOBot could not retrieve a successful homepage response. | This is an observation from AIEOBot, not proof of what another crawler or browser receives. |
| robots-optout | Traditional SEO | Informative | robots.txt carries a User-agent: AIEOBot group that disallows /. | We honour robots.txt rules addressed to our own crawler, so the scan stops here. |
| canonical-host | Traditional SEO | Scored | http:// and https://www. redirect to one https host in ≤2 hops. | Duplicate reachable hosts split ranking and citation signals across "the same" site. |
| hard-404 | Traditional SEO | Informative | An unknown path returns a genuine 404, not a 200 "soft 404" page. | Soft-404s fool crawlers and well-known automated checkers alike. |
| html-lang | Traditional SEO | Scored | <html lang="..."> present. | Screen readers and AI systems use it to pick pronunciation and locale. |
| dup-titles | Traditional SEO | Scored | No two scanned pages share an identical title or description. | Duplicate metadata makes pages indistinguishable to search and AI alike. |
| og-image-reachable | Traditional SEO | Scored | og:image resolves 200 with an image/* content type. | A broken preview image is a common, invisible-until-shared failure. |
| http-caching | Traditional SEO | Informative | ETag or Last-Modified present. | Cheap freshness and bandwidth signal for repeat crawls. |
| perf-basic | Traditional SEO | Scored | TTFB ≤1.5s and HTML ≤1.5MB. | Slow or bloated HTML delays every crawler that fetches it, AI included. |
| indexnow | Traditional SEO | Informative | Key file present at /{key}.txt, or a known IndexNow-enabled platform detected. | Notifies participating search engines about changed URLs; crawling and indexing remain their decisions. |
| ai-bots | AI Discoverability | Informative | Per-bot allow/deny for the search, user-fetcher and training tiers under RFC 9309 (summary line; the tiers are scored separately). | Shows parsed robots.txt rules for named agents, rather than verifying live access. User-triggered fetchers may behave differently. |
| crawl-delay | AI Discoverability | Scored | Scanner heuristic: no Crawl-delay directive, or one of 5 seconds or less. | This directive can affect crawlers that support it; Google does not support crawl-delay. |
| answer-ready | AI Discoverability | Scored | Scanner heuristic: a self-contained 50–800 character paragraph directly follows the first heading. | A clear summary helps readers and tools extract the main answer. This placement test does not predict citations. |
| freshness | AI Discoverability | Scored | Scanner heuristic: a page/article dateModified, datePublished, article:modified_time or <time datetime> is present and ≤180 days old (Organization dates ignored). | Accurate dates describe publication or change. Freshness matters for some queries; a recent timestamp alone does not demonstrate increased AI citations. |
| llms-txt | AI Discoverability | Informative | Informative. Absent = note; present must be text/plain or text/markdown with an H1, ≥1 markdown link and ≥50 characters (the Lighthouse rules). | Optional orientation for tools that consume it; not a general requirement for AI-search visibility. |
| pricing-md | AI Discoverability | Informative | Informative. A plain-text /pricing.md exists. | A plain-text summary can help tools read your pricing without executing JavaScript. |
| ai-search-access | AI Discoverability | Scored | RFC 9309 evaluation: Googlebot, bingbot, OAI-SearchBot, Claude-SearchBot, PerplexityBot, DuckAssistBot and Applebot are not disallowed for /. | These rules affect crawler access; allowing a request does not guarantee indexing or a citation. |
| ai-training-policy | AI Discoverability | Scored | GPTBot, ClaudeBot and Google-Extended allow/deny reported and scored; the wider training-bot list is informative only. | Training permissions are a policy choice and need to be distinguished from search access. |
| ai-user-fetchers | AI Discoverability | Informative | Lists ChatGPT-User, Claude-User, Perplexity-User and similar; flags dead legacy tokens. | User-triggered fetchers can follow different rules from search and training crawlers; behaviour varies by provider. |
| robots-managed-conflict | AI Discoverability | Informative | Detects a Disallow group for a user-agent followed by an Allow group for the same agent (CDN-managed block or otherwise); warns when a search-lane bot is affected. | CDN-managed and owner-managed rules can differ; the combined policy needs to match your intent. |
| snippet-controls | AI Discoverability | Scored | No noindex/nosnippet/max-snippet:0 on a public page via meta robots or X-Robots-Tag. | Google uses indexing and preview controls to limit search presentation and content used directly in AI Overviews and AI Mode. |
| ssr-content | AI Discoverability | Scored | At least 300 characters of visible text present without executing JavaScript. | Content in the initial HTML is accessible without JavaScript; crawler and browser-agent capabilities vary. |
| bot-ua-blocked | AI Discoverability | Informative | Records the HTTP status the honest AIEOBot user-agent received from the homepage (401/403/402/challenge noted). | Network and access controls can differ by identity or request. An AIEOBot response does not establish whether another provider can fetch the page. |
| content-signal | AI Discoverability | Informative | Reports Content-Signal directives and the Content-Usage HTTP header proposed by the IETF AI Preferences working group. | These express usage preferences; adoption and interpretation vary by provider. |
| md-alternate | AI Discoverability | Informative | Accept: text/markdown returns a Markdown response, or a rel="alternate" Markdown link is advertised. | A growing pattern (Markdown for Agents) that hands agents clean content directly. |
| date-consistency | AI Discoverability | Informative | JSON-LD dateModified, visible "Updated" text and sitemap lastmod agree within 30 days. | Conflicting freshness signals undermine the ones a page does provide. |
| schema-missing | Schema Coverage | Scored | At least one JSON-LD block found. | Schema is how AI systems understand what a business or page actually is. |
| schema-types | Schema Coverage | Scored | Every JSON-LD block carries an @type. | Untyped or unrecognised blocks provide no machine-readable meaning. |
| schema-broken-url | Schema Coverage | Scored | No doubled https:// prefix in sameAs or similar URL fields (pass emitted when schema is present and clean). | A single malformed URL can make some consumers ignore the entire array. |
| schema-faq | Schema Coverage | Informative | Informative. Presence reported; never a warning when absent. | FAQ rich results were retired; presence is a courtesy note rather than a requirement. |
| schema-service | Schema Coverage | Scored | An Organization, LocalBusiness subtype or Service block is present. | AI systems use this to understand what the business does. |
| schema-valid | Schema Coverage | Scored | JSON-LD parses; @context and @type present; FAQPage text matches visible content. | A block that fails to parse, or marks up hidden text, is worse than no schema at all. |
| org-entity | Schema Coverage | Informative | name, url, logo and ≥2 sameAs links (bonus for Companies House / LinkedIn / Wikidata). | Entity disambiguation is what AI systems primarily use business schema for. |
| author-dates | Schema Coverage | Informative | Article/BlogPosting carries an author entity and dated datePublished/dateModified. | Dated, attributed passages are cited noticeably more often than anonymous, undated ones. |
| webmcp | Agent Interaction (WebMCP) | Scored | Bounded static scan finds registerTool text with modelContext/WebMCP context, or toolname/tooldescription form markup. | Source evidence can identify an integration to inspect. It does not verify browser support, runtime registration, discovery or successful invocation. |
| webmcp-depth | Agent Interaction (WebMCP) | Informative | Informative count of registerTool text references; never a count of distinct or registered tools. | Loops, library definitions and inactive code make source-reference counts unsuitable for measuring tool coverage. |
| webmcp-declarative | Agent Interaction (WebMCP) | Informative | toolname/tooldescription attributes found on a <form>. | Declarative markup is a WebMCP route in supporting implementations. Source attributes do not establish runtime registration or successful form use. |
| well-known-agent-manifests | Agent Interaction (WebMCP) | Informative | Probes /.well-known/mcp/server-card.json, agent-card.json, api-catalog and /openapi.json. | A machine-readable capability manifest is a low-cost, high-signal declaration for agent tooling. |
| forms-labelled | Agent Interaction (WebMCP) | Informative | ≥90% of inputs have an associated label. | Unlabelled inputs are as opaque to agents as they are to screen readers. |
| button-semantics | Agent Interaction (WebMCP) | Informative | Real <button>/<a href> elements outnumber div[onclick] fakes. | Agents rely on semantic, keyboard-operable controls to act reliably. |
| link-text | Agent Interaction (WebMCP) | Informative | "click here" / "read more" style text is under 20% of links. | Non-descriptive link text gives agents (and assistive tech) nothing to act on. |
| landmarks | Agent Interaction (WebMCP) | Informative | <main> and <nav> elements present. | Landmarks let an agent navigate page structure without guessing from layout. |
| spf | Security posture | Informative | SPF present, ideally with a strict -all. | Without SPF, anyone can send email that appears to come from your domain. |
| dmarc | Security posture | Informative | DMARC present at p=quarantine or stronger. | DMARC turns SPF/DKIM alignment into an enforceable anti-spoofing policy. |
| hsts | Security posture | Informative | Strict-Transport-Security present with a meaningful max-age. | Forces browsers to use https, closing a downgrade-attack window. |
| xcto | Security posture | Informative | nosniff present. | Stops browsers from guessing content types in a way attackers can abuse. |
| server-ver | Security posture | Informative | Server header absent or without a version number. | Version strings hand attackers a head start on known exploits. |
| csp | Security posture | Informative | Present; no unsafe-inline/unsafe-eval in script-src; object-src, base-uri and frame-ancestors set. | The single most effective header against injected-script attacks. |
| referrer-policy | Security posture | Informative | A same-origin or stricter policy is set. | Controls how much of a visitor's browsing context leaks to third-party links. |
| permissions-policy | Security posture | Informative | Present, restricting unused browser features. | Reduces the attack surface exposed to embedded and third-party scripts. |
| security-txt | Security posture | Informative | Valid at /.well-known/security.txt: 200, text/plain, Contact field, unexpired Expires. | Gives researchers a documented way to report vulnerabilities responsibly. |
| dnssec | Security posture | Informative | AD flag set on a DNS-over-HTTPS lookup. | Protects the domain's own DNS answers from being spoofed. |
Calibration: a 29-domain benchmark
Before launch the scoring model was tried against a 29-domain benchmark spanning UK SMEs and agencies, agent-ready platforms, UK publishers and a handful of deliberately minimal sites (example.com, info.cern.ch and similar), then checked from a separate network location. This was an exploratory sample used to inspect the scoring model, not a representative survey of the web or a study of search outcomes.
- 29 domains scored (including the deliberately minimal sites); median overall 59; 20 of 29 sit in the 50–74 "some gaps" band.
- Only one domain in the benchmark reached 90+ overall.
- Agent Interaction (WebMCP) had a median of 0 in this sample. Tool registration is an optional capability; the sample does not establish its effect on search visibility.
- The model was also checked on this site's self-scan and a second production site. Those technical checks are not evidence of improved rankings, citations or enquiries.
What our scanner can see
The scanner fetches public HTML, linked scripts, crawl rules and DNS records. It does not execute page JavaScript or log in. This helps identify content that is available in the initial response, access restrictions and technical problems worth investigating.
A page can look complete in a browser while its initial HTML contains little useful text. But our requests do not reproduce a platform's IP addresses, crawler infrastructure, indexed copy or answer-selection process. Firewalls can respond differently to each. A successful scan therefore does not prove access by every bot or inclusion in an AI answer. The paid visibility audit tests observed answers separately.
The security posture badge
Alongside the four scored groups, every report carries an unscored security posture badge — an A–F letter grade in the style of Mozilla Observatory or securityheaders.com, built from response headers and DNS records rather than from AI-readiness signals.
It checks for a real Content-Security-Policy (and flags unsafe-inline /unsafe-eval in script-src), Referrer-Policy, Permissions-Policy, HSTS, a valid security.txt, DNSSEC, and email-spoofing protection via SPF and DMARC. None of it feeds the overall AI-search-readiness percentage — a site can score 100 on the four groups above and still carry a weak security badge, and vice versa. It's kept separate deliberately: security hygiene and AI-search readiness are both worth measuring, but conflating them into one number would make neither easier to act on.