28 Jul 2026
7 min

From DOM Scraping to Contracts: Understanding WebMCP (Part 1)

<!– Status of knowledge: July 2026. WebMCP is a moving target. Verify API names against the spec and Chrome docs before publication. –>

WebMCP is a proposed web standard that lets a web page expose its functionality to AI agents as structured, schema-typed tools, instead of forcing agents to reverse-engineer the user interface. The proposal is incubated in the W3C Web Machine Learning Community Group, with engineers from Google and Microsoft among its editors, and it consolidates several earlier efforts in the same direction, including Microsoft’s “Web Model Context” explainer, Chrome’s “script tools” prototype, and the open-source MCP-B project.

Before we go any further, two disclaimers that frame everything in this series. First, WebMCP is not a finished web standard. It is an experimental W3C Community Group draft, currently in a Chrome origin trial, and its API surface is still actively changing. Second, Angular is the first major framework to ship built-in support for it, but that support is explicitly experimental rather than a stable feature: the APIs carry Experimental in their names and may break outside a major release. Everything in this series should be read through that lens. This is a technology to understand and prototype with, not one to build production commitments on today.

This is the first of two articles. In this part we cover what WebMCP actually is, what it deliberately is not, and how the API works at a conceptual level. In part two we look at Angular’s experimental support, the security model that comes with it, and an honest assessment of adoption.

The interface gap

Today’s browser agents interact with websites the way a translator interprets a language they half-know. The agent inspects the page using DOM dumps, accessibility trees, screenshots, or combinations of them, feeds that representation to a large model, then guesses which element is the “Checkout” button, synthesizes a click, waits, re-inspects, and repeats. Tools like Playwright MCP (which primarily works from accessibility snapshots), browser-use, and the various “computer use” agents all work some variant of this loop.

It works, barely, and it fails in three predictable ways:

Latency. Every step is a round trip through a large model, often a multimodal one.

Cost. Images and raw DOM dumps are token-expensive relative to the tiny amount of signal they carry (“there is a search field here”).

Non-determinism. The agent is inferring intent from presentation. A CSS refactor, a delayed ad load, or an A/B test variant can break the whole chain. Failure rates compound across multi-step tasks.

This is not a controversial diagnosis. The W3C explainer itself motivates WebMCP with exactly these problems: representations built from raw DOM content and screenshots are expensive to process and brittle to interpret, and structured, page-declared capabilities are the proposed answer. The promise is not that agents become smarter, but that they stop paying a translation tax on every single action.

What WebMCP is, and three things it isn’t

WebMCP lets a web page expose its functionality (JavaScript functions or plain HTML forms) as tools: named, described, schema-typed actions that an in-browser AI agent can discover and call directly. The conceptual move is an inversion of control. Instead of the agent reverse-engineering what your page can do, the page declares it: “here are my capabilities, here are the parameters each one takes, here is what I return.”

Before going further, three clarifications that will save you from building the wrong mental model:

1. WebMCP is not MCP. Despite the name, it does not implement the MCP wire protocol. There is no JSON-RPC, no client-server transport, and no plans for MCP’s resources or prompts. Only the tools concept survives. Early proposals explored porting the full MCP protocol into the browser; the group deliberately went another way, because MCP has no native notion of web primitives like origins, browser permissions, or tab lifecycle. What WebMCP shares with MCP is the vocabulary and mental model: tools with names, descriptions, and JSON Schemas. A WebMCP-enabled page is analogous to an MCP server. The page becomes a “server” that exists exactly as long as the tab does.

2. WebMCP is not for headless or fully autonomous agents. This is stated as an explicit non-goal in the spec. The design is human-in-the-loop by construction: the human’s UI remains primary, agent tools augment it, and sensitive actions are expected to route through user confirmation. If your use case is unattended background automation, you are looking at the wrong layer.

3. WebMCP does not replace backend MCP. They are complementary. A flight-booking site might expose WebMCP tools so the agent in the user’s browser can drive the search flow inside the user’s session, while also running a classic MCP server so Claude or ChatGPT can hit its API server-side. Different consumers, different trust models.

So why not just tell everyone to build backend MCP servers? The spec’s explainer names three problems with the backend-only approach, and they are worth internalizing because they are the entire justification for WebMCP existing:

  • UI disintermediation. A backend agent bypasses your interface entirely. The user loses visibility and control; you lose the shared screen where a human can watch, correct, and confirm what the agent is doing.
  • State and auth replication. A backend MCP server lives outside the user’s browser session. It needs its own authentication and its own copy of state, including the cart the user half-filled by hand before invoking the agent.
  • Developer burden. You have to build and operate a separate backend surface. With WebMCP, the same client-side functions that already power your components can be surfaced to agents directly.

That last point is also the honest catch: the economic argument assumes your frontend logic is callable. If your business logic is welded into event handlers, extracting it into clean functions is the real migration cost, though that refactor improves your codebase whether or not agents ever show up.

How it works: contracts, not clicks

WebMCP defines two API surfaces. What follows is a conceptual tour, not a tutorial. The exact shapes are still shifting, which is itself part of the story.

The imperative API

A page registers a tool with a name, a model-readable description, a JSON Schema for inputs, and an execute callback. Adapted from the official explainer:

const controller = new AbortController();

await document.modelContext.registerTool({
  name: 'add-todo',
  description: "Add a new item to the user's active todo list",
  inputSchema: {
    type: 'object',
    properties: {
      text: { type: 'string' },
    },
    required: ['text'],
  },
  async execute({ text }) {
    await addTodoItemToCollection(text);
    return { content: [{ type: 'text', text: `Added: "${text}"` }] };
  },
}, { signal: controller.signal });

If you have ever written an MCP server, every field is familiar. That is deliberate. Two details are worth pausing on.

First, unregistration happens via AbortSignal, the same idiom as fetch and event listeners. This is a small thing, but it signals that WebMCP is being designed as a web platform API, not a protocol port. SPAs are expected to register and tear down tools as views change: checkout tools exist only while the checkout view does.

Second, and this is a detail many early tutorials already get wrong: the namespace has changed twice. The proposal’s earliest drafts used window.agent; Chrome shipped the API as navigator.modelContext, and Chrome’s official documentation now states plainly that navigator.modelContext is deprecated as of Chrome 150 in favor of document.modelContext. Same API, migrating namespace, three names in under a year. Treat this as your calibration for how early this spec is.

The declarative API

For static sites and classic forms, no JavaScript is required. Annotate a form and the browser deterministically compiles it into a tool, deriving the input schema from the form controls:

<form toolname="book_table"
      tooldescription="Reserve a table at the restaurant"
      toolautosubmit>
  <input name="date" type="date"
         toolparamdescription="Reservation date" />
  <input name="partySize" type="number"
         toolparamdescription="Number of guests" />
  <button type="submit">Book</button>
</form>

A few details here that almost no coverage mentions:

  • toolautosubmit is opt-in. Without it, the agent fills the fields and the browser focuses the submit button; a human has to actually click. Human-in-the-loop, encoded in an HTML attribute.
  • The current draft proposes CSS pseudo-classes, :tool-form-active and :tool-submit-active, that would let you style the form while an agent is filling it and when it is awaiting human review. Agent activity becomes a visible UI state. These remain part of an evolving specification, not universally implemented functionality.
  • SubmitEvent grows an agentInvoked property and a respondWith() method, so your submit handler can distinguish agent-driven submissions and return a structured result (or a validation error) to the agent without navigating the page. This closes the loop: the agent learns whether the action actually succeeded and can plan its next step.
  • For form submissions that do navigate cross-document, the response channel is still an open question. One proposal on the table is to treat the first <script type=”application/ld+json”> block on the destination page as the tool response. If you have spent years adding schema.org markup for SEO, that idea should feel poetic.

The cross-origin model

Tool registration is disabled by default in cross-origin iframes; an embedding page must delegate it explicitly via the tools Permissions Policy (<iframe allow=”tools”>). A tool can additionally be scoped to specific secure origins with exposedTo, and getTools() returns only same-origin tools unless the caller explicitly asks for others via fromOrigins. On top of that, Chrome only enables WebMCP in origin-isolated documents: a page that opts out of origin isolation (for example via document.domain) has the APIs disabled entirely. Translation: a random third-party widget embedded on your page cannot quietly expose tools on your behalf. Someone thought about the enterprise questions early.

MCP, skills, and the third way

Here is the framing I find most useful for where WebMCP sits in the agent-tooling landscape.

Classic MCP gives you strict schema guarantees. When the agent calls a tool, the arguments are validated against a contract. But every connected server’s tools sit in the context window whether or not they are relevant to the current task. It scales poorly to the long tail.

Skills solve the token problem through progressive disclosure: only a title and description live in context, and the full instructions load on demand. But a skill is ultimately a text prompt; there is no schema guarantee at the moment of action.

WebMCP introduces a third pattern: contextual tools with full schemas. Which tools exist depends on where the agent is: the page, the route, the component currently rendered. Navigate from search results to a product page, and set_filter disappears while add_to_cart appears. You get MCP’s determinism with skills-like contextual loading, driven by the application’s own lifecycle.

This pattern is bigger than WebMCP itself. It is a preview of where agent tooling in general seems to be heading: tools loaded by task context rather than pre-registered globally. (The two worlds are already converging. There is an open spec issue exploring letting site authors ship a higher-level skill that orchestrates multiple WebMCP tools.)

And that is exactly why Angular’s implementation deserves a closer look: a framework with a dependency injection tree, a router, and component lifecycles already has the machinery to express “these tools exist in this context” natively.

In part two, we walk through Angular v22’s experimental WebMCP support, from application-wide tools to Signal Forms that describe themselves to agents, then take a hard look at the security model that comes with running tools inside an authenticated session, and finish with a sober assessment of who actually calls these tools today.


State of play as of July 2026. WebMCP is a W3C Web Machine Learning Community Group draft, currently available through a Chrome origin trial. Verify against the spec and Chrome’s WebMCP docs before shipping anything.

– W3C explainer + declarative API explainer: github.com/webmachinelearning/webmcp 

– Chrome docs: developer.chrome.com/docs/ai/webmcp (+ /imperative-api; deprecation note for navigator.modelContext confirmed there, last updated 2026-07-01) 

– Chrome Status entry: chromestatus.com/feature/5117755740913664; Intent to Experiment: groups.google.com/a/chromium.org/g/blink-dev/c/gmYffo5WOE8 

– Timeline: InfoQ (infoq.com/news/2026/06/webmcp-web-agent-standard-chrome) – Namespace churn: aibuilderclub.com/blog/webmcp-complete-guide 

Share this post

Sign up for our newsletter

Stay up-to-date with the trends and be a part of a thriving community.