DEV Community

Manu Shukla
Manu Shukla

Posted on • Originally published at ecorpit.com

WebMCP in Chrome 149: build agent tools without DOM scraping

WebMCP in Chrome 149: build agent tools without DOM scraping

Summary. Chrome opened the WebMCP origin trial from Chrome 149, which reached stable on 2 June 2026, and Google last revised the WebMCP documentation on 7 August 2026. WebMCP lets a page register named tools with a JSON Schema so a browser agent calls checkout or filter_results directly instead of simulating clicks. The commercial pressure behind it is measurable: Adobe Analytics recorded a 393% year-over-year rise in AI-sourced traffic to US retail sites in the first quarter of 2026, off a holiday season that drove a record $257.8 billion in US online spend with AI traffic up 693.4%. Adobe also scored the average US retail homepage at 75% machine readability and product pages at 66%, so a third of the content agents need on a product page is not reachable. One API change matters immediately: navigator.modelContext is deprecated in Chrome 150, and document.modelContext is the interface to write against.

What WebMCP actually changes

Today a browser agent completes a task by actuation. Google's own definition is blunt: actuation is "the act of an agent simulating manual mouse clicks and text input, as though it were the human user engaging with your website." Every step in that chain is a guess. The agent reads the DOM, decides that the button labelled "Continue" is the one that advances checkout, and hopes the label did not change in last week's release.

WebMCP inverts that. The page declares what it can do. Google's documentation lists three things the API standardises: discovery, so a page registers tools such as checkout or filter_results; JSON Schemas, so inputs and outputs are explicit rather than inferred; and state, so the agent knows what resources exist on the page right now.

The practical consequence for an engineering team is that agent compatibility stops being a design problem. Google puts it directly: WebMCP tools "connect to application logic, not design," so a redesign does not break an agent's ability to act. That is the difference between a capability you maintain once and a surface that breaks every sprint.

Two limits are worth internalising before anyone opens a ticket. WebMCP tools are ephemeral: they exist only while the page is open, and once the user navigates away or closes the tab, the agent cannot act. And discovery is visit-based. Google's own limitations list says clients and browsers "must visit a site directly to know if it has callable tools." There is no registry that advertises your tools to the wider agent ecosystem.

Why this is showing up in commerce first

The numbers behind agent traffic are no longer speculative. Adobe Analytics, which covers over 1 trillion visits to US retail sites, 100 million SKUs and 18 product categories, reported that traffic to US retail sites from generative AI sources grew 393% year over year across January to March 2026, and 269% year over year in March 2026 alone. That followed the 2025 holiday season, where AI-sourced traffic rose 693.4% against the prior year and consumers spent $257.8 billion online between 1 November and 31 December 2025, up 6.8%.

The conversion picture flipped inside twelve months. In March 2025, AI traffic converted 38% worse than non-AI traffic. By March 2026 it converted 42% better, a record in Adobe's series. Engagement rate ran 12% higher than non-AI traffic, time on site 48% longer, and pages per visit 13% higher.

"This 2025 holiday season, consumers embraced generative AI more than ever as a shopping assistant in their purchasing decisions," said Vivek Pandya, lead analyst, Adobe Digital Insights, in Adobe's 7 January 2026 season recap.

Adobe then measured whether retail sites are actually readable by machines, scoring pages out of 100%. US retail homepages averaged 75%, category pages 74%, and individual product pages 66%. The spread between brands is wider than the average suggests: 82.5% for the best-performing homepages against 54.2% for the lowest. Store locator pages scored 73% and customer service pages 79%.

Machine readability and WebMCP are not the same problem, and conflating them wastes budget. Readability governs what an LLM can extract from your page. WebMCP governs what an agent can reliably do on it. A product page can be perfectly legible and still leave an agent unable to add to cart without three guessed clicks.

The imperative API, with working code

The imperative API is standard JavaScript. Register a tool with a name, a description, an input schema, and an execute function.

await document.modelContext.registerTool({
  name: 'get_order_status',
  description: 'Search orders in a given timeframe. Returns order number, shipping status and location',
  inputSchema: {
    type: 'object',
    properties: {
      timeframe: {
        type: 'string',
        enum: ['today', 'yesterday', 'last_7_days', 'last_30_days', 'last_6_months'],
        description: 'Timeframe for the order lookup.'
      }
    },
    required: ['timeframe']
  },
  execute: async ({ timeframe }) => {
    // Call your API or database and return the order data as a string.
  },
});
Enter fullscreen mode Exit fullscreen mode

Tools are removable. Pass an AbortSignal at registration and abort the controller to unregister, which maps cleanly onto a single-page app where a tool should only exist on one route.

const controller = new AbortController();
await document.modelContext.registerTool(addTodoTool, { signal: controller.signal });

// Unregister the tool later.
controller.abort();
Enter fullscreen mode Exit fullscreen mode

Two annotations belong on almost every tool you write. readOnlyHint tells the agent the tool does not change state, which lets it decide when a user confirmation is needed. untrustedContentHint labels a payload as untrusted, and Google recommends it whenever a tool returns user-generated or externally sourced data.

annotations: {
  readOnlyHint: false,
  untrustedContentHint: true
}
Enter fullscreen mode Exit fullscreen mode

Discovery and manual execution are available to your own code too. document.modelContext.getTools() returns an alphabetically ordered list of tools the calling document is authorised to see, and document.modelContext.executeTool() runs one with arguments passed as a valid JSON string. A toolchange event fires on document.modelContext when the available tool list changes, which is the hook to use if you are building your own in-page agent surface rather than waiting for the browser's.

React and Angular both have experimental support. React uses the usewebmcp package, which registers tools through hooks tied to component mount and unmount and adds schema-driven type inference. Angular ties registration to the dependency injection lifecycle and can turn Signal Forms into WebMCP tools, which pairs with the work covered in our guide to Angular 21 zoneless signal forms.

The declarative API, with working code

If the action you want to expose is already an HTML form, you do not need JavaScript. Add two attributes to the <form> element and the browser builds the tool for you.

<form toolname="supportRequestTool"
  tooldescription="Submit a request for support."
  action="/submit">

  <label for="firstName">First Name</label>
  <input type=text name=firstName>

  <select name="select" required
    toolparamdescription="Determines what team this request is routed to.">
    <option value="Customer happiness team">Return my purchase.</option>
    <option value="Distribution team">Check where my package is.</option>
  </select>

  <button type=submit>Submit</button>
</form>
Enter fullscreen mode Exit fullscreen mode

The browser converts the fields into a JSON Schema. Field names become properties, required becomes a required entry, and <select> options become both an anyOf list with titles and a flat enum. Where a field needs a clearer description than its label gives, toolparamdescription overrides it; without that attribute the browser falls back to the associated <label>, then to aria-description. Remove either toolname or tooldescription and the tool unregisters.

Submission is where the declarative API earns its keep. By default the agent fills the form and the user clicks Submit, which keeps a human in the loop by construction. Add toolautosubmit and the model's invocation triggers submission and navigation directly.

<form toolautosubmit toolname="search_tool"
  tooldescription="Search the web" action="/search">
  <input type=text name=query>
</form>
<script>
  document.querySelector("form").addEventListener("submit", (e) => {
    e.preventDefault();
    if (!myFormIsValid()) {
      if (e.agentInvoked) { e.respondWith(myFormValidationErrorPromise) };
      return;
    }
    if (e.agentInvoked) { e.respondWith(Promise.resolve("Search is done!")); }
  });
</script>
Enter fullscreen mode Exit fullscreen mode

Three additions to the platform make this workable. SubmitEvent.agentInvoked is a boolean that is true when an agent triggered the form, so you can branch behaviour. SubmitEvent.respondWith(Promise) passes a promise whose resolved value is serialised back to the model as the tool's output, and it requires preventDefault() first. The toolactivated and toolcancel events fire on the window when fields are pre-filled and when the user cancels or the form resets; both are non-cancelable and carry a toolName.

Chrome also ships focus pseudo-classes so users can see what the agent touched: :tool-form-active on the form and :tool-submit-active on the submit button, with a default dashed outline you can restyle.

Choosing between the two APIs

Decision point Imperative API Declarative API
What you write JavaScript calling document.modelContext.registerTool toolname and tooldescription attributes on an existing <form>
Best fit Navigation, state changes, data lookups, anything without a form Search, support requests, bookings, any flow that already posts a form
Schema authoring You write the JSON Schema by hand The browser derives it from field names, required and <select> options
Human in the loop You decide, using readOnlyHint and confirmation Default is manual submit; toolautosubmit opts out
Result returned to the model Return value of execute respondWith(Promise) after preventDefault()
Cross-origin sharing Supported through exposedTo and fromOrigins Not applicable
Framework support React usewebmcp, Angular Signal Forms Plain HTML, no framework needed

The order that works in practice: annotate the forms you already have, ship, measure, then write imperative tools for the flows that have no form. Most teams find the declarative pass covers search, support and lead capture in a day, and that is the part of the funnel agents reach first.

WebMCP is not a replacement for MCP

Google's guidance is explicit that this is a false choice, and the confusion is common enough that the Chrome team wrote a page about it. WebMCP is not an extension or a replacement of the Model Context Protocol. The two operate at different layers.

Dimension MCP WebMCP
Purpose Makes data and actions available to agents anywhere, anytime Makes a live website ready for agent interaction when a user visits
Lifecycle Persistent, server and daemon Ephemeral, tab-bound
Connectivity Global: desktop, mobile, cloud, web Environment-specific: browser agents
UI interaction Headless and external Browser-integrated and DOM-aware
Discovery Agent-specific registration flows Tools registered on the page during the visit
Use case Background API actions Navigates and actuates on a live web UI

Google frames the difference as ownership of the interface. With MCP apps, your UI renders inside the agent's UI and must conform to it. With WebMCP, the agent is a guest on your platform, working against live session data, cookies and DOM elements that only exist in an open tab. WebMCP also omits server-side MCP concepts such as resources, which is why the Chrome team calls it a set of MCP-inspired APIs rather than a JavaScript port of MCP.

The architecture that follows is straightforward. Core business logic and data retrieval belong in an MCP server so the capability is platform-agnostic and always reachable; WebMCP is the last mile that lets a browser agent act inside the user's session. Teams weighing that split against agent-to-agent designs will find the trade-offs in our MCP vs A2A enterprise agent protocol decision breakdown, and the server-side hardening work in the MCP server hardening guide.

The permissions model will block you before your code does

Two gates sit in front of every WebMCP call, and both fail quietly if you have not read them.

Origin isolation comes first. WebMCP is only available in origin-isolated documents, which keeps the document's origin stable for the lifetime of a tool. If the document has document.domain enabled, for example by sending the Origin-Agent-Cluster: ?0 header, the WebMCP APIs are disabled outright. Legacy applications that still rely on document.domain for cross-subdomain scripting have to retire that dependency before any of this works.

The tools permissions policy comes second. It defaults to self, which allows registration in top-level and same-origin contexts and disables it for cross-origin iframes. A cross-origin iframe needs explicit delegation:

<iframe src="https://example.com" allow="tools"></iframe>
Enter fullscreen mode Exit fullscreen mode

Cross-origin exposure is a separate switch again, and it is two-sided by design. The hosting origin lists who may see a tool through exposedTo at registration; the consuming origin must still ask for it by listing the host in fromOrigins on getTools(). Both arrays accept secure origins only.

// On https://partner.org
await document.modelContext.registerTool({
  name: 'my_shared_tool',
  description: 'Shared across origins',
}, {
  exposedTo: ['https://trusted.com', 'https://example.com']
});

// On https://example.com
const allTools = await document.modelContext.getTools({
  fromOrigins: ['https://partner.org']
});
Enter fullscreen mode Exit fullscreen mode

Treat exposedTo as a data-sharing decision, not a configuration detail. Google's example is the right mental model: a read-only tool such as getFavoriteProducts reveals user information, so expose it only to sites you would share that data with anyway, and a write tool such as postComment acts on the user's behalf, so the bar is higher again. One more thing to know: Chrome extensions can query and execute WebMCP tools using content scripts, and with host_permission they can already run custom JavaScript on the page regardless.

Prompt injection is the risk you actually own

Google's security page does not soften this. Because LLMs treat text, instructions and user data as one token sequence, they are open to indirect prompt injection, and the Chrome team states plainly that it is impossible to guarantee safety inside a model because models are probabilistic. Google's own bug hunters have documented repeatable prompt injection attacks against agentic systems built on current models, and Google reports that the prevalence of attacks on the web is rising.

That places the burden on tool design. Mark anything returning user-generated or third-party content with untrustedContentHint. Mark genuinely read-only tools with readOnlyHint so the agent can reserve confirmation prompts for actions that change state. Keep sensitive operations behind a user confirmation; the spec draft includes requestUserInteraction() for asynchronously requesting user input during tool execution, and consent management across parties is still an open discussion in the WebMCP repository.

Google also publishes character budgets, which exist to keep tool definitions inside agent guardrails rather than to save bytes.

Element Recommended budget Why it matters
Tool description 500 characters Longer descriptions get truncated or ignored by agent guardrails
Parameter description 150 characters Keeps each argument unambiguous without bloating the schema
Tool name 30 characters Names are matched by the model, so short and literal wins
Parameter name 30 characters Same matching problem, one level down
Individual tool output 1.5K characters Large payloads crowd the agent's context and slow the turn

Google notes these limits vary across agents and may end up in the specification later, so treat them as a starting budget to tune with real feedback rather than a fixed contract. The teams building browser-agent policy on the other side of this will recognise the same tension covered in our agentic browser enterprise data security controls guide, and the injection guardrail patterns in the AI agent security and prompt injection guardrails playbook.

How to test before you ship

Local development does not need the origin trial. Set chrome://flags/#enable-webmcp-testing to Enabled and relaunch Chrome, and the APIs are available on localhost.

For live testing, register for the origin trial through the Chrome origin trials console and add the token to the pages that register tools. Origin trials are time-limited and may carry usage limits, so treat the token as an expiring dependency in your deployment checklist rather than a permanent flag. Chrome's shorter release cadence makes that worth automating; the mechanics are in our Chrome two-week release cycle web QA playbook.

For behavioural testing, install the Model Context Tool Inspector extension from the Chrome Web Store. It shows which tools are registered on a page, calls them manually, validates that the browser parses your JSON Schema as intended, and displays the structured output or error the tool returned. Its natural-language prompts are sent by default to the gemini-3-flash-preview model, and Google notes it is separate from the Gemini in Chrome features.

Google ships three reference demos: a pizza maker and a React flight search using the imperative API, and a French bistro demo using the declarative API, all in the GoogleChromeLabs/webmcp-tools repository. The page agent demo is the one to read if you need to retrieve tools from an iframe and execute them inside your own chat interface.

The API surface is still moving. The clearest evidence is the interface rename: navigator.modelContext is deprecated in Chrome 150 in favour of document.modelContext. Anything written against the older path during the trial needs updating, and it is a one-line change that will silently stop working if you miss it.

India-specific considerations

For Indian D2C and marketplace teams, the sequencing argument is different from the US one. Agent-sourced traffic is a smaller share of Indian sessions than Adobe's US retail figures suggest, so the case for WebMCP is not a traffic case yet. It is a build-order case. Declarative annotations on forms you already ship cost a sprint at most; imperative tools for checkout do not, and checkout is where the regulatory questions start.

Any tool that returns order history, saved addresses or payment instruments is processing personal data under the Digital Personal Data Protection Act 2023, and an agent invoking it is a new processing context to account for in your notice and consent design. The conservative default is to mark those tools readOnlyHint: true, never set toolautosubmit on a payment step, and keep the confirmation in your UI where the user can see it. WebMCP's ephemerality helps here: the tool exists only while the tab is open, so there is no persistent agent-facing endpoint to secure separately, unlike an MCP server.

Payment flows deserve a hard line. The declarative default, where the agent fills the form and the human presses Submit, is the correct behaviour for anything that moves money, and it happens to match how additional factor authentication already works in Indian payment journeys. Teams mapping this against the wider agentic checkout standards will find that ground covered in our agentic commerce standards guide for merchants and the demand-side view in AI shopping agents and D2C agentic commerce.

The wider platform context, including how origin trials and interoperability targets shape what you can rely on in 2026, sits in our Interop 2026 web platform developer guide.

A rollout order that does not waste a sprint

Start with an inventory rather than code. List the tasks a user completes on your site, mark which already exist as an HTML form, and mark which of those a competent agent would attempt on a user's behalf. Search, support request, booking, filter, order lookup and account update are the usual six.

Annotate the forms first, because the declarative path needs two attributes and no schema authoring. Confirm each derived schema in the Tool Inspector before moving on; a <select> with vague option text produces a vague enum, and that is a content fix, not an engineering one.

Then write imperative tools only for flows without a form, and keep the first batch read-only. A read-only get_order_status tool tells you whether agents find and call your tools at all, and it carries none of the risk of a write tool. Once the call volume is real, add write tools with confirmation and the annotation hints in place.

Audit document.domain usage before any of this, because origin isolation is a hard gate. If an application still sets it, WebMCP will not run there no matter how correct the tool code is.

The real cost here is usually the schema and the copy, not the JavaScript. Getting a tool description under 500 characters that is still unambiguous is a writing problem, and it is the part that decides whether an agent picks your tool or falls back to clicking around.

How eCorpIT can help

eCorpIT builds and instruments agent-facing web surfaces for ecommerce, SaaS and marketplace teams, covering the form annotation pass, imperative tool design, origin-isolation remediation and the security review that has to sit alongside them. Our senior engineering teams work to CMMI Level 5 process discipline and ISO 27001:2022 controls, and we design applications aligned with DPDP requirements where personal data is in scope. If you want a scoped assessment of which flows on your site are worth exposing as tools during the origin trial, contact us.

FAQ

What is WebMCP and how is it different from MCP?

WebMCP is a proposed browser standard that lets a web page register structured tools for browser agents. MCP is a server-side protocol that exposes data and actions to any agent, anywhere. Google states WebMCP is not a replacement for MCP; MCP is persistent and platform-agnostic, while WebMCP is ephemeral and tab-bound.

Which Chrome version do I need for the WebMCP origin trial?

The WebMCP origin trial is available from Chrome 149, which reached stable on 2 June 2026. For local development you do not need the trial token at all: enable the flag at chrome://flags/#enable-webmcp-testing and relaunch Chrome. Origin trials are time-limited and may carry usage limits during the trial period.

Should I use the imperative or the declarative API?

Use the declarative API when the action already exists as an HTML form, because two attributes on the form element are enough and the browser derives the JSON Schema. Use the imperative API for navigation, state changes and data lookups that have no form, where you write the schema and an execute function yourself.

Does WebMCP work inside cross-origin iframes?

Not by default. Tool registration is disabled in cross-origin iframes because the tools permissions policy defaults to self. The embedding page must delegate access with an allow="tools" attribute on the iframe. Separately, tools are hidden from cross-origin documents unless listed in exposedTo and requested through fromOrigins.

What breaks WebMCP on an existing application?

Origin isolation is the common blocker. WebMCP only runs in origin-isolated documents, so a page that enables document.domain, for example by sending the Origin-Agent-Cluster: ?0 header, has the APIs disabled entirely. Legacy cross-subdomain scripting that depends on document.domain has to be retired before tools can register.

How do I stop an agent from submitting a payment without the user?

Keep the declarative default, where the agent fills the form and the user clicks Submit, and do not add toolautosubmit to a payment step. Mark read-only tools with readOnlyHint so the agent reserves confirmations for state changes. The spec draft also includes requestUserInteraction() for requesting input during execution.

How long should a WebMCP tool description be?

Google recommends 500 characters per tool description, 150 per parameter description, 30 characters each for tool and parameter names, and a 1.5K character limit per individual tool output. These budgets keep definitions inside agent guardrails. Google notes the limits vary between agents and may later be added to the specification.

Is agent traffic large enough to justify this work?

Adobe Analytics recorded a 393% year-over-year increase in AI-sourced traffic to US retail sites in the first quarter of 2026, and that traffic converted 42% better than non-AI traffic in March 2026. Adobe also scored average US retail product pages at 66% machine readability, so the underlying gap is wide.

References

  1. WebMCP: Chrome for Developers documentation
  2. WebMCP Imperative API: Chrome for Developers
  3. WebMCP Declarative API: Chrome for Developers
  4. WebMCP tool security: Chrome for Developers
  5. When to use WebMCP and MCP: Chrome for Developers
  6. Chrome 149 release notes: stable 2 June 2026
  7. WebMCP explainer on GitHub
  8. WebMCP Chrome Status entry
  9. Adobe: US retailers see surge in AI traffic, but many websites are not entirely readable by machines (16 April 2026)
  10. Adobe: Holiday shopping season drove a record $257.8 billion online (7 January 2026)
  11. Google Bug Hunters: task injection and the agency of autonomous AI agents
  12. Google Security Blog: prompt injections on the web
  13. All the news from the Google I/O 2026 developer keynote
  14. WebMCP demos: GoogleChromeLabs/webmcp-tools
  15. Angular: experimental WebMCP support

Last updated: 14 August 2026.

Top comments (0)