Skip to content

What Is WebMCP and Why Your Website Needs It

10 min read
Bart Waardenburg

Bart Waardenburg

AI Agent Readiness Expert & Founder

The way AI agents interact with websites is changing. Until recently an agent that wanted to book a flight or search a catalog on your site had to read the accessibility tree or a screenshot, guess which button did what, click, wait and repeat. WebMCP, a W3C proposal co-edited by engineers from Google and Microsoft, gives websites a standard way to expose their functionality as structured tools that an agent can call directly, in the user's own browser session.

In February this was a Chrome flag and a draft. Since August it is something an agent will use: OpenAI's ChatGPT desktop browser and Codex call WebMCP tools on pages that offer them, Shopify switched tools on for every Liquid storefront, and Chrome and Edge run origin trials. WebKit has formally opposed the proposal and Mozilla is neutral, so this is not a done deal either.

What WebMCP is

WebMCP (Web Model Context Protocol) is a browser API, incubated in the W3C Web Machine Learning Community Group as a Draft Community Group Report. It lets a page register tools: named functions with a description, a JSON Schema for their input, and an execute callback. An agent running in or alongside the browser reads those definitions and calls the tools instead of driving the page through its UI. The proposal came from Microsoft's Edge team in August 2025, and Google's Chrome team co-edits it.

The name invites a misreading, so a clarification from one of its authors, Patrick Brosset: the browser does not become an MCP server. WebMCP covers the primitives layer, the tool definitions, and leaves the protocol plumbing to the browser and the agent. In other words, you write JavaScript functions and describe them; you never speak MCP yourself.

EDITORS
Google + Microsoft
STATUS
W3C CG draft
IN CHATGPT DESKTOP SINCE
25 Aug 2026

Why WebMCP matters

A typical browser-use session today looks like this: the agent takes a snapshot of the page, asks a model which element to click, clicks it, waits for the page to settle, and repeats, often dozens of times for a single task. Each round trip costs tokens and can fail on a moved button or a late-loading modal. From your server's point of view the traffic is indistinguishable from a scraper.

With WebMCP the same task is one call. A shop that registers a search_products tool receives a structured request and returns structured results, and the agent never touches the filter dropdowns. You decide which functions exist and what they accept, and everything runs in the visitor's own session with the same cookies and the same authorization your buttons already use.

ONE STRUCTURED CALL

A tool call replaces a loop of snapshots, clicks and waits, and returns data the agent can use directly.

YOU DEFINE THE SURFACE

Only the functions you register exist for the agent. Nothing else on the page becomes a tool by accident.

SAME SESSION, SAME CHECKS

Tools run in the user's tab with the user's login, so your existing authentication and validation apply.

As Christian Heilmann put it when the Chrome preview landed: "agents have become first-class citizens of the world wide web." Instead of fighting the web's infrastructure, agents can work with it, and the site owner keeps control over what is exposed.

Two APIs: declarative and imperative

WebMCP offers two ways to expose tools. The declarative API annotates HTML forms; the imperative API registers tools from JavaScript. You can use one or both.

The declarative API: attributes on forms

The declarative approach is the fastest way in. You add a few attributes to an existing form and the browser turns it into a tool definition that agents can discover and fill in. No JavaScript required.

Declarative API: an HTML form with WebMCP attributes html
<form
  id="search-flights"
  toolname="searchFlights"
  tooldescription="Search for available flights by origin, destination, and date"
  toolautosubmit="true"
>
  <label for="origin">From</label>
  <input
    type="text"
    id="origin"
    name="origin"
    required
    toolparamdescription="Departure airport code (e.g. AMS, JFK, LHR)"
  />

  <label for="destination">To</label>
  <input
    type="text"
    id="destination"
    name="destination"
    required
    toolparamdescription="Arrival airport code (e.g. CDG, SFO, NRT)"
  />

  <label for="date">Date</label>
  <input
    type="date"
    id="date"
    name="date"
    required
    toolparamdescription="Departure date in YYYY-MM-DD format"
  />

  <button type="submit">Search Flights</button>
</form>

The attributes, as described in the declarative API explainer:

  • toolname: the identifier of the tool (for example searchFlights)
  • tooldescription: a plain-language explanation of what the tool does, which the agent uses to decide when to call it
  • toolparamdescription: a description per input, so the agent knows what value to supply
  • toolautosubmit: optional, lets the agent submit the form after filling it in

The imperative API: registering tools from JavaScript

For anything beyond a form submission, the imperative API registers tools on document.modelContext. Each tool has a name, a description, an input schema, optional annotations and an execute callback. The getter moved from navigator to document in May 2026, because tools are scoped to a document and a window can outlive one; Chrome 150 deprecates the old location but keeps it as an alias, and OpenAI's browser exposes the new one.

Imperative API: registering a tool on document.modelContext javascript
if (typeof document.modelContext?.registerTool === "function") {
  const controller = new AbortController();

  await document.modelContext.registerTool(
    {
      name: "search_products",
      description: "Search the product catalog by keyword, category and maximum price",
      inputSchema: {
        type: "object",
        properties: {
          query: { type: "string", description: "Search keywords" },
          category: {
            type: "string",
            description: "Product category filter",
            enum: ["electronics", "clothing", "home", "sports"],
          },
          maxPrice: { type: "number", description: "Maximum price in EUR" },
        },
        required: ["query"],
        additionalProperties: false,
      },
      annotations: { readOnlyHint: true },
      execute: async ({ query, category, maxPrice }) => {
        const params = new URLSearchParams({ q: query });
        if (category) params.set("category", category);
        if (maxPrice) params.set("max_price", String(maxPrice));
        const res = await fetch(`/api/products?${params}`);
        return { results: await res.json() };
      },
    },
    { signal: controller.signal }
  );

  // Later, for example when the component unmounts:
  // controller.abort(); // unregisters the tool
}

Three details in that snippet matter. The feature check is mandatory, because outside the origin trials, the Chrome flag, Brave's experiment and the ChatGPT browser document.modelContext is undefined. Unregistering is done through an AbortSignal passed in the options, which is the only removal mechanism in the current spec. And registering a second tool with the same name rejects with an InvalidStateError, so keep names unique.

The same interface also exposes getTools(), which lists the tools registered on the page, and executeTool(), which runs one. Those are what an agent, an extension or a test harness uses to inspect and call your tools. The options object accepts an exposedTo list of origins, which controls which documents in the frame tree can see a tool.

Which API should you use?

Aspect Declarative API Imperative API
Implementation HTML attributes on forms JavaScript registration
Best for Search, contact, login, booking forms Complex logic, multi-step workflows, API calls
JavaScript needed No Yes
Dynamic behaviour Limited to form submission Full async logic, API calls, state updates
Response format Form submit, optionally respondWith() Whatever execute returns
Effort Minutes per form Hours per tool

In practice you will use both: declarative for the forms you already have, imperative for functionality that has no form.

The spec is thin on user consent. What it does specify: the API is only available in secure contexts (HTTPS), access is gated behind a permissions-policy feature called tools with a default allowlist of 'self', tools can be scoped to origins with exposedTo, and each tool can carry a readOnlyHint annotation that tells the agent it changes nothing. A built-in confirmation dialog, or an API for a tool to ask the user a question mid-execution, does not exist.

Confirmation lives with the agent. OpenAI's implementation gives every tool invocation a safety review, applies its normal confirmation rules to consequential actions such as purchases, messages, deletions and permission changes, and shows users a "Site tools" panel with every tool definition and a log of what was called. Its documentation also states that "website-provided tool definitions and results are untrusted content", which is the right posture. The mirror image applies on your side: an agent call is a request from a browser you do not control, so it gets the same validation and authorization as a form post.

Discovery: what exists and what does not

Tools registered with either API are discoverable once an agent has the page open in a browser that supports WebMCP; that is what getTools() is for. This is the only discovery mechanism the spec defines.

Site-level discovery, a way for an agent to learn what your site offers before it opens a page, is an open discussion in the community group with no proposal in the spec. No browser or agent documents reading a manifest, and the Shopify and OpenAI deployments publish none. Our scanner used to award points for a file at /.well-known/webmcp.json; as of 27 August it no longer does, because there is nothing for such a file to conform to and nobody reads it. ChatGPT does not act on it. The consequence, which I cover in the August post , is that from outside a capable browser your tools are invisible.

Where WebMCP runs today

WebMCP is a Draft Community Group Report, not on the W3C standards track. Where things stand on 27 August 2026:

Where Status Notes
Chrome Origin trial from Chrome 149 Local testing via chrome://flags/#enable-webmcp-testing; Gemini in Chrome announced at I/O as a consumer, no date yet
Edge Origin trial, Edge 150 Microsoft co-edits the spec
Brave Experimental Support in Leo AI chat
ChatGPT desktop app Live since 25 August 2026 Built-in browser, for ChatGPT Work and Codex, GPT-5.6 Sol and Terra
Firefox Position: neutral Mozilla's interest is in the declarative variant; no implementation
Safari Position: oppose WebKit cites privacy, security, API design and venue concerns; no implementation

Two platforms did more for adoption than any browser. On 5 August Shopify switched WebMCP on for every Liquid storefront, ten tools from search_catalog to proceed_to_checkout, with nothing for merchants to install. On 6 August Cloudflare opened a developer preview that injects a bridge script at the edge and registers tools on document.modelContext for sites that flip a toggle. Google's own list of companies experimenting with WebMCP, from I/O 2026, includes Expedia, Booking.com, Shopify, Credit Karma, TurboTax, Redfin, Etsy, Instacart and Target.

What is still open

In February I wrote a timeline that ran through the browsers. That was the wrong frame. Adoption is being decided by platforms and agent vendors, and the browsers are following. What remains genuinely open:

  • Standards track. The spec is still a Community Group report, and WebKit's opposition makes a move to the standards track harder.
  • Safari. As long as WebKit opposes, Safari users have no WebMCP path. Expect agent vendors to keep their DOM-driven fallbacks for years.
  • API churn. The getter moved once already; getTools() and executeTool() were added in July and August. Feature-detect everything and keep the fallback shim.
  • Discovery. Until the spec has a site-level answer, agents only learn about your tools by visiting, which keeps search visibility in charge of who gets visited.

How to implement WebMCP today

You do not have to wait for broad browser support. The declarative API costs a few attributes, the imperative API a small module, and both are inert in browsers that lack the API. Step by step:

Step 1: annotate your existing forms

Take your most important forms (search, contact, booking, login) and add the attributes. Minutes per form:

Search form with WebMCP attributes html
<form
  action="/search"
  method="get"
  toolname="searchProducts"
  tooldescription="Search products by keyword. Returns matching products with prices and availability."
>
  <label for="q">Search</label>
  <input
    type="search"
    id="q"
    name="q"
    required
    toolparamdescription="Search keywords, for example: wireless headphones"
  />
  <button type="submit">Search</button>
</form>

Step 2: register imperative tools

For functionality without a form, such as checking stock, comparing products or calculating shipping, register tools from a module:

Registering a read-only availability tool javascript
const mc = document.modelContext ?? navigator.modelContext; // shim while Chrome 150 keeps the alias

if (typeof mc?.registerTool === "function") {
  await mc.registerTool({
    name: "check_availability",
    description: "Check whether a product is in stock at a store near a postal code",
    inputSchema: {
      type: "object",
      properties: {
        productId: { type: "string", description: "Product SKU or ID" },
        postalCode: { type: "string", description: "Postal code for the store lookup" },
      },
      required: ["productId"],
      additionalProperties: false,
    },
    annotations: { readOnlyHint: true },
    execute: async ({ productId, postalCode }) => {
      const res = await fetch(`/api/availability/${encodeURIComponent(productId)}?postal=${encodeURIComponent(postalCode ?? "")}`);
      if (!res.ok) {
        return { error: "Unknown product ID. Use the SKU shown on the product page." };
      }
      return await res.json();
    },
  });
}

Step 3: handle agent submissions differently

When an agent submits a form you probably want to return structured data instead of a redirect, and log the interaction separately. The declarative explainer's SubmitEvent.agentInvoked and respondWith() are for that:

Responding to an agent-invoked form submission javascript
document.getElementById("search-form").addEventListener("submit", (event) => {
  if (!event.agentInvoked) {
    return; // people get the normal navigation
  }

  event.preventDefault();
  const formData = new FormData(event.target);
  const results = performSearch(formData.get("q"));

  event.respondWith({ results, total: results.length });
});

Step 4: test in a real agent

  • Open the page in the ChatGPT desktop app (ChatGPT Work or Codex) and check the "Site tools" entry in the address bar; it lists every tool definition the page registered
  • In Chrome, enable chrome://flags/#enable-webmcp-testing and install the Model Context Tool Inspector extension to list and call tools by hand
  • For production traffic, register for the Chrome origin trial (from Chrome 149) or the Edge one (Edge 150)
  • Call every tool with wrong and missing inputs and check that the error messages help an agent recover

What implementing WebMCP gets you

An agent that finishes the task on your site instead of abandoning it halfway, on the agents that support WebMCP, which today means ChatGPT's desktop browser, Brave's experiment and whatever consumes the Chrome and Edge trials. I have not seen published conversion numbers, and I would distrust any that appear this early.

TASKS THAT COMPLETE

Search, availability and cart actions become one call each, with nothing to mis-click along the way.

AGENTS READ YOUR WORDS

The tool descriptions you write are what the agent believes your site can do. On Shopify, Shopify wrote them; everywhere else you do.

FEWER GUESSES ON YOUR PAGE

Agents that use tools stop brute-forcing forms, which is better for your logs and your rate limits.

A HEAD START ON THE FALLBACK

Sites without tools are still driven through the UI. Being callable is the difference between a task done and a task guessed.

Mobile-responsive sites won the mobile era. I expect agent-callable sites to do the same in the agent era, and the shops that got WebMCP from Shopify this month without lifting a finger are the first test of that claim.

Who should implement WebMCP?

  • E-commerce: catalog search, product details, cart and checkout. On a stock Shopify Liquid theme you already have these; check what Shopify exposed on your behalf.
  • Travel and hospitality: flight, hotel and rental search. Multi-step bookings work, but each step is a tool call on the page the agent is on, since there is no cross-page flow definition in the spec.
  • SaaS platforms: account management, configuration, support tickets. Let agents perform administrative tasks through well-defined tools, with your existing permissions.
  • Financial services: account lookups, transaction history, calculators. Mark read-only tools honestly and leave anything that moves money to the agent's confirmation flow.
  • Healthcare: appointment scheduling, provider search, refill requests. Structured tools with clear input schemas reduce errors in workflows where a wrong click matters.
  • Real estate: property search, mortgage calculators, viewing appointments.
  • Content publishers: even read-only sites gain from the declarative API on their search form.

Start with your highest-traffic form. A search form with WebMCP attributes takes five minutes and makes your most important functionality callable.

WebMCP vs other agent protocols

Protocol Scope Where it runs Best for
WebMCP Client-side tool exposure In the browser (JavaScript) Interactive websites, forms, SPAs
MCP Server-side tool protocol Backend servers APIs, databases, backend services
A2A Agent-to-agent communication Between agents Multi-agent orchestration
OpenAPI API documentation Backend servers REST APIs, developer integrations
agents.json Agent endpoint discovery Static file Listing available agent endpoints

These protocols complement each other. WebMCP handles client-side browser interactions, MCP handles backend tool connections, A2A handles agent-to-agent coordination, and OpenAPI documents your REST APIs.

Best practices

  • Feature-detect, always. document.modelContext is undefined almost everywhere; a bare call throws.
  • Verb-based, unique names: search_flights, book_hotel, submit_ticket. A duplicate name rejects the registration.
  • Write descriptions for a reader who has not seen your site. The description is the only thing the agent has when deciding whether to call the tool.
  • Keep the list short. Every registered tool is context the agent has to read on every visit. Expose the tasks people actually come for.
  • Accept raw user input and normalise it yourself: natural-language dates, flexible formats, common typos.
  • Return errors an agent can act on, such as "Invalid airport code. Expected a 3-letter IATA code like AMS or JFK" instead of a bare 400.
  • Use readOnlyHint truthfully, and never as a way to skip a confirmation the user would want.
  • Reuse your existing endpoints and checks. A tool is a second front door to logic you already have. It must not become a side entrance around your authorization.

Getting started

You do not need to do everything at once. In order of return on effort:

  1. Add WebMCP attributes to your search form, the highest-impact and lowest-effort change
  2. Annotate your contact and login forms
  3. Register imperative, read-only tools for the lookups people ask about most: availability, pricing, order status
  4. Open your site in the ChatGPT desktop app and read what "Site tools" shows an agent
  5. Only then add tools that change state, and make sure each one runs the same checks as the button it replaces

Sources

Ready to check?

Scan your website

Measure published signals and get recommendations across 5 categories. The stable-core score and methodology grade appear only when evidence is complete.

  • Stable-core score and grade when evidence is complete
  • 5 categories, 70 checkpoints
  • Code examples for every recommendation

Related articles

Continue reading about AI agent readiness and web optimization.

WebMCP Is Live in ChatGPT and Codex: What Changed in August 2026
10 min read

WebMCP Is Live in ChatGPT and Codex: What Changed in August 2026

OpenAI turned on WebMCP site tools in the ChatGPT desktop browser and Codex on 25 August, three weeks after Shopify switched it on for every Liquid storefront. Three live deployments show the part nobody mentions: from the outside, you can't see any of it.

ai-agents agent-protocols web-standards
What Is agents.json? Advertising AI Agent Capabilities on Your Website
10 min read

What Is agents.json? Advertising AI Agent Capabilities on Your Website

agents.json is the emerging complement to robots.txt - a machine-readable file that tells AI agents what your website can do. We cover the Wildcard specification, compare it to A2A, MCP, and OpenAPI, and show you how to implement it step by step.

ai-agents web-standards agent-protocols
What Is MCP? The Model Context Protocol for AI Agents
10 min read

What Is MCP? The Model Context Protocol for AI Agents

Anthropic's Model Context Protocol (MCP) connects AI assistants to external tools and data. We cover the architecture, discovery via /.well-known/mcp.json, current adoption, and how to implement it.

ai-agents web-standards agent-protocols

Explore more

Explore the checks behind measured stable-core coverage.

Rankings
SEE HOW OTHERS SCORE

Rankings

Browse AI readiness scores for scanned websites.
Compare
HEAD TO HEAD

Compare

Compare two websites side-by-side across all 5 weighted categories.
About
HOW WE MEASURE

About

Learn about our 5-category scoring methodology.