AI

What Is WebMCP? How It Works and What It Means for AI Agents

This guide explains how WebMCP works, how it differs from MCP, and how to call a site’s tools from Playwright or Claude Code. It also covers adoption data from a scan of top homepages, security risks, and when to scrape pages instead.
28 min read
what-is-webmcp-R-mcp-page-wiring

WebMCP is a proposed web standard that lets a website give AI agents tools, such as “add to cart”. The site registers each tool in the browser, so agents call it instead of guessing what each button does. Chrome and Edge are testing it.

A scan of top-ranked homepages in a regular Chrome found tools on almost none, so agents still scrape most pages. Where tools exist, their output can differ from the rendered page.

This guide explains how WebMCP works and differs from the Model Context Protocol (MCP), and how to call its tools or scrape pages without them.

TL;DR

  • WebMCP tools run in the page, and MCP tools run in a server process. MCP clients reach WebMCP tools through a browser, for example with Playwright MCP.
  • In Chrome with default settings, 1 of 544 top-ranked homepages had WebMCP tools. The one site was a Shopify store, whose platform added the tools.
  • Treat tool text as untrusted. On the Shopify stores tested, the add-to-cart tool’s description said not to ask for confirmation.
  • Check the HTML for a WebMCP script or token first. On one store, the check used about 2% of a full page load’s traffic. Scrape pages without one.

What WebMCP is and which browsers support it

WebMCP is a JavaScript API in the browser. A page calls it to register tools. Each tool has a name, a natural-language description, a JSON Schema for its input, and a function that runs when an agent calls it. An agent discovers the tools and invokes them from inside the browser or from an external browser automation client.

One goal is reliability. Without WebMCP, a browser agent reads screenshots, the DOM, or the accessibility tree. That works on nearly any page the agent can load, but the agent has to infer what each button does. With WebMCP, the site declares which actions exist and which parameters each one takes.

The WebMCP specification is a W3C Community Group draft, edited by engineers at Google and Microsoft. Because it is still a draft, expect the API to change between Chrome releases.

Chrome and Edge run WebMCP as an origin trial, a time-limited test of a new feature on sites that register for it. During the trial, a site enables the API by serving a signed origin trial token. Support across browsers and agents differs widely:

Browser or agent Status when tested Details
Chrome Origin trial Chrome 149 to 156, extended through Chrome 162, which reaches the stable channel in February 2027
Edge Origin trial From Edge 150
ChatGPT desktop app Supported In the built-in browser, where OpenAI calls WebMCP tools “site tools”
Brave Experimental In its Leo assistant
Firefox Neutral Mozilla’s standards position. In Firefox Beta and Nightly, dom.modelcontext.enabled in about:config enables an implementation
Safari Opposed WebKit’s standards position

The API’s entry point is document.modelContext. During the origin trial, it exists only on sites that serve an origin trial token, or when a flag such as chrome://flags/#enable-webmcp-testing enables it everywhere. In practice, treat WebMCP in Chrome and Edge as an opt-in feature that each site enables.

How WebMCP works

A site exposes a tool by calling document.modelContext.registerTool(). The browser keeps the tool for the lifetime of the document, and the page can remove it at any time.

WebMCP example: register a tool

This WebMCP example registers a product search tool for a small store. It runs in Chrome 156 with the chrome://flags/#enable-webmcp-testing flag enabled:

const catalog = [
  { sku: "LS-1001", name: "Aluminium laptop stand", price: 51.25, stock: 14 },
  { sku: "LS-1002", name: "Adjustable laptop stand", price: 38.9, stock: 0 },
];

await document.modelContext.registerTool({
  name: "search_products",
  title: "Search products",
  description: "Search the store catalog by keyword. Returns SKU, name, price in USD, and stock.",
  inputSchema: {
    type: "object",
    properties: { query: { type: "string", description: "Keyword, for example 'laptop stand'" } },
    required: ["query"],
  },
  annotations: { readOnlyHint: true },
  async execute({ query }) {
    const hits = catalog.filter((p) => p.name.toLowerCase().includes(query.toLowerCase()));
    return { content: [{ type: "text", text: JSON.stringify(hits) }] };
  },
});

Put the snippet in a <script type="module"> and serve the page from http://localhost. The API exists only in secure contexts, such as HTTPS pages and localhost. The tool returns its matches as a JSON string inside a text content block. MCP tools use the same result format.

execute() is ordinary page JavaScript. It can call the site’s own API with the user’s session cookies, update the UI, or navigate. The agent does not receive that code. It gets only the tool’s name, title, description, input schema, and annotations, plus the return value of execute().

The annotations field in the example describes what kind of tool it is. The spec defines these annotations:

  • readOnlyHint – the tool changes nothing
  • consequentialHint – the tool performs a significant or irreversible action, such as a purchase
  • untrustedContentHint – the output contains data that the site does not trust, such as user reviews
  • debugging – the tool is for developers, not end users

Chrome 156 forwards these hints without validating them. Treat them as the site’s own description of each tool.

To inspect the tool in Chrome, open DevTools, go to the Application panel, and select WebMCP. The pane lists the page’s tools and logs each call with its status, input, and output:

Chrome DevTools Application panel with the WebMCP pane open on a localhost demo store. The call log shows one completed search_products call with the input query "laptop stand", and Available Tools lists search_products with its description
The example page in Chrome 156 after one search_products call from a script. The outlined row is the call and the arguments the caller sent.

What changed in 2026

WebMCP code from early 2026 often fails in Chrome 156, so check older tutorials before you copy them. The API moved from navigator.modelContext to document.modelContext in May, so calls such as navigator.modelContext.provideContext() no longer work.

With Chrome’s Declarative API, a site can also define a tool with an HTML form. The spec removed the Declarative API in October, but Chrome 156 still runs it. A declarative tool waits for a person to press Submit unless the form has the toolautosubmit attribute, so set a timeout on every tool call.

How Chrome exposes WebMCP tools to agents

Chrome 156 exposes the same tools to 3 kinds of callers. They are a browser extension, an in-page agent script, and a Chrome DevTools Protocol (CDP) client outside the browser:

Diagram: in Chrome 156, local or hosted, a web page registers tools in a tool map. A browser extension and an in-page agent reach the tool map inside the browser, and a CDP client in a remote agent reaches it through the WebMCP domain
Chrome keeps the tools in the tool map of document.modelContext, and a CDP client calls them with WebMCP.invokeTool.

Reach the tools through the DevTools Protocol

Playwright and Puppeteer automate Chrome over CDP, and Chrome 156 has an experimental WebMCP domain, a group of CDP commands and events. Puppeteer and Playwright 1.64, including Playwright’s Python package, expose a page.webmcp API, so your agent code can call tools without sending raw CDP commands. Puppeteer, Playwright, and CDP report readOnlyHint as annotations.readOnly, so use that name in client code. Page JavaScript, including the DevTools Console, still uses readOnlyHint.

Chrome 156 in headless mode listed the same tools as headed Chrome, and so did a hosted Chrome on the Bright Data Browser API. Chrome’s WebMCP documentation focuses on local use with a human in the loop. Still, the WebMCP explainer lists headless browsing as a goal, so automated use is part of the design.

In a Bright Data Browser API session, an agent lists and invokes a site’s tools through the same CDP connection that loads the site’s pages. The agent gets the same tools as a visitor’s Chrome, with no browser extension or flag.

WebMCP vs MCP

MCP connects an agent to tools on a server. The agent’s MCP client and the server exchange JSON-RPC messages over stdio or Streamable HTTP. WebMCP uses the same MCP concepts of tools, schemas, and results, but its tools run in a web page. That changes how an agent finds, calls, and authenticates to them:

Property MCP server WebMCP
Where the tool runs A server process the agent connects to JavaScript in an open browser tab
Tool discovery A tools/list request to a configured server By loading the page
Transport JSON-RPC over stdio or Streamable HTTP Calls inside the browser, or CDP for clients outside it
Authentication Server credentials such as API keys or OAuth tokens The user’s browser session and cookies for that site
Tool lifetime While the server runs For the lifetime of the document
Tool author The server owner Each site or its platform, page by page

When a site offers both an MCP server and WebMCP tools, try its MCP server first, because it needs no browser.

On the Shopify stores tested, a WebMCP tool led agents to an MCP server. Shopify theme stores registered a get_ucp_profile tool that returned the store’s Universal Commerce Protocol (UCP) profile, a JSON document at /.well-known/ucp. On Allbirds, a shoe brand on Shopify, the profile listed a server-side MCP endpoint at /api/ucp/mcp.

Shopify’s get_ucp_profile tool connects the two routes:

Diagram: in the MCP row, an agent calls an MCP server over JSON-RPC. In the WebMCP row, an agent calls tools in a browser tab, which calls the site API with the user's session. A dashed arrow labeled URL from get_ucp_profile links the tab to the MCP server

Bright Data Web MCP has a similar name, but it is a product, and WebMCP is a proposed web standard. Web MCP is an MCP server for web search, scraping, and browser automation on public web pages. An agent can use it together with a site’s WebMCP tools.

How many websites support WebMCP

Almost none of the top websites supported WebMCP in the scan. In Chrome with default settings, 1 of 544 top-ranked homepages registered tools.

The method. On October 31, 2026, the scan covered the top 1,000 domains on the Tranco list, a research ranking of popular sites. Each domain got its own Bright Data Browser API session, a hosted Chrome 155 or 156 with default settings, both inside the origin trial. Each homepage then had 5 seconds after the load event to register tools. So the scan detected the tools that a regular visitor’s Chrome would expose in that time.

The Tranco list also ranks CDN, API, and ad domains that serve no homepage. The scan counted the 544 domains whose homepage returned an HTTP status below 400.

The result. The one homepage with tools was wyzecam.com, a Shopify store with 12 tools. note.com enabled the API with its own origin trial token but registered no tools on its homepage.

Each square below is one of those 544 homepages, in Tranco rank order:

Waffle chart of 544 squares for top-ranked homepages checked in Chrome with default settings, with one blue square for wyzecam.com, which has tools, and one orange square for note.com, which has an origin trial token

Homepages can understate adoption, because a site may register tools only on search results or product pages. A check of search results pages on 11 large retail, travel, and job sites, including Amazon, Nike, and Tripadvisor, found no tools there either.

One platform can change the adoption numbers. In August 2026, Shopify enabled WebMCP for every Liquid storefront and for the Hydrogen developer preview. Liquid is the template language of Shopify themes, and Hydrogen is Shopify’s custom storefront framework. Stores on a Shopify theme got the tools without installing anything.

Of 10 well-known Shopify brand stores, the 6 on themes had the same 12 tools, and the 4 on custom storefronts had none. All 6 used one shared third-party origin trial token from cdn.shopify.com. Like every origin trial token, it expires, and if Shopify stops renewing it, agents have to scrape those stores instead. Because theme stores are the main sites with tools, the tests in this guide use them, mostly Allbirds.

Call WebMCP tools from your own agent

The script below uses Playwright 1.64’s page.webmcp in a Bright Data Browser API session. It calls a read-only search tool when the page offers one. On a page with no tools, it reads the accessibility snapshot, the view that many browser agents use.

You need Node.js 22 or later and a Browser API zone, the Bright Data configuration that stores your endpoint and credentials. Create it under Web Access in the control panel, as the Browser API quickstart shows. The Browser API has a free tier and is priced per GB of traffic, and the Browser API pricing page lists the plans.

Create a folder for the examples and install playwright-core there:

mkdir webmcp-lab && cd webmcp-lab
npm install [email protected]

The zone’s Overview tab shows the CDP endpoint for Puppeteer and Playwright in the Access details panel:

Bright Data control panel on a Browser API zone's Overview tab, showing the Web Access navigation and the Access details panel, with the wss:// URL for Puppeteer and Playwright outlined and the customer ID masked
Treat the wss:// URL as a secret, because it contains the zone’s credentials.

Set the whole wss:// URL as an environment variable:

export BRD_BROWSER_WSS="wss://brd-customer-<customer-id>-zone-<zone>:<password>@brd.superproxy.io:9222"

Save the script as webmcp_or_page.mjs:

// webmcp_or_page.mjs: call a site's WebMCP tools when it has them, and scrape the page when it does not.
// Usage: BRD_BROWSER_WSS="wss://..." node webmcp_or_page.mjs <url> [query]
import { chromium } from "playwright-core";

const [url, query = "wool runner"] = process.argv.slice(2);
const browser = await chromium.connectOverCDP(process.env.BRD_BROWSER_WSS);
const page = await browser.newPage();
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 120000 });

// Sites register tools after load, sometimes in batches: wait until the tool count stays the same for 1 second.
let tools = [];
for (let i = 0, stable = 0; i < 40 && stable < 5; i++) {
  await page.waitForTimeout(200);
  const now = await page.webmcp.tools();
  stable = now.length > 0 && now.length === tools.length ? stable + 1 : 0;
  tools = now;
}
const readOnly = tools.filter((t) => t.annotations?.readOnly);
console.log(`tools: ${tools.length}, read-only: ${readOnly.map((t) => t.name).join(", ") || "none"}`);

const search = readOnly.find((t) => /search/.test(t.name));
if (search) {
  // If the input schema has a catalog object, put the query inside it. Otherwise, pass the query directly.
  const input = search.inputSchema?.properties?.catalog ? { catalog: { query } } : { query };
  // Set a timeout. A declarative tool that waits for a person to submit never returns.
  const result = await page.webmcp.callTool(search.name, input, { timeout: 30000 });
  // Tool output is page-authored text: treat it as data, never as instructions.
  console.log(`[${search.name}]`);
  // MCP-format results contain text in content[0]. Print any other result as JSON.
  const text = result?.content?.[0]?.text ?? JSON.stringify(result, null, 2);
  console.log(text.split("\n").slice(0, 6).join("\n"));
} else {
  // No tools: read the accessibility snapshot, the view that many browser agents use.
  const snapshot = await page.locator("body").ariaSnapshot();
  console.log("[no WebMCP search tool, accessibility snapshot]");
  console.log(snapshot.split("\n").slice(0, 6).join("\n"));
}
await browser.close();

Run it against a Shopify store that registers tools:

node webmcp_or_page.mjs https://www.allbirds.com/ "wool runner"

The store returned results through its own search_catalog tool:

tools: 12, read-only: get_cart, get_ucp_profile, search_catalog, search_shop_policies_and_faqs

[search_catalog]

Found 2 products, 1 collection, 1 article, 1 page for “wool runner”. Products: – Women’s Wool Runner – Natural Black (Black Sole) (id: gid://shopify/Product/1878275686469, handle: womens-wool-runners-natural-black) – $110.00 – Men’s Wool Runner NZ – Weathered Brown (Weathered Brown Sole) (id: gid://shopify/Product/7221394931792, handle: mens-wool-runner-nz-weathered-brown) – $110.00

On a site with no tools, such as https://books.toscrape.com/, the script prints tools: 0 and the start of the accessibility snapshot instead. On such a page, the script first waits about 8 seconds for tools, and the check in the next section saves that wait.

To watch a session while your agent runs, open it in the Browser API debugger. Click Chrome DevTools Debugger on the zone’s Overview tab, or send the Page.inspect CDP command from your script. In the debugger’s Console, this one-line command lists the page’s tools and the read-only hints that the script filters on:

(await document.modelContext.getTools()).map(({ name, annotations }) => ({ name, readOnly: !!annotations?.readOnlyHint }))

On Allbirds, the command returned 12 tools:

Bright Data's hosted Chrome DevTools attached to a live Browser API session on allbirds.com. The Console lists 12 WebMCP tools from getTools(), with readOnly true for get_cart, get_ucp_profile, search_catalog, and search_shop_policies_and_faqs

A live Browser API session on allbirds.com, open in the debugger’s hosted DevTools. The store marked 4 of its 12 tools as read-only.

For production, the Browser API runs many sessions in parallel, with built-in proxies and unblocking. For local testing, replace the connectOverCDP() call with chromium.launch({ channel: "chrome", args: ["--enable-features=WebMCP"] }). That argument enables WebMCP for local testing, like the testing flag. Playwright also requires the argument to list tools in a browser that it launches.

Each site defines its own tool names and input schemas, so read inputSchema from the tool list before you build the call arguments. The read-only filter also skips get_product and browse_store, which the store did not mark as read-only, so add other tools that you need by name. And because the script calls tools directly, with no LLM in the loop, it can run as a scheduled job that uses no LLM tokens.

Check for tools before the full page load

The initial HTML document shows whether a page contains a WebMCP marker, so an agent can skip the wait for tools on pages without one. Every site with tools in the tests was a Shopify theme store, and these stores use a webmcp-<hash>.js registration script as the marker. Sites with their own token, such as note.com, serve it in an origin-trial meta tag or an Origin-Trial HTTP header. The hash changed during a week of testing, so the check below matches only the webmcp- prefix.

Save this check as webmcp_precheck.mjs. It loads only the HTML document and aborts every subresource request:

// webmcp_precheck.mjs: load only the HTML document and look for WebMCP markers before a full page load.
// Usage: BRD_BROWSER_WSS="wss://..." node webmcp_precheck.mjs <url>
import { chromium } from "playwright-core";

// Origin-trial tokens are base64: 1 version byte, a 64-byte signature, a 4-byte payload length, then a JSON payload that names the feature.
const isWebmcpToken = (token) => {
  try {
    const b = Buffer.from(token, "base64");
    return JSON.parse(b.subarray(69, 69 + b.readUInt32BE(65))).feature === "WebMCP";
  } catch { return false; }
};

const browser = await chromium.connectOverCDP(process.env.BRD_BROWSER_WSS);
const page = await browser.newPage();
// Allow only the HTML document request, and abort scripts, images, styles, and fonts.
await page.route("**/*", (r) => (r.request().resourceType() === "document" ? r.continue() : r.abort()));
const resp = await page.goto(process.argv[2], { waitUntil: "domcontentloaded", timeout: 90000 });
const html = await resp.text();

// Shopify registers its tools from a webmcp-<hash>.js script. Sites with their own token serve it in HTML or a header.
const metaTokens = [...html.matchAll(/<meta[^>]+origin-trial[^>]*>/gi)].map((m) => m[0].match(/content=["']([^"']+)/i)?.[1]);
const tokens = [...metaTokens, ...(resp.headers()["origin-trial"] ?? "").split(",")].filter(Boolean).map((t) => t.trim());
const found = /webmcp-[\w]+\.js/i.test(html) || tokens.some(isWebmcpToken);
console.log(found ? "WebMCP markers found: load the page and check for tools" : "No WebMCP markers: scrape the page instead");
await browser.close();

Run it before the main script:

node webmcp_precheck.mjs https://www.allbirds.com/

The check found the Shopify script on Allbirds:

WebMCP markers found: load the page and check for tools

The check is cheap. On Allbirds, it used 97 KB of traffic, about 2% of a full page load. When it finds no markers, skip the wait for tools and scrape the page with the Browser API or Bright Data Web MCP. Sites need a token only during the origin trial, so once browsers enable WebMCP by default, check the loaded page for tools instead.

The check reads only the initial HTML and its headers. If another platform’s script adds a token later, the check misses it, and the agent scrapes that page, which still returns its content.

The same check works on raw HTML from the Web Unlocker API, so an agent can decide whether a page needs a browser at all. On 13 test sites, some with tools and some without, it gave the same answer as a full browser check. Stores can rate-limit direct HTTP requests, and one test store did, but Web Unlocker still returned its HTML. So use Web Unlocker for stores that refuse direct requests.

Create a Web Unlocker zone under Web Access, as with the Browser API zone. The Web Unlocker API quickstart shows the request format. The zone’s Overview tab shows your API key and zone name. Set BRIGHT_DATA_API_KEY to the key, and replace web_unlocker with the zone name:

curl -s https://api.brightdata.com/request \
  -H "Authorization: Bearer $BRIGHT_DATA_API_KEY" -H "Content-Type: application/json" \
  -d '{"zone": "web_unlocker", "url": "https://www.allbirds.com/", "format": "raw"}' \
  | grep -o -m 1 'webmcp-[a-z0-9]*\.js'

For Allbirds, the command prints the name of Shopify’s registration script:

webmcp-54c687b6.js

What WebMCP tools return

WebMCP tools return what site owners choose to share, and the LLM token count depends on which parts of the result the agent keeps. For the Women’s Wool Runner in Natural Grey, the table compares the store’s get_product result with the product page, loaded in a Browser API session. The tool result had text content written for the model and a structuredContent object. Token counts use OpenAI’s o200k_base tokenizer:

What the agent reads Tokens
get_product text content 150
get_product full result, text content and structuredContent 1,090
Visible page text 1,033
Accessibility snapshot 4,293

The visible page text used about 7 times as many tokens as the text content alone. The full result, including structuredContent, was about the size of the visible page text. The accessibility snapshot that many browser agents read used about 4 times as many tokens as the full result.

On this page, a cookie consent banner hid the content from the accessibility snapshot, so the table uses the snapshot taken after rejecting the banner. The tools returned data in both cases. When your agent scrapes pages, the Browser API’s Unblocker.enableCookieBlock command stops banners from common consent management platforms (CMPs) before they load.

Apart from size, the 2 parts of the get_product result contained different data. The text content listed the $49.00 price and the only size in stock. The structuredContent object also contained a list_price of $110 and a list of internal product tags, and “FINAL SALE” appeared only in those tags.

For a shopping assistant, the text content is usually enough. For price monitoring, keep structuredContent, because it contains the list price. The sale status is in store-specific tags, so your code needs each store’s tag names. A Markdown scrape of the page with Bright Data Web MCP contained “$49 $110 (55% off)” and “Final Sale” as a shopper sees them.

When tool output differs from the page

The tool output and the rendered page can disagree. For the Women’s Wool Runner collection, the browse_store tool listed 3 products and the collection URL /collections/womens-wool-runners. That URL showed the store’s “Page Not Found” page.

So do not treat WebMCP output as a copy of what the page shows. If a pipeline needs what a shopper sees, scrape the rendered page in the same session and compare it with the tool output. Stores can localize prices and stock, so compare pages from the same country. The Browser API’s geolocation targeting sets the country for each session.

Security: what the agent should check

With WebMCP, a site can put its own text into an agent’s context window, so treat every tool description and output as untrusted input. Check these 4 details:

  • Annotations are self-declared by the site. On the Shopify theme stores tested, no tool set consequentialHint, not even add_to_cart or proceed_to_checkout. The add_to_cart description told the agent that the user’s request “IS the authorization” and not to ask for confirmation.
  • Chrome 156 forwards inputs without schema validation. If an agent sends an integer for a sku that the schema declares as a string, the tool receives the integer unchanged.
  • untrustedContentHint is optional. Any tool output can contain indirect prompt injection, whether or not the site sets this hint.
  • Tool text directs the agent. Shopify’s tool descriptions used instructions in capital letters, such as “do NOT”. The results of search_catalog, get_product, and browse_store each ended with “Next steps” that told the agent when to call add_to_cart.

In your own agent code, use a per-site allowlist of tools, and block the rest. Wrap each tool output in delimiters that contain a random nonce, so the page cannot spoof the closing delimiter and add instructions after it. Run the agent in a separate Browser API session, so its tool calls stay apart from the user’s logins and cart.

Call WebMCP tools from MCP clients

Claude Code, Cursor, and many agent frameworks are MCP clients. WebMCP tools exist only in an open page, so these clients reach them through a browser.

Playwright MCP, the browser MCP server from Microsoft, connects MCP clients to the browser. Since version 0.0.84, released on October 31, 2026, it exposes each WebMCP tool of the open page as an MCP tool named webmcp_<tool>. The feature is enabled by default.

When Playwright MCP connects to the Browser API with --cdp-endpoint, it exposes the page’s tools directly. On Allbirds, it exposed all 12 of the store’s tools. A Chrome that Playwright MCP starts locally needs the --enable-features=WebMCP argument. For the general setup, read our guide to the Playwright MCP server.

You also need Claude Code, installed and signed in. Save an MCP configuration as mcp-config.json. Claude Code expands ${BRD_BROWSER_WSS} from your environment variables, so the file never contains the password:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/[email protected]", "--cdp-endpoint", "${BRD_BROWSER_WSS}"]
    }
  }
}

A Playwright MCP session keeps the page open, so one page load is enough for every later tool call. Each call adds little traffic. On Allbirds, each search_catalog call added under 200 KB, and that figure includes the page’s own background network requests.

Limit the tools Claude Code can run

Playwright MCP exposes every tool, including add_to_cart and proceed_to_checkout. It passes each page’s readOnlyHint to the MCP tool and marks every other tool with MCP’s destructiveHint. The site sets the read-only hint, so enforce a tool allowlist in the client.

In Claude Code, --allowedTools lists the tools that run without a permission prompt. Use the default permission mode, so that other tools need approval unless a settings file allows them:

claude -p "Open https://www.allbirds.com/ with browser_navigate, then use the store's own WebMCP tools to find women's wool runners and the store's return policy. Answer in 3 short sentences with prices." \
  --mcp-config mcp-config.json --strict-mcp-config --permission-mode default \
  --allowedTools "mcp__playwright__browser_navigate,mcp__playwright__webmcp_search_catalog,mcp__playwright__webmcp_get_cart,mcp__playwright__webmcp_search_shop_policies_and_faqs,mcp__playwright__webmcp_get_ucp_profile"

Claude answered using the Allbirds tools:

Allbirds' Women's Wool Runners range from $49.00 (Natural Grey) to $110.00 (Natural Black and the Wool Runner NZ Natural Black), all available in sizes 5–11. Returns are accepted within 30 days of delivery for unworn, unwashed items with tags attached, with the customer covering return shipping unless they opted into paid return coverage at checkout. Refunds go back to the original payment method, and final-sale items aren't eligible for return.

To answer, Claude used the 2 read-only tools it needed, webmcp_search_catalog and webmcp_search_shop_policies_and_faqs. Claude’s answer listed sizes 5 to 11 for all pairs, but the earlier get_product result showed only size 5 in stock for the $49 pair. In a second test, run in an interactive session, Claude had to add the cheapest pair in size 8 to the cart. After a search, Claude called webmcp_get_product, which was not in --allowedTools, so Claude Code stopped and showed a permission prompt:

Claude Code terminal: Claude finds the cheapest women's wool runner with the store's search tool, then calls get_product. Playwright MCP marks the tool description as UNTRUSTED, and Claude Code asks whether to proceed

The run pauses at the first tool outside --allowedTools.

Playwright MCP labels each result as page-provided and untrusted. It serializes the whole tool result as JSON text, so the model also receives the structuredContent object, with fields such as the list price. And because the agent shops in the remote Browser API session, it uses its own cart and leaves the user’s cart unchanged.

Use playwright-cli for coding agents

Playwright also provides playwright-cli, and its docs recommend it for coding agents, because CLI commands send no large tool schemas. That matters most for agents that load every tool schema at startup. Claude Code loads MCP tool schemas only when it needs them, so Playwright MCP works well there. Install playwright-cli with npm install -g @playwright/[email protected].

Run playwright-cli attach --cdp="$BRD_BROWSER_WSS" yourself before you start the agent, so the session URL and its credentials never enter the model’s context. The agent lists and calls store tools with webmcp-list and webmcp-call. Allow only the commands it needs, such as Bash(playwright-cli webmcp-call search_catalog:*). Do not add broader Bash allow rules to any settings file, so that add_to_cart still needs approval.

When to use WebMCP tools, MCP servers, or scraping

For an agent that works across many sites, 3 parts of WebMCP’s design affect where its tools are useful:

  1. Tools appear only after the agent loads a page in a WebMCP-enabled browser.
  2. Each site defines its own tool names and input schemas.
  3. The API depends on origin trial tokens until browsers enable it by default.

On Shopify, choose the route that fits your task:

  • Bulk catalog data. A direct HTTP request to /products.json, the endpoint used for scraping Shopify stores with Python, returned the catalog as JSON on all 3 stores checked. For the Women’s Wool Runner in Natural Grey, the product’s .json URL also contained all 7 sizes and the $110 list price. The get_product tool’s text content listed only the sale price and the one size in stock. Stores can rate-limit direct requests, so route high-volume requests through the Web Unlocker API.
  • A commerce agent with a UCP profile. The store’s UCP MCP server listed its tools over HTTP, from catalog search to checkout. Each tool call had to include the URL of a UCP profile that the agent publishes, so this route fits commerce agents, not data collection.
  • An assistant in the shopper’s tab. Use the WebMCP tools, which act in the shopper’s own browser session.

An agent that works across the open web can combine 2 paths. It calls WebMCP tools where they exist and scrapes the other pages. In Claude Code, for example, add both servers. Playwright MCP covers the tools path, and you can connect Claude Code to Web MCP for the scraping path.

Both paths start by loading the page, so when a site’s bot detection blocks automated browsers, the agent gets neither its tools nor its content. A tool call itself is visible to the site, because each call runs the site’s own code and fires a toolactivated event on the page. Bright Data’s built-in unblocking, in the Browser API and in Web MCP, is designed for the page load, the first step on both paths.

Bright Data Web MCP provides the scraping path as MCP tools for search, scraping, structured data, and unblocking, with a monthly free tier. The Web MCP remote quickstart lists the remote MCP server URL. Web MCP’s browser tools use the same Bright Data Browser API as the webmcp_or_page.mjs script, so the client needs only an MCP connection. On pages with tools, Web MCP also shows what a shopper sees, such as the “Final Sale” label, which get_product returned only in internal tags.

Final thoughts

WebMCP is an in-page tool API that Chrome and Edge test in origin trials, while WebKit opposes it and Mozilla is neutral. MCP servers run their tools in a server process instead, and Bright Data Web MCP, despite its similar name, is one of them. Playwright MCP on the Browser API calls a site’s tools over CDP, and a tool result can use fewer LLM tokens than an accessibility snapshot. The site writes the tool text, so allow only the tools your agent needs and compare results with the rendered page when accuracy matters. Nearly all top homepages in the scan had no tools, so connect your agent to Bright Data Web MCP to scrape them.

FAQ

How do I enable WebMCP in Chrome?

Open chrome://flags/#enable-webmcp-testing, set the flag to Enabled, and relaunch Chrome. The flag enables WebMCP on every site, so it is meant for local testing. During the origin trial, Chrome with default settings enables WebMCP only on sites with a valid token, such as Shopify theme stores.

What is the WebMCP specification?

The WebMCP specification is a Draft Community Group Report of the W3C Web Machine Learning Community Group, edited by Google and Microsoft engineers. The spec defines document.modelContext with registerTool(), getTools(), and executeTool(). It is not a W3C standard, and its API changed several times in 2026.

How do you implement WebMCP on a website?

Call document.modelContext.registerTool() with a name, a description, a JSON Schema for the tool’s input, and an execute() function that reuses page code. Set annotations such as readOnlyHint to describe each tool. During the origin trial, register your origin to get a token, and serve it on pages with tools.

Does WebMCP work with ChatGPT?

Yes, in the ChatGPT desktop app. OpenAI’s site tools are its WebMCP implementation, and ChatGPT Work and Codex use them in the app’s built-in browser. OpenAI’s docs say that tool definitions and results from websites are untrusted content, and that a read-only claim does not prove what a tool does.

What is the WebMCP Inspector extension?

The Model Context Tool Inspector is a Chrome extension that lists the WebMCP tools on the current page. It runs tools manually, or through Gemini with your own API key. It needs the WebMCP testing flag in chrome://flags. Chrome DevTools also has a built-in WebMCP pane that lists the tools and logs each call.

What is the difference between WebMCP and MCP?

MCP connects an AI agent to tools on a server, over stdio or Streamable HTTP. WebMCP tools run as JavaScript in an open web page and use the visitor’s browser session, so they exist only while the page is open. MCP clients, such as Claude Code, can call WebMCP tools through a browser with Playwright MCP.

Does WebMCP replace web scraping?

No, not on most websites. In Chrome with default settings, 1 of 544 top-ranked homepages registered tools, and a tool returns only what the site owner chooses to share. The other pages still need scraping. Bright Data Web MCP scrapes those pages, and Playwright on the Browser API invokes tools where they exist.

No credit card required
Satyam Tripathi

Technical Writer

5 years experience

Satyam Tripathi helps SaaS and data startups turn complex tech into actionable content, boosting developer adoption and user understanding.

Expertise
Python Developer Education Technical Writing