Define the tools once. Humans get forms, agents get schemas.
WebMCP is the browser's answer to a question MCP already answered for servers: how does an agent act on an app without guessing at its UI? Chrome has it in origin trial, Microsoft co-authored it, and the registration call costs three kilobytes of feature-detected code. So our dashboard now speaks it. Here is what shipped, the code, and an honest read on where the standard actually stands.
What is WebMCP?
WebMCP (Web Model Context Protocol) is a proposed web standard that lets a web page register tools AI agents can discover and call through the browser. A page describes each action it supports, a name, a description, a JSON Schema for inputs, and registers it on document.modelContext. An agent operating in that browser calls the tool directly, with the user's existing session and permissions, instead of navigating the human UI by screenshot and click. It is incubated in the W3C Web Machine Learning Community Group by Microsoft and Google, and Chrome ships it today behind an origin trial.
The browser half of a familiar idea
MCP solved tool use for agents that live outside the browser: Claude Code calls publish_html on our MCP server and a site exists. But a second kind of agent is arriving, one that operates inside the browser, alongside a signed-in human. Today that agent's only interface to a web app is the human one: read the DOM or a screenshot, find the button, click, hope the modal is where it was last week. Every dashboard becomes a vision problem.
WebMCP's bet is that pages should just say what they can do. The page registers tools, the browser mediates, the agent calls them. Same JSON Schema discipline as MCP, same result shape (content blocks), but the execution happens in the page's own JavaScript with the user's own session. No tokens to mint, no API client to configure: if the human could do it from the page, the agent can be handed the same capability, explicitly, with the page's own validation in the path.
What we shipped: one catalog, three surfaces
The Stacktree dashboard now has a command palette (⌘K) built on agentk, an open-source cmdk extension we built for exactly this pattern. Every command in it is defined as a tool: a name, a description, and a JSON Schema for its parameters. Set a password, set an email gate, set an expiry, mint a share link, delete a site. The palette renders forms straight from the schemas, so a human types ⌘K, picks "Set password", and gets a generated form with validation.
Those same definitions are then registered on document.modelContext, feature-detected, when the browser exposes it. The verbs deliberately mirror our MCP server's tools: set_password, set_expiry, set_email_gate mean the same thing whether an agent reaches us over MCP from Claude Code, over REST with an API key, or in-browser over WebMCP. One catalog; the surface is just a door.
That is the actual point, beyond any one standard. Tools described as data instead of buttons hard-wired to handlers serve three consumers at once: the palette UI for humans, WebMCP for in-browser agents, and an LLM tool list whenever we want natural-language intent in the palette itself. Adding the third surface cost a useEffect.
The registration code, in full
This is the production code, not a sketch. The only abstraction is executeTool, the same function the palette's forms call:
// Chrome 150 moved the API from navigator.modelContext
// to document.modelContext; accept either.
function getModelContext() {
const mc = document.modelContext ?? navigator.modelContext;
return mc && typeof mc.registerTool === 'function' ? mc : null;
}
useEffect(() => {
const mc = getModelContext();
if (!mc || tools.length === 0) return;
for (const tool of tools) {
mc.registerTool({
name: `stacktree_${tool.name}`,
description: tool.description,
inputSchema: tool.inputSchema,
execute: async (params) => {
const text = await executeTool(tool.name, params);
return { content: [{ type: 'text', text }] };
},
});
}
return () => {
for (const tool of tools) mc.unregisterTool(`stacktree_${tool.name}`);
};
}, [tools]); Notes that matter in practice. The cleanup function is not optional: in a single-page app the available tools change with state (our site list is an enum in the schema, refreshed when sites change), so stale registrations must come down. The result shape, content blocks with typed parts, is MCP's, which is what makes the two protocols feel like one vocabulary. And the whole thing is a no-op in every browser that does not expose modelContext, which today is most of them.
Where the standard honestly stands
Plainly: WebMCP is early, and anyone telling you otherwise is selling something. The spec is a draft in the W3C Web Machine Learning Community Group. Chrome implements it behind an origin trial, and Chrome's own documentation labels the API "under active discussion and subject to change". The rename is the proof: code written against navigator.modelContext in February was deprecated by Chrome 150 in favor of document.modelContext. Microsoft co-authored the spec and has said more Edge news is coming; Firefox and Safari are in the discussion but have committed to nothing.
So no, your users' browsers mostly cannot call our WebMCP tools today. We shipped the registration anyway, and the next section is the reasoning, because it is a cost-benefit calculation other teams will face soon.
Why ship against a moving spec
The cost side: because the palette already defines every action as a JSON Schema tool, WebMCP registration was about thirty lines, feature-detected to zero effect elsewhere. If the API renames again, we change one accessor. The downside is bounded at trivial.
The benefit side is the same reason we published llms.txt, machine-readable pricing, and an x402 catalog before most of their consumers existed: agent-readable surfaces compound. When a browser agent first looks at the Stacktree dashboard and asks "what can I do here", the answer is already structured, already versioned with our MCP vocabulary, already tested by every human who used the palette, because they are the same tools. Day one of the standard landing is day one of it working here.
And for an agent-first host specifically, this is not a side bet. Our users' agents publish the sites; their humans review them in this dashboard. The gap between those two has always been the place where someone falls back to clicking. WebMCP is the first credible proposal for closing it from the browser side, and a publish primitive should be fluent in every protocol agents use to act. MCP for the editor, REST for the script, x402 for the payment, WebMCP for the page.
Frequent questions
What is WebMCP? +
What is the difference between WebMCP and MCP? +
Is WebMCP available in browsers today? +
How do you register a WebMCP tool? +
Why would a dashboard expose WebMCP tools? +
Does WebMCP replace Stacktree's MCP server? +
Related guides
- Publish HTML over MCP The server-side half of the same vocabulary: one tool call from Claude Code to a live URL.
- MCP spec changes in 2026 How the protocol WebMCP borrows its shapes from is itself evolving.
- The publish primitive The thesis underneath all of these surfaces.
- Stacktree for AI agents Every agent door we expose: MCP, REST, skills, x402, and now WebMCP.
Sources and further reading
- Chrome for Developers: WebMCP imperative API ↗ Primary documentation: registerTool shape, origin trial status, and the navigator-to-document rename in Chrome 150.
- WebMCP spec (W3C Web Machine Learning CG) ↗ The draft specification and explainer, incubated by Microsoft and Google.
- Patrick Brosset: WebMCP updates and next steps ↗ From one of the spec's editors at Microsoft: how the API evolved from window.agent and where the collaboration stands.
- agentk on npm ↗ The open-source cmdk extension the palette is built on: JSON Schema tools, generated forms, WebMCP-ready.
Your agent publishes. Your dashboard cooperates.
Sites your agent ships over MCP, managed by humans or in-browser agents through one schema-defined tool catalog. Start free.
Sign up free →