Most WebMCP Chrome tutorials still on page one are already out of date. They tell you to install Canary 146, flip a flag and call navigator.modelContext.provideContext(). Since then, the spec dropped provideContext() in March 2026, moved the whole API to document.modelContext in May, and took the declarative form API out of the spec in October. Meanwhile Chrome opened a public origin trial. Copy an old snippet today and you get undefined. This guide follows the current spec and Chrome’s own docs, and flags what is still settling.
Where WebMCP Stands in Chrome Right Now
WebMCP lets a page register “tools” (named functions with a description and a JSON Schema for their inputs) that an in-browser AI agent can call directly instead of guessing which button does what. For the concept, start with what WebMCP is. It is also a different thing from server-side MCP, which we cover in WebMCP vs MCP.
Status as of November 2026, checked against primary sources:
- Spec: a Draft Community Group Report from the W3C Web Machine Learning Community Group, last updated 2 November 2026. Its own status section says it is “not a W3C Standard nor is it on the W3C Standards Track.” The editors come from Google and Microsoft.
- Chrome: Chrome Status lists a developer trial from Chrome 146 and a WebMCP Chrome origin trial that started in Chrome 149. The trial was originally set to end at Chrome 156 and has been extended to Chrome 162, with an end date of 30 March 2027.
- Edge: the spec repo’s implementation-status page lists an origin trial in Edge 150.
- Firefox and Safari: both have open standards-position issues and no shipped implementation.
- Gemini in Chrome: at Google I/O 2026 Chrome said it “will soon support WebMCP APIs.” We found no confirmed launch, so don’t assume Gemini calls your tools today.
What Outdated WebMCP Tutorials Get Wrong
The spec’s commit history explains why early guides break. Check any pre-mid-2026 code against this list:
navigator.modelContextis gone from the spec. The getter moved toDocumentin May 2026. Both the spec and Chrome’s docs now usedocument.modelContext.provideContext()andclearContext()were removed in March 2026. You register tools one at a time withregisterTool().- Unregistering uses an
AbortSignal, not anunregisterTool()call. - Safety metadata now lives in an
annotationsobject:readOnlyHint,untrustedContentHint,consequentialHintand (from Chrome 156)debugging. - The declarative form API was removed from the spec “for now” in October 2026. Chrome still documents it and ships it in the trial, but treat it as the more experimental of the two paths.
- Event handlers moved:
window.ontoolactivatedstops working in Chrome 156; listen ondocument.modelContextinstead.
Plan Your Tools Before You Write Code
The likeliest mistake is treating WebMCP like schema markup: wrap every form and call it done. Chrome’s best-practices guide warns that every tool uses part of the agent’s context window, and overlapping tools make the agent pick wrongly. Start with the three to five tasks that make you money or save your support team time. For most sites those are site search, product filtering, a quote or booking form, order status and a support request.
Rules from Chrome’s guidance that early tutorials skip:
- One function per tool. Make the name say exactly what happens. Chrome’s example is
create-event(creates the event now) versusstart-event-creation-process(sends the user to a form). - Accept raw input. Let the tool take “11:00 to 15:00” as a string, and don’t make the model do arithmetic. Use readable values like
shipping="Express", notshipping_id=1. - Stay within the character budgets. Chrome’s security guidance suggests about 500 characters per tool description, 150 per parameter description, 30 per tool or parameter name, and 1.5K per tool output.
- Register all or nothing. A page should expose its complete tool set or none of it, never half a workflow.
On a large site, map it first. SEO Rocket builds a site’s structure from its XML sitemaps, so you can see which sections hold search, listing and form pages. Its real-crawler technical audit renders JavaScript, so it shows whether those forms actually exist in the rendered page.
Step 1: Turn On WebMCP in Chrome
There are two switches: one for you, one for your visitors.
For local development, open the WebMCP Chrome flag at chrome://flags/#enable-webmcp-testing, set it to Enabled and relaunch. This affects only your own browser.
For real visitors, register your origin for the WebMCP origin trial in Chrome’s origin-trials console. You get a token, which you add to every page that registers tools, either as a meta tag in the head or as an Origin-Trial response header:
<meta http-equiv="origin-trial" content="YOUR_TOKEN">
Chrome Status shows the trial allows third-party origins, which matters if you are a widget or booking vendor whose script runs on client sites. Per Chrome’s origin-trial docs, a third-party token must be injected from an external JavaScript file, not a meta tag.
Two more requirements. The spec marks modelContext as [SecureContext], so it only exists on HTTPS pages. And both APIs are gated by the tools Permissions Policy, which defaults to self, so a cross-origin iframe needs allow="tools" before it can register anything.
Step 2: The Declarative Route (Annotate an Existing Form)
If the task already lives in an HTML form, the declarative API is the quickest path. You add toolname and tooldescription to the <form>, and Chrome turns its fields into a JSON Schema. For each field’s description it uses toolparamdescription if present, then the associated <label>, then aria-description.
<form toolname="request_quote"
tooldescription="Requests a flooring installation quote for a given area and material."
action="/quote">
<label for="area">Floor area in square metres</label>
<input id="area" name="area" type="number" required>
<select name="material" toolparamdescription="Flooring material the customer wants installed.">
<option value="vinyl">Vinyl</option>
<option value="oak">Engineered oak</option>
</select>
<button type="submit">Get quote</button>
</form>
When an agent calls the tool, Chrome focuses the form and fills it in, and the user can see it happen. By default the user still clicks Submit. Adding toolautosubmit lets the agent’s call submit the form. In your submit handler, event.agentInvoked is true for agent submissions, and event.respondWith(promise), called after preventDefault(), sends a result back to the model. Chrome also applies the :tool-form-active and :tool-submit-active CSS pseudo-classes, so you can style the moment an agent takes over.
Step 3: The Imperative Route (Register Tools in JavaScript)
Use the imperative API for anything that isn’t a single form: filtering a listing, reading cart state, or a multi-step configurator. Always feature-detect, because unsupported browsers have no modelContext at all:
if ('modelContext' in document) {
const controller = new AbortController();
await document.modelContext.registerTool({
name: 'filter_products',
description: 'Filters the product list by category and maximum price.',
inputSchema: {
type: 'object',
properties: {
category: { type: 'string', enum: ['vinyl', 'oak', 'laminate'] },
maxPrice: { type: 'number', description: 'Maximum price per square metre' }
},
required: ['category']
},
annotations: { readOnlyHint: true },
execute: async ({ category, maxPrice }, { signal }) => {
const count = await applyFilters(category, maxPrice, signal);
return `Showing ${count} ${category} products.`;
}
}, { signal: controller.signal });
// controller.abort() unregisters the tool, e.g. when the view unmounts
}
Note the second argument to execute. It carries an AbortSignal, so pass it to any fetch() to cancel work when the user or agent cancels. Chrome’s guidance also says to resolve only once the UI matches the new state. An agent that gets “success” before the page updates will plan its next step against stale data. Chrome lists experimental React, Angular and Vue integrations, and the webmcp-types npm package provides TypeScript typings.
Declarative vs Imperative WebMCP: Which to Use
The real choice is not about style. It depends on where the logic already lives and how much spec risk you will accept:
- Choose declarative when the task is one existing form, such as contact, quote, newsletter or support. You only add attributes, no JavaScript is required, and if WebMCP disappears tomorrow your form still works. The trade-off is that it is no longer in the spec, so its shape is the most likely to change.
- Choose imperative when the task spans state, such as filters, carts, configurators or anything behind client-side routing. It is the path the spec actually defines today, and the GitHub explainer says any future declarative API would complement it, not replace it.
- Mix them on most real sites: declarative for standalone forms, imperative for app-like flows. Either way, follow Chrome’s best-practices advice to share one application service for validation, permissions and side effects, so the UI, the tools and your tests all enforce the same rules.
Security: The Part You Cannot Skip
Chrome’s tool-security guidance is blunt: you cannot guarantee safety inside an LLM, and indirect prompt injection is real. Your defences live in your code; annotations help the agent decide when to ask the user:
consequentialHint: trueon anything irreversible, such as bookings, payments or deletions, so the browser or agent can ask the user to confirm.untrustedContentHint: trueon tools that return reviews, comments or other user-generated or external data.readOnlyHint: trueon lookups, so agents don’t ask for confirmation they don’t need.exposedToonly for origins you would share that data with directly. Tools are invisible to other origins by default, so keep it that way unless you have a reason.
Two further points from Chrome’s docs. Browser extensions can query and run WebMCP tools through content scripts, so a tool is not private just because no AI agent is visible. And “validate strictly in code, loosely in schema”: schema constraints are not guaranteed to be respected, so your execute function must reject bad input and return an error message the model can use to correct itself.
Test Your Tools Before Agents Use Them
You don’t need to wait for a mainstream agent. Chrome offers three ways to test:
- Chrome DevTools can debug WebMCP tools and show how the browser parsed your JSON Schema. That is where a declarative form with the wrong parameter names shows up.
- Model Context Tool Inspector (Chrome Web Store) lets you prompt an agent against your page and check that it picks the right tool. It needs a Gemini API key.
- Example Agentic Chrome Extension (GoogleChromeLabs on GitHub) runs tools from natural-language prompts via a local Node server with OpenAI, Google or Anthropic keys, or an on-device model via
chrome://flags/#prompt-api-tool-use.
From the console, await document.modelContext.getTools() lists everything the page has registered. Then write a few evals, realistic user requests paired with the tool and arguments you expect, and re-run them whenever you change a description.
What WebMCP Does (and Doesn’t) Do for SEO
Expect “WebMCP for rankings” claims. Neither the spec nor Chrome’s documentation links WebMCP to search rankings. Chrome’s own limitations section says agents “must visit a site directly to know if it has callable tools”, and there is no registry or sitemap for tools. So the pages that carry your tools still need to be found the usual way: crawlable, indexed and cited in AI answers. WebMCP improves what happens after an agent arrives, not whether it arrives, so the groundwork in our agentic search guide and llms.txt explainer still comes first.
What you can measure is the conversion side. In your submit handler, send an analytics event whenever event.agentInvoked is true, so agent-completed quotes or bookings show up as their own segment in GA4. SEO Rocket connects to GA4 and Search Console alongside its AI-visibility tracking. You can see whether AI answers cite you and whether agents that land on your site complete tasks, in one chat, using the same playbook proven across 1,000,000+ ranking pages.
WebMCP Chrome FAQ
Is WebMCP enabled by default in Chrome?
No. It needs the enable-webmcp-testing flag locally, or an origin-trial token on your pages for real visitors. The trial currently runs through Chrome 162.
Should I use navigator.modelContext or document.modelContext?
Use document.modelContext. The spec moved the API there in May 2026, and Chrome’s current docs use it throughout. Code that calls navigator.modelContext follows the old API.
Does WebMCP work without JavaScript?
The declarative form attributes need no script, though Chrome’s trial implements them while the spec has set them aside for now. Imperative tools require JavaScript.
Will adding WebMCP hurt my site in other browsers?
No, as long as you feature-detect. Unknown form attributes are ignored, and a guarded registerTool() call never runs where the API doesn’t exist, so it is a safe progressive enhancement.