WebMCP: Letting AI Agents Use Your Site Like an API, Not a Screenshot
Table of Contents
Ask an AI browser agent to “return this order” on a typical e-commerce site today, and watch what actually happens under the hood: it screenshots the page, sends the image to a vision model, guesses which of forty near-identical buttons is the right one, clicks, waits, screenshots again, and repeats — burning tokens and seconds on every step, and breaking the moment a designer ships a CSS refactor. Chrome’s answer to that is WebMCP, a proposed browser API that lets a page declare its own capabilities as structured, callable tools instead of making an agent reverse-engineer them from an interface built for human eyes.
The problem: agents are reverse-engineering interfaces built for humans
Today’s browser agents lean on two techniques, and both share the same flaw.
Screenshot-and-click feeds page images to a vision model, which infers what’s clickable and simulates the interaction. It’s slow (a vision-model round trip per action), expensive (every step is an inference call), and fragile — a moved button or a renamed label breaks the flow.
Raw DOM parsing skips the screenshot but doesn’t skip the guessing. Modern web apps generate deeply nested trees with class names like .css-1a2b3c, so an agent still has to infer what a form does from markup that was never meant to describe intent.
Both approaches force the agent to reverse-engineer a website’s capabilities from an interface designed for human visual consumption. WebMCP’s premise is straightforward: let the site just say what it can do.
The fix: two parallel layers, one page
WebMCP doesn’t replace your UI. It adds a second, machine-readable layer next to it:
- Human layer — your existing HTML, CSS, and JavaScript, untouched.
- Machine layer — a set of tools, each with a name, a description, and a JSON Schema for its inputs, registered through a browser API (
document.modelContext, formerlynavigator.modelContext).
The browser sits between the two, handling tool discovery, user consent, and execution — an agent visiting the page can ask “what can I do here?” and get back a typed, unambiguous answer instead of a DOM tree to interpret.
flowchart TB
subgraph Page["Your webpage"]
Human["Human layer\nHTML / CSS / JS UI"]
Machine["Machine layer\nregisterTool() + JSON Schema"]
end
Browser["Browser\ndiscovery, permission prompts,\nexecution boundary"]
Agent["AI agent\n(in-browser or extension)"]
User(["User"])
Human -.same app logic.-> Machine
Machine -->|tool list + schemas| Browser
Browser -->|discovered tools| Agent
Agent -->|"call tool(args)"| Browser
Browser -->|"consent prompt"| User
User -->|approve| Browser
Browser -->|"execute()"| Machine
Machine -->|result| Browser
Browser -->|result| Agent
Because tools run inside the real page, in the user’s authenticated session, there’s no OAuth dance to bolt on and no separate scraping-resistant API to maintain — the agent uses the same session cookies and application logic a logged-in human already has.
Two ways to expose a tool
WebMCP ships two APIs depending on how much control you need.
Declarative API: annotate a form you already have
If a feature is already an HTML <form>, you can turn it into a tool by adding a few attributes — no JavaScript required:
<form
toolname="supportRequestTool"
tooldescription="Submit a request for support."
action="/submit"
>
<label for="firstName">First Name</label>
<input type="text" name="firstName" />
<label for="lastName">Last Name</label>
<input type="text" name="lastName" />
<select
name="select"
required
toolparamdescription="Determines what team this request is routed to."
>
<option value="Customer happiness team">Return my purchase.</option>
<option value="Distribution team">Check where my package is.</option>
<option value="Website support team">Get help on the website.</option>
</select>
<button type="submit">Submit</button>
</form>
toolname and tooldescription tell the agent what the form is for; toolparamdescription documents an individual field, and the browser derives the rest of the JSON Schema from the input types that are already there. Add toolautosubmit if the tool should submit itself once the agent fills it in, useful for something like a search box:
<form toolautosubmit toolname="search_tool" tooldescription="Search the web" action="/search">
<input type="text" name="query" />
</form>
Imperative API: register a tool with custom logic
For anything that isn’t a plain form submission — toggling app state, running a client-side calculation, calling your own fetch layer — the imperative API registers a tool directly:
await document.modelContext.registerTool({
name: 'toggle_layer',
description: 'Control pizza layers (sauce, cheese). Use "add", "remove", or "toggle".',
inputSchema: {
type: 'object',
properties: {
layer: { type: 'string', enum: ['sauce-layer', 'cheese-layer'] },
action: { type: 'string', enum: ['add', 'remove', 'toggle'] },
},
required: ['layer'],
},
execute: async ({ layer, action }) => {
await toggleLayer(layer, action);
return `Performed ${action || 'toggle'} on layer: ${layer}`;
},
});
inputSchema is a standard JSON Schema, which is the part that matters most: it’s what lets the agent construct a valid call on the first try instead of guessing at parameter names, and it’s what the model uses to catch a malformed request before it ever touches execute.
What happens on a single tool call
The full lifecycle — discovery, consent, execution — looks like this:
sequenceDiagram
participant U as User
participant A as AI agent
participant B as Browser
participant P as Page (Machine layer)
A->>B: Open page / request tool list
B->>P: Read registered tools
P-->>B: Tools + JSON Schemas
B-->>A: Available tools (e.g. toggle_layer, search_tool)
A->>B: call toggle_layer({ layer: "cheese-layer", action: "add" })
B->>U: Permission prompt: allow this action?
U-->>B: Approve
B->>P: execute({ layer, action })
P-->>B: "Performed add on layer: cheese-layer"
B-->>A: Tool result
That consent step is the part worth dwelling on. WebMCP is explicitly permission-first — the browser can require a human-in-the-loop confirmation before a tool actually runs, and because everything executes inside a visible browsing context (not headlessly), an agent can’t quietly script fifty actions in a tab the user isn’t watching. Domain isolation keeps a tool registered on one origin from touching another, which matters once an agent might have several sensitive tabs open at once — banking in one, a shopping site in another.
Where this actually stands today
WebMCP is a Draft Community Group Report, not a shipped standard, and it’s worth being precise about the current shape of it:
- Prototyped in Chrome behind a flag (
chrome://flags/#enable-webmcp-testing), with an origin trial planned from Chrome 149 and an Early Preview Program for developers who want early docs and demo access. - Chrome-only for now — no other browser has committed to shipping it.
- Client-side and single-tab: there’s no cross-site discovery mechanism yet, so an agent can’t currently ask “which sites near me support WebMCP” — it has to already be on your page.
- The API surface is still moving;
navigator.modelContextwas already superseded bydocument.modelContextmid-preview, which is a useful reminder that none of the exact method names here are stable yet.
How this relates to Anthropic’s Model Context Protocol
The name is deliberate. MCP already standardizes how an AI application talks to external tools and data sources — typically a server process exposing tools over stdio or HTTP. WebMCP applies the same idea — tools with names, descriptions, and JSON Schemas that a model can call — to the browser tab itself, with the page as the tool provider and the browser as the trust boundary instead of a server and a client SDK. As Chrome engineer Anand Sagar frames it, the goal is to become something like the “USB-C of AI agent interactions” — one connector shape instead of a different bespoke scraping strategy per site.
What it means if you build web UI
The shift WebMCP asks for is real but narrower than it sounds: you’re not building a second application, you’re exposing the application logic you already have through a second, typed entry point. A checkout flow, a filter panel, a support form — each already has a function underneath the click handler; WebMCP just gives that function a name, a schema, and a front door an agent can use without screen-scraping your button labels.
It’s early enough that I wouldn’t rebuild anything around it yet — one browser, one flag, an API that already renamed its own entry point once. But the direction is worth tracking: if “agent-readable” becomes as standard an expectation as “mobile-responsive,” the sites that already have clean application logic behind their UI will have the easiest time exposing it.
Sources: Chrome for Developers: WebMCP, Chrome Blog: WebMCP Early Preview Program, Vijay Kumar: WebMCP — agents are learning to browse better.

