What is WebMCP, and should your site use it yet?
WebMCP turns a page's forms and functions into named tools that a browser agent can call, instead of guessing at buttons. What it is, where it really works as of October 2026, a form we tested in Chrome, and the rules that keep it safe.
WebMCP is a browser API that lets a web page hand an AI agent a set of named tools, such as "request a studio visit" or "search the catalog", each with a description and typed inputs. The agent calls the tool instead of guessing which button does what. You can add it to an existing HTML form with a few attributes, or register tools in JavaScript. As of 6 October 2026 it is a draft from a W3C Community Group, not a W3C standard, and Chrome runs it as an origin trial. It is the "act" part of an AI-ready website, next to the parts agents read.
What it is, and what it isn't
A browsing agent that is asked to book something today reads the page, often through its accessibility tree or screenshots, and then clicks and types like a person would (how AI agents read websites covers that). WebMCP gives it a shorter path. The page declares its actions as tools on document.modelContext, and the agent calls them with structured input.
Three things it is not:
- Not a W3C standard. The specification is a Draft Community Group Report from the Web Machine Learning Community Group, dated 2 October 2026, edited by Brandon Walderman (Microsoft), Khushal Sagar and Dominic Farolino (Google). Some older articles call it a standard, and some use
navigator.modelContext. The current draft usesdocument.modelContext. - Not an MCP server. The tools run in the visitor's tab, with the visitor's session and cookies. Chrome's documentation says the API "is primarily designed for local browser workflows with a human in the loop".
- Not something that changes your page for people. Browsers without WebMCP ignore the attributes, and the form works exactly as before.
Where it works, as of October 2026
| Where | Status as of 6 October 2026 |
|---|---|
| Chrome | Origin trial, started in Chrome 149 (announced 9 June 2026). Turn it on locally at chrome://flags/#enable-webmcp-testing. |
| Shopify | Live by default "on every Liquid storefront and on the Hydrogen developer preview" since 5 August 2026, with tools such as search_catalog, get_product, update_cart and proceed_to_checkout. Checkout tools (get_checkout, update_checkout, complete_checkout, navigate_to_storefront) followed on 28 September 2026. |
| Cloudflare | A developer preview since 6 August 2026, switched on in the dashboard under Agent Readiness, then WebMCP. It injects a bridge script at the edge with two tool packs, Content Credentials and Site MCP Server. It is not on by default for every site. |
Chrome's documentation doesn't list which agents call these tools today. Its stated aim is an API that "any browser with agentic capabilities can implement".
The smallest correct start: a form
If your site has a booking, quote or contact form, this is the whole change. We ran this exact form in Chrome 154 on 6 October 2026, with WebMCP turned on, and checked what the browser registered:
<form action="/visit" method="post"
toolname="request_studio_visit"
tooldescription="Ask the studio for a visit on a given date. The studio replies by email to confirm.">
<label for="name">Your name</label>
<input id="name" name="name" required>
<label for="email">Email</label>
<input id="email" name="email" type="email" required>
<label for="date">Preferred date</label>
<input id="date" name="date" type="date" required
toolparamdescription="The day you would like to visit, in YYYY-MM-DD.">
<label for="size">Group size</label>
<select id="size" name="size">
<option value="1">Just me</option>
<option value="2-4">2 to 4 people</option>
</select>
<button type="submit">Request a visit</button>
</form>
document.modelContext.getTools() returned a tool named request_studio_visit with this input schema, built by the browser:
{
"type": "object",
"properties": {
"name": { "type": "string", "description": "Your name" },
"email": { "type": "string", "description": "Email" },
"date": {
"type": "string",
"format": "date",
"description": "The day you would like to visit, in YYYY-MM-DD. (Dates MUST be provided in 'YYYY-MM-DD' format.)"
},
"size": {
"type": "string",
"anyOf": [
{ "type": "string", "const": "1", "title": "Just me" },
{ "type": "string", "const": "2-4", "title": "2 to 4 people" }
],
"enum": ["1", "2-4"],
"description": "Group size"
}
},
"required": ["name", "email", "date"]
}
What that output teaches:
- Your labels become the agent's instructions. "Email" is all the agent learned about that field. A label like "Email we reply to" serves people and agents better.
toolparamdescriptionreplaces the label text when the label isn't enough. requiredcarries over, and each<option>becomes an allowed value with its visible text as a title.- Field types are only partly carried. The date field gained
"format": "date", but the email field arrived as a plain string. Your server still has to check it.
What happens when an agent calls it
We called the tool from the page with executeTool and watched the form.
Without toolautosubmit, Chrome filled every field, moved focus to the submit button and matched the form with the :tool-form-active pseudo-class. The tool call then waited. The declarative explainer describes the intent: the agent "should then tell the user to check the form contents, and submit it manually". This is the right default for anything that books time or spends money.
With toolautosubmit, the form submits on its own, and the submit event has agentInvoked set to true. You can answer the agent directly with respondWith, and the value you pass becomes the tool's result:
document.querySelector("form[toolname]").addEventListener("submit", (event) => {
if (!event.agentInvoked) return; // people get the normal submit
event.preventDefault();
event.respondWith(
fetch(event.target.action, { method: "POST", body: new FormData(event.target) })
.then((res) => (res.ok
? { ok: true, message: "Request received. The studio replies by email." }
: { ok: false, message: "The request did not go through. Please try again." }))
);
});
The browser's own validation still runs. When we passed not-an-email with autosubmit on, the call was rejected with "Form validation failed: email: Please include an '@' in the email address." That protects against typos, not against misuse, so the server check stays.
When to reach for registerTool
Use the imperative API for actions that aren't a form: a read-only lookup, a filter on a product list, or a step inside a single-page app.
if ("modelContext" in document) {
const registration = new AbortController();
document.modelContext.registerTool(
{
name: "get_opening_hours",
description: "Return the studio's opening hours for the next seven days.",
inputSchema: { type: "object", properties: {} },
annotations: { readOnlyHint: true },
async execute() {
const res = await fetch("/api/hours");
return await res.json();
},
},
{ signal: registration.signal }
);
// Later, when the tool no longer applies: registration.abort();
}
The if keeps every other browser on the plain page. Aborting the signal unregisters the tool. The specification limits names to 128 characters of letters, digits, underscores, hyphens and periods. Chrome's guidance is stricter: 30 characters for names, 500 for tool descriptions, 150 for parameter descriptions and about 1,500 characters per tool result.
The safety rules
Chrome's security guidance is blunt: "it's impossible to guarantee safety inside of a large language model." Plan for an agent that has been misled by something it read elsewhere.
- Mark what each tool does.
readOnlyHintfor tools that only read.consequentialHintfor "high-stakes or non-reversible actions".untrustedContentHintwhen the tool returns reviews, comments or other content you didn't write. - Keep
toolautosubmitoff for anything that spends money or books time. Shopify's checkout tools follow the same idea. Its documentation tells agents: "Before you callcomplete_checkout, show the buyer the current order and total, and get their permission to place it." The tools also hand control back to the buyer when a step needs them, such as a 3D Secure check. - Validate on the server, exactly as for a person. An agent's submission arrives as an ordinary form post. Rate limits, spam checks and stock checks still apply.
- Mind iframes. WebMCP sits behind a Permissions Policy named
tools, allowed for the page's own origin by default. A cross-origin iframe gets it only if you delegate it. - Name tools for what they really do. Chrome's best practices separate doing from starting:
create-eventcreates the event, whilestart-event-creation-processonly opens the flow.
How to test it
- Turn on
chrome://flags/#enable-webmcp-testingand open your page. Chrome's Model Context Tool Inspector extension lists the registered tools and lets you call them by hand. - For a live site, register for the origin trial on Chrome's origin trials page and add the token to your pages.
- Run Lighthouse's experimental Agentic Browsing category. It needs Chrome 150 or later, and its WebMCP audits need origin trial registration. It also checks names and roles in the accessibility tree, layout shifts and whether an llms.txt exists (what is llms.txt).
- In an automated test, launch Chrome with the WebMCP feature enabled and read
await document.modelContext.getTools(). Our run used--enable-features=WebMCPTestingin Chrome 154.
Should you add it yet?
Add the declarative attributes now if your site has a few forms that matter, such as booking, quotes, contact or sign-up. The change is small, browsers without support ignore it, and good labels help screen reader users too. Wait on anything elaborate. The draft still marks the algorithm that turns a form into a schema as "TODO", and Chrome revised its WebMCP security, imperative and declarative pages in September 2026 alone. Check the status again before you build on it.
Agents decide what a site can do before they visit any one page. The A2A protocol's Agent Card, published at /.well-known/agent-card.json, is one way to list a site's skills. If you publish one, give its skills the same names as your tools. The free AI-ready check looks for that file, along with robots.txt, llms.txt and structured data. A tool is only as good as what happens after the submission, so connect the form to a real backend where every request, from a person or an agent, lands in the same place.
Sources
Checked 6 October 2026. Standards and vendor pages change; the linked pages are the authority.
- W3C Web Machine Learning Community Group: WebMCP, Draft Community Group Report (2 October 2026)
- WebMCP declarative API explainer (GitHub)
- Chrome for Developers: WebMCP overview (updated 1 October 2026)
- Chrome for Developers: WebMCP declarative API (updated 25 September 2026)
- Chrome for Developers: WebMCP imperative API (updated 21 September 2026)
- Chrome for Developers: WebMCP tool security (updated 1 September 2026)
- Chrome for Developers: WebMCP best practices (updated 18 May 2026)
- Chrome blog: WebMCP origin trial (Alexandra Klepper, 9 June 2026)
- Chrome for Developers: Lighthouse Agentic Browsing (updated 5 May 2026)
- Shopify changelog: WebMCP support for Liquid and Hydrogen storefronts (5 August 2026)
- Shopify changelog: WebMCP support for checkout (28 September 2026)
- Shopify docs: Checkout WebMCP
- Cloudflare: give any website a WebMCP interface (Will Rowe, 6 August 2026)
- A2A protocol specification: Agent Card
