DocsCapabilitiesWebMCP
WebMCP
In-page tools a browsing agent can call directly.
Why an agent cares
It lets a page hand an agent named tools instead of making it drive the UI, which is the difference between a reliable action and a screen-scrape. Tools register in JavaScript, so this is captured from the live page rather than parsed out of the HTML.
Adoption
Early pilots. Named early adopters exist, behind flags or trials. Nothing has been independently measured yet. For this one in particular, browsers are trialling it, but almost no publisher has shipped it.
Direction of travel: ▲ rising, as at .
Chrome origin trial in 149 to 156 and an Edge flag, but Spronta's Jul 2026 survey put publisher deployment at close to zero outside demonstrations.
| Adopter | Depth | Evidence |
|---|---|---|
| Google Chrome (origin trial 149-156) | preview | developer.chrome.com |
| Microsoft Edge (flag, 147+) | preview | spronta.com |
| Angular (declareWebMcpTool) | preview | angular.dev |
| Expedia, Booking.com, Shopify | announced | spronta.com |
What we check
webMcpPresent is true, so a site that has not adopted this is not assessed on it and appears in no report. 7 of these 8 can fail it. In a Lumar crawl these land on the page's own row.| Check | Severity | Raises | On whose authority |
|---|---|---|---|
webMcpToolMissingName | high | usability | Lumar readiness profile |
webMcpInvalidToolName | high | usability | Lumar readiness profile |
webMcpToolMissingDescription | high | usability | Chrome profile |
webMcpImperativeMissingDescription | high | conformance, usability | specification (W3C WebMCP draft, 2026-07-28) |
webMcpImperativeMissingExecute | high | conformance, usability | specification (W3C WebMCP draft, 2026-07-28) |
webMcpDuplicateToolName | high | usability | Lumar readiness profile |
webMcpParamMissingDescription | medium | usability | Chrome profile |
webMcpImperativeMissingInputSchema | informational | nothing | specification (W3C WebMCP draft, 2026-07-28) |
Examples
Both of these are fixtures the test suite runs through the real collector, not snippets written for a document: the first is a shape we score as valid, the second is one we flag.
<!-- webMcpPresent + correct: declarative WebMCP form with tool metadata on the form
and a per-parameter description on the input. -->
<form
toolname="subscribe_newsletter"
tooldescription="Subscribe an email address to the newsletter."
action="/api/subscribe"
method="post"
>
<label>
Email
<input name="email" type="email" toolparamdescription="Subscriber email address" required />
</label>
<button type="submit">Subscribe</button>
</form>
<!-- webMcpPresent + correct: imperative registration with a complete inputSchema, on the
current-draft home (document.modelContext, W3C draft 28 Jul 2026) and registered from a
getTools() continuation — a crawler whose emulation misses any current-draft member
(registerTool, getTools) visibly fails to capture the tool. The legacy navigator home is
covered by issues.html. -->
<script>
if (document.modelContext) {
(async () => {
await document.modelContext.getTools();
document.modelContext.registerTool({
name: "get_order_status",
description: "Look up the status of an order by its ID.",
inputSchema: {
type: "object",
properties: { orderId: { type: "string", description: "Order identifier" } },
required: ["orderId"],
},
async execute({ orderId }) {
return { status: "shipped", orderId };
},
});
})();
}
</script><!-- webMcpPresent: yes (a WebMCP form exists).
webMcpToolMissingDescription: the form has a toolname but no tooldescription (required).
webMcpParamMissingDescription: the "email" parameter has no toolparamdescription, no
associated <label>, and no aria-description, so an agent has nothing to describe it. -->
<form toolname="subscribe_newsletter" action="/api/subscribe" method="post">
<input name="email" type="email" required />
<button type="submit">Subscribe</button>
</form>
<!-- webMcpImperativeMissingDescription: the registerTool call omits its (required) description.
webMcpImperativeMissingInputSchema (informational only): it also omits inputSchema — allowed
for a parameterless tool, so it does not fail validity. It does provide execute.
Registered via the legacy navigator.modelContext home (pre-rename origin trials) —
deliberate: the shim must keep catching legacy-home pages (correct.html covers the
current-draft document.modelContext home). -->
<script>
if (navigator.modelContext) {
navigator.modelContext.registerTool({
name: "get_order_status",
async execute(args) {
return { status: "unknown" };
},
});
}
</script>Specifications
| Document | Revision | Kind |
|---|---|---|
| W3C WebMCP draft (Web Machine Learning CG) | 2026-07-28 | specification |
| Chrome docs — WebMCP | living | vendor profile |
| Chrome docs — declarative API (form annotations) | living | vendor profile |
| Chrome docs — imperative API (registerTool) | living | vendor profile |
Last re-read against the published documents: .