When an agent buys something on a website today, it usually works the page the way a very patient tourist works a foreign menu. It takes a screenshot. It finds a rectangle that looks like it might be a button. It clicks. It waits for the page to settle, and then it takes another screenshot to find out what happened.

Every one of those passes costs an image and a model call, which is why agentic checkout feels slow and expensive. And the whole thing rests on an assumption that holds only until your design team ships a redesign: that the button will still look like a button, in roughly the same place.

How an agent works a page it cannot read Take a screenshot of whatever loaded Guess which pixels are the button Click and hope no undo, no receipt Wait for the page to settle one screenshot, one model call, every single pass the site ships a redesign and the loop stops finding anything Reading a page as an image means paying for a fresh look before every click.
The pixel loop. It demos well and breaks quietly.

The odd part is that your site already knows all of this. It has a search, a cart, a checkout, a booking flow. None of it is written down anywhere a program can read.

So the failure isn't that agents read pages badly. Pages were never written for anything except people. Every button on your site is a promise made in a visual language, and an agent has to reverse-engineer that promise from a screenshot on every visit.

WebMCP is the proposal that closes that gap. It is a browser API, developed jointly by engineers at Google and Microsoft in the W3C Web Machine Learning Community Group, that lets a page hand an agent a list of its own actions: a name, a description written in plain English, and a JSON Schema for the inputs each one takes. Instead of the agent working out what a button does, the site says what it does.

Six ways an agent can reach your app

WebMCP is one of six routes an agent can take into a web application. Laying them out in order — from furthest away from your interface to closest to it — is the quickest way to see what makes this one different.

01

The raw API

Your script calls the company's backend directly with an API key. Precise and fast, but you found the endpoints yourself and you manage the key. The website is never involved.

your agent → HTTPS + key → their backend
your agentsetup requiredtyped actions
02

A backend MCP server

The company runs a server that describes its actions as named tools and your agent connects to it. Someone who understands the product defined those tools, which helps. The interface is still skipped.

your agent → MCP server → their backend
your agentsetup requiredtyped actions
03

Computer use

Your agent sees the live page as an image and clicks around. Nothing to set up, works on any site ever built, and every look costs money. A layout change confuses it.

your agent ↔ pixels ↔ the page
your agentzero setuppixels only
04

Browser automation

Your agent reads the page's markup instead of a picture of it, which is more reliable than pixels. The tools are generic, so the agent still has to infer meaning from anonymous divs.

your agent ↔ DOM tools ↔ the page
your agentzero setupgeneric structure
05

WebMCP

The page declares its own actions with names, descriptions and typed inputs, and your agent calls them. The work happens in the tab you are already sitting in, signed in as you.

your agent ↔ named tools ↔ the page
your agentzero setuptyped actions
06

The site's own assistant

The company ships a chat box, picks the model and pays for the tokens. It is accurate, because it was built by people who know the product. Your agent stays outside.

vendor's agent → app logic + data
their agentzero setuptyped actions

What each one gives up

Three things vary across the six: whose agent does the work, what someone has to configure before anything happens, and what the agent actually receives once it arrives. Every option except one trades away at least one of the three.

What each approach gives up Your own agent Nothing to configure Named, typed actions Raw API Backend MCP server Computer use Browser automation WebMCP Built-in site assistant the only row with three ticks Every route trades away your agent, your setup time, or real named actions.
The raw API and the backend MCP server give you clean typed actions, but you do the configuring and the site itself never comes into it. Computer use asks for nothing and hands the agent pixels. Browser automation gives structure — the same generic structure as every other site on the internet. The built-in assistant is precise and free, and it isn't yours, so nothing it learns travels with you.
Three things an agent needs on the web Your own agent Nothing to configure Named, typed actions Computer use Browser automation Raw API Backend MCP server Built-in site assistant WebMCP the only one in the middle
WebMCP keeps all three: you bring your own agent, you configure nothing, and you get named actions instead of guesswork.

What changes when the page declares

Once the site names its own actions, several things follow that are easy to underrate.

Guessing Agent screenshot ? ? ? best guess Wrong click one redesign breaks it Declaring Agent reads the tool list exact call search_products add_to_cart checkout add_to_cart(sku, 2) When the page names its own actions, there is no interpretation step left to get wrong.
Same page, same agent. The difference is whether anyone wrote the actions down.
  • There is no guessing step. The agent gets a list of actions with typed inputs. Bad arguments fail against the schema instead of quietly doing the wrong thing to somebody's cart.
  • The action runs in the session the user is already in. It executes inside the browser tab, so there is no API key for the agent to hold, no second login, and no token to pass around.
  • The available actions change with the page. A logged-out visitor's agent might see search and product lookup. After sign-in, the page registers order history, cart and checkout. Nothing special happens on the agent's side — it reads the list again.
  • Your interface stays in front of the user. Tools execute on the visible page, so the person watches it happen, and your product doesn't get reduced to an API being called from inside somebody else's chat window.
  • Any model can call it. Inputs are described with JSON Schema, the same format Claude, GPT and Gemini already use for tool calling, so you describe each action once.
Signed out Signed in tools the agent can see tools the agent can see user signs in read only added by the page, not the agent The site decides which actions exist for the session the visitor is already in. search_products get_product search_products get_product order_history add_to_cart checkout
Permissions come for free, because they are just your existing session.

Setup in code

A tool is a plain JavaScript object handed to the browser. The code lives in your page's own front-end script — the same JavaScript that already runs when someone loads the site. You register each tool once, and from then on an agent visiting that page can list it and call it.

// Feature-detect: this API is experimental and not everywhere yet.
if ('modelContext' in document) {
  await document.modelContext.registerTool({
    name: 'add_to_cart',
    description: 'Add a product to the shopping cart on this page.',
    inputSchema: {
      type: 'object',
      properties: {
        productId: { type: 'string', description: 'SKU from the product page' },
        quantity:  { type: 'number', minimum: 1, default: 1 }
      },
      required: ['productId']
    },
    async execute({ productId, quantity = 1 }) {
      // Reuse the function already behind your own button.
      await addToCart(productId, quantity);
      return {
        content: [{ type: 'text', text: `Added ${quantity} × ${productId} to the cart.` }]
      };
    }
  });
}

There are four parts and only one of them is new work. The name is what the agent calls. The description is written in plain English, because a language model reads it to decide whether this is the right action — write it for a smart new colleague, not for a docs page. The inputSchema says which arguments are valid, so malformed calls never reach your code. And execute is the function that runs: it calls addToCart, the same function already sitting behind your own button. You are not building a second version of your product for agents. You are pointing at the one you have.

If the thing you want to expose is already a form, you write no JavaScript at all. Two attributes on markup you already ship will do it:

<form toolname="search_flights"
      tooldescription="Search available flights between two cities.">
  <input name="from" placeholder="Departure city">
  <input name="to"   placeholder="Arrival city">
  <button type="submit">Search</button>
</form>

The browser reads the form, works out that it takes a from and a to, and builds the schema itself. Add toolautosubmit if you want the agent's call to submit the form rather than just fill it in — and think twice before you do that on anything that spends money.

Four things that trip people up

The API moved. Early write-ups used navigator.modelContext. The spec moved the getter onto the document, on the reasoning that tools belong to a page rather than to the browser, and Chromium 150 deprecated the old name. The old spelling still runs in some builds, which makes the change easy to miss. Probe for document.modelContext and treat anything else as legacy.

It is gated by permissions policy. Both APIs sit behind the tools permissions policy, which defaults to self. Tool registration works in top-level and same-origin contexts, and is off in cross-origin iframes unless the embedding page adds allow="tools".

It needs an origin-isolated document. If your page enables document.domain (for example with an Origin-Agent-Cluster: ?0 header), the WebMCP APIs are disabled outright, so that the document's origin stays stable for the lifetime of a tool.

Tool arguments are untrusted input. A tool call is a request from a model that may have read text written by somebody else on the internet. Validate on the server as you would for any public form, keep destructive actions behind a confirmation the human has to click, and be deliberate about the exposedTo option, which is how you share a tool with specific trusted origins rather than keeping it to your own.

Where this actually stands

Spec
Draft Community Group Report in the W3C Web Machine Learning Community Group, edited by Google and Microsoft engineers. Not a finished standard, and it has already renamed things mid-flight.
Chrome
Public origin trial from Chrome 149. Local development flag at chrome://flags/#enable-webmcp-testing.
Edge
Preview support; Microsoft is co-authoring the spec.
Agents
In practice the callers today are the browser's own agentic surfaces and test harnesses, not the mainstream assistants most people use.
Frameworks
Angular ships experimental WebMCP support; other ecosystems are mostly community shims.

Chrome's own documentation is honest about the limits. WebMCP is designed for local browser workflows with a human in the loop rather than headless automation. Complex interfaces may need real refactoring before their state is expressible as tools. And discovery is unsolved: a client has to visit your site to find out that it has callable tools at all — there is no directory.

So this is not a thing to bet a quarter on. It is a thing to spend an afternoon on, because the cost of trying is close to nothing and the downside is bounded: pages that register tools are ordinary pages everywhere the API doesn't exist.

How to try it this week

  1. Turn on chrome://flags/#enable-webmcp-testing and relaunch. For live traffic, register for the origin trial instead and add the token to your pages.
  2. Pick a form you already have. Search is the cheapest possible start. Add toolname and tooldescription to it and reload.
  3. Install the Model Context Tool Inspector extension. It lists the tools registered on the page, calls them by hand, and shows you the exact output your tool returned — which is where most schema mistakes surface.
  4. Prompt it in plain language and watch whether the agent picks the right tool. If it doesn't, the description is usually the problem, not the code.
  5. Then move up: three to ten core actions, registered imperatively, each one reusing a function you already ship. Confirmations on anything that spends money.

A site that tells an agent what it can do gets cleaner, more reliable results than a site that makes the agent guess from pixels. That much is not really in question. What's in question is whether enough sites write their actions down for browsers to keep investing in reading them — and that part is decided by whoever adds the two attributes first.

Frequently asked questions

What is WebMCP?

WebMCP is a proposed browser API that lets a web page declare its own actions — each with a name, a plain-English description and a JSON Schema for its inputs — so an AI agent can call them directly instead of guessing at the interface from a screenshot. It is being developed by Google and Microsoft engineers in the W3C Web Machine Learning Community Group, and it runs inside the tab the visitor is already signed into.

Is WebMCP available in Chrome yet?

It is available for testing, not for production. Chrome has run a public origin trial since Chrome 149, and you can switch it on locally with the chrome://flags/#enable-webmcp-testing flag. Edge has preview support and Microsoft is co-authoring the spec. It remains a Draft Community Group Report rather than a finished standard, and the API has already been renamed once.

Is it document.modelContext or navigator.modelContext?

Use document.modelContext. The specification moved the getter from Navigator to Document, on the reasoning that tools belong to a page rather than to the browser, and navigator.modelContext was deprecated in Chromium 150. The old spelling survives as an alias in some builds, so existing code keeps working — which is exactly why the change is easy to miss.

Do I need to write JavaScript to expose a tool?

Not if the thing you want to expose is already a form. Adding toolname and tooldescription attributes to a <form> is enough — the browser derives the JSON Schema from the fields and their labels on its own. Add toolautosubmit if you want the agent's call to submit the form rather than just fill it in, and be careful with that on anything that spends money.

How is WebMCP different from a backend MCP server?

A backend MCP server exposes a company's actions from the server side, which means the agent skips the website entirely and someone has to configure a connection and its credentials first. WebMCP runs in the browser tab, reusing the session the visitor is already signed into — so there is no API key for the agent to hold and no setup step before it works. The trade-off is reach: a backend server works headlessly, while WebMCP is designed for a human-in-the-loop browser workflow.

Before an agent can call your actions, it has to reach your pages

WebMCP only matters on a page an agent can actually load. If you want to know which AI crawlers and assistants can see your site today — and which ones your robots.txt is quietly turning away — the free AI crawler checker shows you the whole access map in a few seconds.

And for the wider picture of how answer engines decide what to quote, start with How to Get Cited by AI or the metrics worth watching in AI Search KPIs.

Sources and further reading