WebMCP Lets a Page Hand Agents Its Tools — If the Page Holds a Trial Token
This site is a few dozen small tools — a UUID generator, a Base64 encoder, a JWT decoder, a cron expression builder. When a browser agent uses one of them today, it does what a very patient intern would: reads the DOM or a screenshot, finds the version dropdown, types into the count field, clicks the button and scrapes the output. WebMCP promises to replace all of that with the page simply saying "here is a tool called generate-uuid-v4, this is its input schema, call it".
Before touching a single template I read the spec, Chrome's documentation and the early adopters' write-ups. The most useful thing I found was not the API. It was a site whose eight WebMCP tools registered nothing, for every visitor, for three months, while every test passed. That story is most of what you need to know about shipping WebMCP in 2026.
WebMCP turns a page's features into tools an agent calls directly
WebMCP is a browser API that lets a web page register named tools, each with a description, a JSON Schema for its input and a function that runs it, so an agent in the browser can call them instead of operating the UI. The idea is the same one MCP applies to servers — described tools with typed inputs — with one decisive difference: the tool runs inside the page, in the user's own session, with no server to deploy and no separate authentication.
It is not a standard yet. The specification is a Draft Community Group Report from the W3C Web Machine Learning Community Group, dated 10 September 2026, and implementation is uneven:
| Engine | Status in September 2026 |
|---|---|
| Chrome | Origin trial from Chrome 149 through 156, ending 16 November 2026; local testing via chrome://flags/#enable-webmcp-testing |
| Edge | Origin trial from Edge 150 |
| Firefox | Not implemented; Mozilla's standards position is under review |
| Safari | Not implemented; under consideration in WebKit's standards-positions process |
| ChatGPT Desktop | Supported, per the spec repository's implementation status |
An origin trial means the API exists only on pages that serve a valid trial token. For every other visitor on stable Chrome, it isn't there.
The imperative API: one registerTool call per tool
A page registers tools with document.modelContext.registerTool(), one call per tool. The getter has lived on document since the 27 May 2026 draft, and that timing matters for the trial: Chrome 149, the release the trial opened with, exposes only the old navigator.modelContext, Chrome 150 added document.modelContext and kept the old getter as a deprecated alias, and Chrome 153 Dev has already removed it. Until the trial ends, read both. Here is roughly what exposing the UUID v4 generator would look like, self-contained and read-only:
// Chrome 149 has only navigator.modelContext; Chrome 150+ moved it to document
const modelContext = document.modelContext ?? navigator.modelContext;
if (modelContext) {
// registerTool() returns a promise that rejects on a duplicate name
modelContext.registerTool({
name: 'generate-uuid-v4',
title: 'Generate UUID v4',
description: 'Generate random UUID v4 values in the browser. Nothing is sent to a server.',
inputSchema: {
type: 'object',
properties: {
count: { type: 'integer', minimum: 1, maximum: 100, description: 'How many UUIDs to generate' },
},
},
annotations: { readOnlyHint: true }, // tells the agent this tool changes nothing
async execute({ count = 1 }) {
const uuids = Array.from({ length: count }, () => crypto.randomUUID());
return { content: [{ type: 'text', text: uuids.join('\n') }] };
},
}).catch(console.error);
}
The constraints are small but strict. A tool name is 1 to 128 characters of letters, digits, _, - and ., and registering a duplicate name rejects the promise. Access is gated by a tools Permissions Policy whose default allowlist is 'self', so a third-party iframe cannot register tools on your page unless you delegate the permission, and Chrome's documentation adds that WebMCP "is only available in origin-isolated documents".
Treat that code as a snapshot. ModelPiper, the site from the introduction, documented the ground moving under them during the trial: the getter moved from navigator to document, a bulk provideContext({ tools }) gave way to one async registerTool() per tool, and reading the registry became an async getTools(). Check the Chrome documentation on the day you ship, not the blog post you bookmarked.
The declarative API: a form is already a tool
For anything that is already an HTML form, WebMCP needs no JavaScript at all — four attributes turn the form into a tool definition the browser synthesises itself:
<form action="/convert" method="get"
toolname="convert-unix-timestamp"
tooldescription="Convert a Unix timestamp in seconds to an ISO 8601 date in UTC">
<input type="number" name="ts" required
toolparamdescription="Unix timestamp in seconds, for example 1767225600">
<button type="submit">Convert</button>
</form>
toolname and tooldescription map to the imperative name and description, and removing either one unregisters the tool. toolparamdescription on each control becomes the property description in the generated input schema. The fourth, toolautosubmit, lets the agent submit without the user pressing the button — which is exactly why it is missing from the example above. Without it, the agent fills the form and the human confirms.
The declarative explainer also defines how the agent gets a result back. The page can intercept submission and answer the agent without navigating, through SubmitEvent#respondWith(). And when the submission does navigate, "the first <script type=application/ld+json> tag on the target page is used as the cross-document tool's response" — so the JSON-LD structured data you already emit for search engines doubles as the tool's return value. The proposal also adds :tool-form-active and :tool-submit-active pseudo-classes, so you can show users visibly that an agent is working the form.
Eight tools that registered nothing for three months
ModelPiper shipped eight WebMCP tools in late April 2026. Without an origin trial token, document.modelContext was simply undefined for ordinary Chrome visitors, so every registration was a silent no-op: "Zero tools, on every page load, for every visitor, for three months." They noticed only after enrolling in the trial on 1 August.
Both of their test suites passed the whole time. The unit tests defined document.modelContext on a fake object and asserted the right methods were called. The other suite asserted the source contained the string document.modelContext. Their verdict applies to any API you only ever reach through a stub: "A test that checks whether your code mentions an API, rather than what that API does when called, will pass a rename, a move, and a property that was never real."
The fixes they adopted translate directly to any site:
- Log the registration outcome. Count the tools
getTools()returns after page load and send that number to your analytics. Zero is a bug report. - Test against a real browser with
chrome://flags/#enable-webmcp-testingenabled, not a stub. - Put the trial expiry in monitoring. ModelPiper's check "goes red 30 days before expiry with the renewal steps printed". This trial ends on 16 November 2026, and when a token lapses the failure is the same silence as never having one.
Every tool description is a prompt
A WebMCP tool runs with the full authority of the logged-in user, and its description and output go straight into the model's context. The specification lists the risks itself: prompt injection, misrepresentation of intent, privacy leakage and same-origin boundary violations. This is the trust boundary I worried about with prefilled AI prompt links, turned around — there, a link typed instructions into an assistant; here, your page hands the assistant text and actions.
The spec gives you three annotations to state intent, and I would set them from the first tool:
| Annotation | What it signals | When I would set it |
|---|---|---|
readOnlyHint |
Calling the tool changes nothing | Generators, converters, decoders — every tool on this site |
untrustedContentHint |
The output may contain content the site did not author | Anything returning comments, reviews, user profiles or fetched third-party data |
consequentialHint |
The action has real-world consequences | Purchases, messages, deletions, account changes |
My rules would be short. Start with read-only tools. Never add toolautosubmit to a form that changes state. Mark any output that includes user-generated content as untrusted, because a comment that says "ignore previous instructions" is now one tool call away from the model. And keep tool descriptions factual — a description that oversells what a tool does is a misrepresentation of intent the agent has no way to detect.
Where WebMCP fits next to llms.txt and server MCP
The three mechanisms answer different questions, and a site can use all of them without overlap:
| llms.txt | Server-side MCP | WebMCP | |
|---|---|---|---|
| Question it answers | What should an AI read on this site? | What can an agent do against my backend? | What can an agent do on this page, right now? |
| Runs where | Static file on your server | A server you deploy | Inside the page, in the user's browser |
| Authentication | None | Its own — OAuth, API keys | The user's existing session |
| Maturity in 2026 | Widely published, weak evidence of use | Broad client support | Chrome and Edge origin trials only |
What I Would Ship Before 16 November
For a tools site like this one, the move is small and reversible: register a handful of read-only tools behind feature detection, start with declarative attributes on forms that already exist, leave toolautosubmit off everywhere, and log how many tools actually registered on each page view. Enrol in the trial, put its end date in monitoring, and budget for at least one more API change before anything stabilises.
What I would not do is restructure the UI around agents. Firefox and Safari have not committed, the spec is a community draft, and the only guaranteed outcome of an origin trial is that it ends. Build the tools so that when WebMCP is missing, nothing about the page for a human changes.