An AI agent that lands on your site has, until now, had one way in: read the DOM, guess which element is the search box, type into it, guess which button submits, and hope the page didn't re-render underneath it. It's brittle, it's slow, and it breaks every time you ship a redesign.
WebMCP replaces the guessing with a contract. Your page registers a typed menu of its own functions — "here's a search-flights tool, it takes an origin and a date" — and the agent calls them directly with validated arguments, no DOM-scraping. It reached a public origin trial in Chrome 149, announced at Google I/O on May 19, 2026, and it's co-authored by Google and Microsoft under the W3C Web Machine Learning Community Group. Here's how to wire it up — both APIs, the origin-trial switch, and the one line that keeps it from becoming a liability.
The imperative API: register a tool in JavaScript#
When the tool is real logic — mutate state, run a query, hit your backend — you use document.modelContext.registerTool(). A descriptor has four parts: a name, a plain-language description, an inputSchema (standard JSON Schema), and an async execute that does the work and returns MCP-shaped content.
const controller = new AbortController();
await document.modelContext.registerTool({
name: "add-todo",
description: "Add a new item to the user's active todo list",
inputSchema: {
type: "object",
properties: {
text: { type: "string", description: "The text content of the todo item" }
},
required: ["text"]
},
async execute({ text }) {
await addTodoItemToCollection(text);
return {
content: [
{ type: "text", text: `Added todo item: "${text}" successfully.` }
]
};
}
}, { signal: controller.signal });
The signal is your off-switch: call controller.abort() and the tool unregisters, which matters on a single-page app where a tool is only valid on one route.
One trap the blog snippets get wrong: the object is document.modelContext, not navigator.modelContext. The API shipped in early builds on navigator, but navigator.modelContext became a deprecated alias from Chrome 150 in favor of document.modelContext. Feature-detect defensively:
const modelContext = document.modelContext || navigator.modelContext;
if (modelContext) { /* register your tools */ }
The declarative API: no JavaScript at all#
If the "tool" is a form you already ship — search, filter, a lookup — you don't need execute or a build step. Annotate the <form> and let the browser synthesize the tool from it: toolname and tooldescription on the form, toolparamdescription on each input.
<form toolname="search-cars" tooldescription="Perform a car make/model search">
<input type="text" name="make" toolparamdescription="The vehicle's make (i.e., BMW, Ford)" required>
<input type="text" name="model" toolparamdescription="The vehicle's model (i.e., 330i, F-150)" required>
<button type="submit">Search</button>
</form>
By default the browser fills the fields and then waits for the human to review and submit — a built-in human-in-the-loop for free. Add the boolean toolautosubmit attribute only when the agent submitting on its own is genuinely safe. The declarative-vs-imperative split is the first decision to make; the table at the top of this piece is your shortcut.
Turning it on: the origin-trial token#
WebMCP is behind an origin trial, so it isn't live for your visitors until you opt in. Register your origin in the Chrome Origin Trials console, take the token it issues, and drop it in the page head:
<meta http-equiv="origin-trial" content="YOUR_ORIGIN_TRIAL_TOKEN">
An Origin-Trial HTTP response header works too. Once it's on, Chrome DevTools' Application panel lists your registered tools and a Lighthouse audit checks them — and the agent that actually calls them today is Gemini in Chrome. That's the whole surface right now: one browser, one built-in agent, a spec that's still moving.
The one paragraph you can't skip#
A WebMCP tool runs inside the user's live, authenticated session. That's the feature — no OAuth handshake, the agent just inherits the login — and it's also the whole risk.
This is ambient authority: the tool can do whatever the logged-in user can do. And because a language model reads instructions and data as one undifferentiated stream, an attacker can smuggle commands through a poisoned tool description or through data your tool returns — turning your obliging agent into a confused deputy that transfers funds or deletes a record while wearing the user's credentials.
So before you ship: gate every destructive, financial, or identity-changing tool behind a real human confirmation (the declarative default is your friend here). Mark read-only tools with readOnlyHint so the agent can skip needless prompts, label any third-party data your tool returns with untrustedContentHint, and sanitize every tool description the way you'd sanitize untrusted HTML — never interpolate a user-supplied string into it.
WebMCP is the right shape for the agentic web: a page that declares its capabilities beats one an agent has to reverse-engineer. Ship the read-only tools now to get discovered by the agents already crawling — Expedia, Booking.com, Shopify, and Target are already piloting it — and keep the dangerous ones behind a human until the spec, and your threat model, have both settled.



