Skip to main content
AI6 min read

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, formerly navigator.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.modelContext was already superseded by document.modelContext mid-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.

Mohammed Alfas

Mohammed Alfas

Software Engineer

I'm a software engineer who spends most days building things for the web and most nights reading about how AI is changing how we build them. This site is where I write down what I learn.

Related posts