August 26, 2026AI agents

How to Make Your Website Agent-Ready with WebMCP

A working guide to WebMCP, the browser API that lets your page hand an AI agent named functions instead of pixels. What it is, how to add your first tool, how to design tools an agent can use, what being agent-ready is worth for conversions, and where the idea is going.

By Akshay Aggarwal · Updated August 26, 2026 · 18 min read

Most AI agents use a website the way a person does. They take a screenshot, ask a model where to click, click there, take another screenshot to see what happened, and repeat. It works often enough to be impressive and costs enough to be painful.

WebMCP is a different arrangement. Your page publishes a list of things it can do, each with a name, a description in plain English and a schema for its inputs. An agent in the browser reads that list and calls the function. No screenshots, no guessing which button is the real submit button, no fifteen turns to complete a booking.

If you run a site, this is the first concrete answer to a question that has been vague for a year: what does it mean to be ready for agents? Not a robots.txt line, not a schema.org block. A list of things your site can do, written down in a form a model can call.

This post is the practical version: what the API looks like, how to add it to a site, how to write tools an agent can actually use, what being agent-ready is worth commercially, and where the idea is heading.

What it actually is#

WebMCP adds one object to the page. Every document gets a modelContext, and you register tools on it. Here is a complete tool:

await document.modelContext.registerTool({
  name: 'add_to_cart',
  description: 'Add a product to the shopping cart by product ID and quantity.',
  inputSchema: {
    type: 'object',
    properties: {
      productId: { type: 'string', description: 'The product ID, as shown on the product page.' },
      quantity: { type: 'number', description: 'How many units to add. Defaults to 1.' },
    },
    required: ['productId'],
  },
  annotations: { readOnlyHint: false },
  execute: async ({ productId, quantity = 1 }, { signal }) => {
    await cart.add(productId, quantity, { signal });
    renderCart();
    return `Added ${quantity} of ${productId}. Cart total is now ${cart.total()}.`;
  },
});

The execute function is your own code. In most cases it is the same function your button already calls. The agent sees the name, the description and the schema, decides whether the tool fits what the user asked for, sends arguments that match the schema, and gets your return string back.

Three details matter more than they look.

The tools belong to the tab. They exist while that page is open, and they are gone when the user navigates away. There is no registry to publish to and no uptime to maintain. An agent learns what your site can do by being on your site.

There is no token. Every backend integration you have ever set up issued a credential that reaches an account from anywhere, whether or not the user's machine is on. A WebMCP tool runs inside the tab under the session the user already has. Nothing new is minted and closing the tab ends it. That is a real difference from the OAuth grant behind a Connect button.

It is not MCP, despite the name. There is no JSON-RPC, no server and no transport. Mozilla's reviewer said the name misleads developers who reasonably assume the MCP spec is involved, and they have a point. The two are related by idea, not by wire format.

MCPWebMCP
Where the tool runsA server, or a process on the user's machineThe page, in the tab
LifetimePersistentEnds on navigation
AuthOAuth token or local process trustThe session cookie the user already has
Who can call itAny MCP client, anywhereAn agent in that browser, on that page
Written inAny language with an SDKJavaScript, or HTML attributes
Good forServer-side capability that should always be availableLive interaction with a page and its client state

Adding it to a site#

Start with the smallest useful thing rather than a plan to expose your whole product. Pick two or three functions that a user does often, wrap them, and see what an agent does with them.

For local development, turn the API on at chrome://flags/#enable-webmcp-testing. To run it for real users, register for the origin trial and put the token in the page:

<meta http-equiv="origin-trial" content="YOUR_TOKEN_HERE">

Feature detection is one line, and you should ship it, because most of your visitors are on a browser that has never heard of this:

if ('modelContext' in document) {
  await registerAgentTools();
}

Two platform rules will bite you if you skip them. WebMCP is available only in origin-isolated documents, so a page that sets document.domain gets nothing. And tool registration is governed by a tools Permissions Policy that defaults to self, so a cross-origin iframe cannot register tools unless the embedder allows it with allow="tools". If you want a partner origin to see a specific tool, pass exposedTo when you register it.

If your app is mostly forms, you may not need JavaScript at all. Annotate the form and the browser builds the schema for you from the labels and options:

<form toolname="supportRequestTool"
      tooldescription="Submit a request for support."
      action="/submit">
  <label for="firstName">First Name</label>
  <input type="text" name="firstName">

  <select name="team" 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>
  </select>

  <button type="submit">Submit</button>
</form>

Removing toolname or tooldescription unregisters the tool, which gives you a simple way to turn tools on and off as the page changes. The form stays visible to the user while the agent fills it, and you can check agentInvoked on the SubmitEvent if you want to handle an agent submission differently from a human one. There is also a toolautosubmit attribute that submits without review, which I would keep away from anything that spends money.

In a single-page app, register on mount and unregister on unmount. An AbortController handles both:

useEffect(() => {
  const controller = new AbortController();
  document.modelContext?.registerTool(checkoutTool, { signal: controller.signal });
  return () => controller.abort();
}, []);

TypeScript definitions are published as webmcp-types, and the explainer points React developers at a usewebmcp package.

Designing tools an agent can use#

This is the part that decides whether the feature works, and it has almost nothing to do with the API. Chrome's own guidance is unusually specific, and it matches what anyone who has written tool descriptions for a model already suspects.

One tool, one job. Overlapping tools confuse the model, and every tool you register costs context and slows down the choice. Ten precise tools beat forty vague ones.

Name the tool for what it does, and be honest about whether it finishes the job. create-event should create the event. If your tool only opens a form for the user to complete, call it something like start-event-creation-process so the agent knows the work is not done.

Write descriptions that say what the tool can do rather than what it cannot. "This tool can create a calendar event scheduled for a specific date and time" works. "Do not use this tool for weather" does not, because it spends your description budget on a negative.

Take input in the shape a person would give it. If a user says "11:00 to 15:00", let the tool accept that string instead of demanding two ISO timestamps. Use enums where the choices are fixed, and prefer meaningful values over internal identifiers: shipping: "Express" is better than shipping_id: 1.

Validate strictly in your code and loosely in the schema. When a call is wrong, return a descriptive error rather than throwing something generic, because a model that reads a clear error usually fixes its own arguments and retries.

Update your interface when a tool changes something. The agent looks at the page to plan its next move, and a cart that silently changed in memory but not on screen will send it in the wrong direction. The user is watching too, which is the entire point of keeping this in the browser.

Keep things short. Chrome's guidance suggests roughly 30 characters for tool names, 500 for descriptions, 150 for parameter descriptions and 1.5K for output. The spec separately caps tool names at 128 characters.

Register tools that match the current page state. If the user is logged out, do not advertise a tool that requires an account. If they are on a product page, that is when add_to_cart makes sense.

What you get for it#

The most useful public numbers come from WindTunnel, which ran 49 tasks across 8 sites in 16 model and interface configurations, three attempts each. In the canonical run dated 20 August 2026, holding the model constant, calling WebMCP tools cost about 23 times less than a DOM and vision agent doing the same work ($0.009 against $0.210 per task), finished about 5.5 times faster (6.8s against 29.3s median) and used about 12.5 times fewer tokens (5,172 against 64,424 median).

Both approaches solved 48 of the 49 tasks.

That parity is worth sitting with, because it tells you what WebMCP is for. Screen-driving already works on a well-built site. What changes is the price. A twentyfold cost difference is the difference between an agent feature you offer to paying customers and one you can leave on for everyone. The benchmark also found that screen-driving attempts ran out of their turn budget 181 times while tool-calling attempts never did, which is the reliability story rather than the capability story. One result cuts the other way: on a sensitive checkout task, the screenshot-driven agent succeeded 18 times out of 20 against WebMCP's 15. A deterministic call is not automatically the safer one.

Read that benchmark knowing who ran it. It comes from a company building WebMCP tooling and was posted into the W3C review thread as an argument for the design. The method and the raw results are public, which is more than most vendor benchmarks give you.

There are two benefits the numbers do not show. The first is that you keep the user. When an agent talks to your backend through a server integration, your site is out of the conversation: no page, no upsell, no branding, no analytics, and a lot of state you now have to duplicate on a server. The explainer calls this disintermediation and treats avoiding it as a design goal. With WebMCP the work happens in your UI, in front of the person doing it.

The second is that you are not building a second product. A backend integration means replicating the user's session, permissions and context somewhere else. A WebMCP tool calls the function that is already on the page, with the auth the browser already has.

Reach and conversions, honestly#

Two questions come up whenever a site owner hears about this. Will it bring me traffic, and will it make me money? The answers are different.

It will not bring you traffic, at least not today. An agent finds your tools by loading your page, so there is no directory to be listed in and no ranking to win. WebMCP is not a discovery channel and anyone selling it as the next SEO is guessing. What discovery looks like for agents is still an open question, and the current design deliberately does not answer it.

Conversion is where the case is real, and it comes down to who completes the task. An agent that fights your interface abandons things: it mis-clicks a filter, gives up on a five-step checkout, or runs out of budget partway through and tells the user it could not finish. That is a lost sale in the same way a broken mobile layout is a lost sale. The WindTunnel run above is the cleanest public evidence: attempts driving the UI by screenshot exhausted their turn budget 181 times, and tool-calling attempts never did.

Chrome's own use-case write-up leans on the same intuition from a longer-running feature, noting that autofill deployed well can lower form abandonment by 75%. That number is about autofill rather than WebMCP, and it is their figure rather than an independent one, so treat it as a reason to look rather than proof. The mechanism is the same either way: fewer steps between intent and completion.

The commercial argument I find most convincing is not about conversion rate at all. It is about staying in the transaction. If an agent cannot use your site, the user's assistant will reach your business some other way: a marketplace, an aggregator, a backend integration you do not control, or a competitor who is easier to operate. In each of those, someone else owns the interface, the upsell and the relationship. The explainer names this directly and calls preventing disintermediation a design goal. Being callable in your own UI is how you stay in the middle of your own sale.

Where to start, in rough order of payoff: search and filtering, because it is read-only and the agent gets it wrong most often; long or multi-step forms, because that is where people and agents both give up; then repeat actions like reordering, where the agent has history to work from. Checkout last, and behind a confirmation.

The part to be careful about#

The spec's security section is candid in a way specs usually are not, and it is worth reading before you ship. On misrepresentation of intent it says: "There is no guarantee that a WebMCP tool's declared intent matches its actual behavior. This creates a fundamental trust gap: agents rely on natural language descriptions to decide whether to invoke a tool and whether to prompt the user for permission, but cannot verify the tool's actual effects before execution."

The listed risks include poisoned tool descriptions, injection through what a tool returns, and privacy leakage through over-parameterisation, where a site declares more parameters than it needs and a helpful agent fills them in from personal context the user never gave that site. The mitigations are still open issues, including the name length cap and a shared prompt-injection eval dataset that does not exist yet.

If your tool returns anything a user or a third party wrote, mark it:

annotations: { readOnlyHint: true, untrustedContentHint: true }

Where this goes#

The honest status: this is an incubation, not a standard. Chrome Platform Status lists its maturity as a specification being incubated in a Community Group, and the engines disagree about whether it should exist at all.

EnginePosition
ChromiumImplementing, origin trial from Chrome 149
WebKitOppose
GeckoNeutral, interested in the imperative API
W3C TAGReview open, tagged as missing multi-stakeholder support

WebKit's objection is worth understanding because it is about the shape of the web rather than the shape of the API. Their position is that an agent acting for a user is a kind of assistive technology, and a site should not be able to tell that one is driving. Once "an agent is here" becomes an observable fact, a site can give agents capabilities it withholds from its own interface, or withhold capabilities from agents, which is the screen-reader-blocking problem aimed at a new target. Their preferred fix is to close the gap in HTML and ARIA, where people, assistive technology and agents all benefit from the same work.

The counter-argument, made in the TAG thread, is that better semantics help an agent understand a page but do nothing about the cost of operating it, and that an HTML rich enough to express named actions with typed inputs and side effects would be a capability layer with extra steps. Both positions are reasonable, which is why this will take a while to settle.

So what should you expect? In the near term, a Chrome-family capability that some sites adopt for their highest-value flows: checkout, search, filtering, long forms. Adoption will be driven by cost rather than novelty, because that is where the measured difference is.

Further out, the interesting question is not technical. If agents can operate a site properly, sites gain a reason to invite them in rather than block them, and the argument shifts from "keep the bots out" to "which agents may act here, on whose behalf, and with what proof". You can see the beginning of that in exposedTo, which is a site deciding which origins are allowed to call its tools. That is an access-control model for agents, wearing the clothes of a JavaScript option.

Two things would have to happen for this to become infrastructure rather than a Chrome feature. A second engine has to implement something compatible, which today means the disagreement above has to resolve. And the injection problem needs a real answer rather than a hint flag, because a capability layer that any site can populate with attacker-written descriptions is a capability layer no careful agent will fully trust.

What to do this week#

Wrap two functions you already have and register them behind a feature check. Search and filter are good first candidates, since they are read-only and cannot embarrass you. Watch what an agent does with your descriptions, then fix the descriptions, because that is where almost all of the failure lives. Keep every tool reachable by a human through the UI, and leave anything that spends money behind an explicit confirmation. This is a one-implementation incubation, so a thin wrapper is a sensible bet and a rewrite is not.

Disclosure: we make Jarvis, a free and open-source Mac assistant that speaks MCP and does not implement WebMCP. The distinction is the reason why. Jarvis runs on your Mac and reaches mail, calendar and files through local tools and macOS itself, while WebMCP reaches one tab in one browser family. When it lands more widely it will complement that rather than replace it.

Frequently asked questions

What is WebMCP in simple terms?

A browser API that lets a web page publish its own functions as named tools with plain-English descriptions and JSON Schema inputs, so an AI agent in the browser can call them directly instead of taking screenshots and clicking around.

How do I add WebMCP to my website?

Call document.modelContext.registerTool() with a name, description, inputSchema and an async execute function that runs your existing client-side code, or annotate a form with toolname and tooldescription. Guard it with a feature check for modelContext in document, enable chrome://flags/#enable-webmcp-testing for local development, and add an origin trial token meta tag to run it for real users.

Is WebMCP the same as MCP?

No. MCP is a client-server protocol over JSON-RPC that connects AI applications to external systems and keeps working whether or not a browser is open. WebMCP is a browser API whose tools live in a tab and end when the user navigates away. The explainer lists replacing backend protocols like MCP as a non-goal.

Which browsers support WebMCP?

Chromium is the only engine implementing it, through an origin trial that starts in Chrome 149, with a local flag at chrome://flags/#enable-webmcp-testing. WebKit filed a formal position of oppose in June 2026 and Mozilla is neutral, so do not assume Safari or Firefox support.

Is WebMCP a security risk for my site or my users?

It is a new surface worth treating carefully. The spec names poisoned tool descriptions, injection through tool output, and privacy leakage when a site asks for more parameters than it needs. Mark tools that return user-generated content with untrustedContentHint, use readOnlyHint honestly, restrict cross-origin exposure with exposedTo, and keep a person in the loop for consequential actions.

Does WebMCP help SEO or bring agent traffic to my site?

Not directly. An agent discovers your tools by loading your page, so there is no listing, index or ranking involved. The benefit shows up after arrival, in whether an agent can complete a search, a form or a checkout on your site instead of failing partway and taking the user elsewhere.

Do I still need an MCP server if I ship WebMCP tools?

It depends where the logic lives. Capability that should be available to any AI client at any time belongs in an MCP server. Interaction with a live page under the user's existing session belongs in WebMCP. Plenty of products will end up with both.

Try it on your own Mac

Jarvis is free and runs on-device. Apple silicon and Intel.

Download Jarvis

Keep reading