Report for
developer.mozilla.org
https://developer.mozilla.org/en-US/visit site ↗
- Find
friction
- Understand
clear
- Act
friction
- Survival
- 69
- Can an agent read and act at all?
- Superpower
- 0
- WebMCP tools exposed
- If WebMCP added
- 73
- Headline with WebMCP at full marks
Do this first
ranked by severity × category weight
- Machine-readable structurehigh
No structured data (JSON-LD)
Add a JSON-LD block describing the page's primary entity.
Show the fix
One script tag turns guesswork into facts. Start with WebSite/Organization, then the page type (Product, Article, FAQPage…).
Reference ↗<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "WebSite", "name": "developer.mozilla.org", "url": "https://developer.mozilla.org/", "potentialAction": { "@type": "SearchAction", "target": "https://developer.mozilla.org/search?q={query}", "query-input": "required name=query" } } </script> - Form semanticshigh
Unlabelled form controls
Associate every control with a <label> or aria-label.
Show the fix
Labels are the primary signal for what a field wants.
<label for="field">field</label> <input id="field" name="field" type="checkbox">
- Form semanticshigh
Controls outside a <form>
Wrap controls in a <form> with an explicit submit control.
Show the fix
Agents submit forms via standard HTML — not div onclick handlers.
<form action="/submit" method="post"> …fields… <button type="submit">Submit</button> </form>
Category breakdown
- 60
Agent discovery
3 of 5 discovery signals present.
weight 18% · confidence high
- 50
Machine-readable structure
Agents must infer what this page is from prose alone.
weight 18% · confidence high
- 100
Access & renderability
Agents can read this page without a browser.
weight 18% · confidence high
- 35
Form semantics
Fields are unlabeled; an agent cannot tell what they want.
weight 16% · confidence high
- 100
Actionability
Actions are real links, buttons and forms.
weight 15% · confidence medium
- 0
WebMCP capabilitysuperpower
No WebMCP tools — the single biggest upgrade available here.
weight 15% · confidence medium
Find
frictionCan an agent locate this page and its entry points?
Agent discovery
60/1003 of 5 discovery signals present.
lowNo llms.txtAn optional Markdown file that tells LLM-based agents what the site is and where the important pages are. Cheap to add; adoption by agents is still emerging.▶
Evidence
- llms.txt · https://developer.mozilla.org/llms.txt not found
Fix
Add /llms.txt (Markdown).
Five minutes of work; some agents and Lighthouse's agentic audit already look for it.
# developer.mozilla.org > One-paragraph description of what this site is for and who it serves. ## Key pages - [Home](https://developer.mozilla.org/): what visitors can do here - [Docs](https://developer.mozilla.org/docs): how to use the product
lowNo MCP discovery filesNothing under /.well-known tells an agent whether this site exposes an MCP server. Only relevant if you run one — but if you do, this is how agents find it.▶
Evidence
- well-known · https://developer.mozilla.org/.well-known/oauth-protected-resource, mcp.json, mcp/server-card.json not found
Fix
If you host an MCP server, publish /.well-known/oauth-protected-resource.
Required by the MCP authorization spec; clients use it to locate your authorization server.
{
"resource": "https://developer.mozilla.org/mcp",
"authorization_servers": ["https://auth.developer.mozilla.org"],
"scopes_supported": ["read"],
"bearer_methods_supported": ["header"]
}3 things already working
- ✓robots.txt present and permits agents — Crawlers and user agents are allowed to read this page.
- ✓Sitemap available — sitemap.xml is present and well-formed.
- ✓Feed advertised — An RSS/Atom feed is declared, giving agents a structured view of new content.
Understand
clearCan it tell what the page is without guessing?
Machine-readable structure
50/100Agents must infer what this page is from prose alone.
highNo structured data (JSON-LD)Without schema.org markup an agent must infer what this page is — a product, an article, an organisation — from prose. That inference is where agents make mistakes.▶
Evidence
- raw-html · No script[type=application/ld+json] found
Fix
Add a JSON-LD block describing the page's primary entity.
One script tag turns guesswork into facts. Start with WebSite/Organization, then the page type (Product, Article, FAQPage…).
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "developer.mozilla.org",
"url": "https://developer.mozilla.org/",
"potentialAction": {
"@type": "SearchAction",
"target": "https://developer.mozilla.org/search?q={query}",
"query-input": "required name=query"
}
}
</script>lowNo OpenGraph metadataSocial metadata is a minor signal for agents, but many crawlers read og:* as a fallback summary.▶
Evidence
- raw-html · No meta[property^=og:]
Fix
Add og:title, og:description and og:image.
Low effort; improves link previews and gives agents a second summary source.
<meta property="og:title" content="MDN Web Docs"> <meta property="og:description" content="…"> <meta property="og:image" content="https://developer.mozilla.org/og.png">
mediumNo <main> landmarkLandmarks tell an agent where the content is and what is chrome. Found: nav, header/footer.▶
Evidence
- raw-html · No <main> or [role=main]
Fix
Wrap the primary content in <main>; use <nav>, <header>, <footer>.
Semantic landmarks are free structure — screen readers and agents both use them to skip chrome.
<header>…site header…</header> <nav aria-label="Primary">…</nav> <main> …the content agents should read… </main> <footer>…</footer>
1 thing already working
- ✓Clean heading outline — One h1, 13 headings, no skipped levels.
Access & renderability
100/100Agents can read this page without a browser.
3 things already working
- ✓Response headers allow agent access — No noindex/noai directives or bot-management headers detected.
- ✓No CAPTCHA markup detected — No reCAPTCHA, hCaptcha, or Turnstile widgets found in the raw HTML.
- ✓Content is readable without JavaScript — Primary content appears in the raw HTML; no JS-dependence heuristics fired.
Act
frictionCan it complete the task — book, buy, submit?
Form semantics
35/100Fields are unlabeled; an agent cannot tell what they want.
highUnlabelled form controls1 control has no accessible name — an agent cannot tell what to enter.▶
Evidence
- raw-html · label > input @ label > input
Fix
Associate every control with a <label> or aria-label.
Labels are the primary signal for what a field wants.
<label for="field">field</label> <input id="field" name="field" type="checkbox">
mediumControls missing a name attribute1 control lacks name — without a name the value cannot be submitted or described in a tool schema.▶
Evidence
- raw-html · label > input @ label > input
Fix
Add a name attribute to every control.
Agents need stable field keys for submission and tool schemas.
<label for="field">field</label> <input id="field" name="field" type="checkbox">
highControls outside a <form>inputs outside a <form> cannot be submitted by an agent without executing scripts▶
Evidence
- raw-html · label > input @ label > input
Fix
Wrap controls in a <form> with an explicit submit control.
Agents submit forms via standard HTML — not div onclick handlers.
<form action="/submit" method="post"> …fields… <button type="submit">Submit</button> </form>
mediumMissing submit affordance1 control is not inside a form with a submit button — an agent cannot send the values.▶
Evidence
- raw-html · label > input @ label > input
Fix
Add a submit button inside the owning form.
Agents need a standard submit control to complete form actions.
<form action="/submit" method="post"> <label for="field">field</label> <input id="field" name="field" type="checkbox"> <button type="submit">Submit</button> </form>
Actionability
100/100Actions are real links, buttons and forms.
2 things already working
- ✓Primary action 'Getting started modules' is a real <a> — The page's primary action is directly invokable from its raw HTML.
- ✓All actions use native HTML — All 189 actions are real links, buttons or forms. Script bundles may still attach invisible event listeners that raw HTML cannot show.
WebMCP capability
0/100No WebMCP tools — the single biggest upgrade available here.
highNo WebMCP tools — this is the biggest single upgrade availableWebMCP lets a page hand an agent a named, typed tool instead of a form it has to reverse-engineer. Browsers in the Chrome/Edge origin trial and agent clients such as ChatGPT Desktop already call these tools. The "+N" on this report is what declaring one is worth to your score. Note that we only read the served HTML: a tool registered from a JavaScript bundle would be invisible to us.▶
Evidence
- raw-html · No form on this page — the snippet below is a site-search starting point
Fix
Declare a site-search tool
The declarative attributes are the cheapest path: the browser synthesizes the JSON Schema from the controls you already have.
<form action="/search" method="get" toolname="search_site" tooldescription="Search https://developer.mozilla.org"> <input name="q" type="search" toolparamdescription="Search query" required> <button type="submit">Search</button> </form>
infoSame tool, imperative APIIf the form is rendered by JavaScript or the tool needs to do more than submit, register it imperatively. execute() resolves to a plain JSON-serializable value; the browser stringifies it.▶
Evidence
- raw-html · No form on this page — the snippet below is a site-search starting point
Fix
Register the tool with document.modelContext.registerTool.
WebMCP is not on by default in any shipping browser yet, so include the polyfill: <script src="https://unpkg.com/@mcp-b/webmcp-polyfill@5.1.0/dist/index.iife.js" integrity="sha384-ZLqD1afbu2b2LJVDDqBf95wR/DGWh5FT1bx6E2S+4uMPdMOc8QGIIfw2gBWLKIB2" crossorigin="anonymous"></script>
// Until Chrome ships WebMCP by default, include the polyfill:
// <script src="https://unpkg.com/@mcp-b/webmcp-polyfill@5.1.0/dist/index.iife.js" integrity="sha384-ZLqD1afbu2b2LJVDDqBf95wR/DGWh5FT1bx6E2S+4uMPdMOc8QGIIfw2gBWLKIB2" crossorigin="anonymous"><\/script>
document.modelContext.registerTool({
name: "search_site",
description: "Search https://developer.mozilla.org",
inputSchema: {
"type": "object",
"properties": {
"q": {
"type": "string",
"description": "Search query"
}
},
"required": [
"q"
]
},
async execute({ q }, { signal }) {
const res = await fetch("/api/search?q=" + encodeURIComponent(q), { signal });
return await res.json(); // plain JSON-serializable value — not an MCP { content } envelope
},
annotations: { readOnlyHint: true },
});Fetched Wed, 14 Oct 2026 19:25:09 GMT in 0.7s · HTTP 200 · 9 discovery files checked · rendered DOM: skipped
Rendered-DOM checks are not run in v1; JavaScript dependence is estimated from the raw HTML.