Feature · WebMCP

WebMCP, both sides.

WebMCP is the W3C standard for how a page exposes tools to AI agents. Every other player sits on one side of it. Dornick sits on both — it calls your page's tools as a client, publishes its own as a provider, and ships the polyfill so both work today.

WebMCP is the W3C draft for how a web page exposes typed, callable tools to AI agents, through document.modelContext. Dornick is the only runtime that sits on both sides of it: it calls the page's tools as a client, and publishes its own as a provider — generated from configuration you already wrote.

Everyone else is on one side

WhoTheir sideWhat they can't do
Shopify, Cloudflare, any site adding <form toolname> provider nothing calls those tools from inside the page
Chrome's built-in agent consumer you can't build on it, or ship it
MCP-B (@mcp-b/*) provider plumbing it has no agent of its own
CopilotKit, Stagehand, Vercel AI SDK neither not on the standard at all

Consuming: the page's tools become the agent's tools

On by default. Every tool registered on document.modelContext is adopted into Dornick's tool registry under a webmcp__ prefix and re-synced whenever the page fires toolchange. The agent calls them directly — no DOM scraping, no selector guessing.

// The page registered "add_to_cart" — however it was built.
// Dornick's agent now has a real tool called webmcp__add_to_cart.

const dornick = new Dornick({ config, transport });   // webmcp defaults to on
dornick.attach(form);

Adopted tools are always treated as untrusted, whatever the page claims about itself. Their output is fenced and screened for prompt injection before it reaches the model, and side-effecting tools are denied unless you supply a confirmation handler.

Publishing: your config is already the tool schema

This is the part that costs you nothing. Dornick already knows your data points, so it generates the provider surface from them.

new Dornick({ config, transport, webmcp: { publish: true } });

// Registers onto document.modelContext:
//   dornick_tree · dornick_read · dornick_ls · dornick_grep   — read-only workspace verbs
//   dornick_set_email, dornick_set_plan, …                — one per configured dataPoint
//   dornick_ask                                          — talk to the running agent

Each setter's JSON Schema comes from the type, pattern, and allowedValues you already wrote in your config. Writes route through the virtual filesystem, so your beforeFieldFill hooks and ACLs still apply — nothing touches the DOM directly. Read-only by default; you widen it explicitly.

Declarative tools, from HTML attributes

WebMCP also has an attribute form, and Dornick's polyfill implements it — including SubmitEvent.agentInvoked and respondWith(). It works against a native implementation with no polyfill loaded at all.

<form toolname="search-cars"
      tooldescription="Search the inventory by make and model"
      toolautosubmit>
  <input name="make" toolparamdescription="e.g. BMW, Ford" required>
  <button type="submit">Search</button>
</form>

Field types map to JSON Schema the way you'd expect — type=number with min/max/step becomes minimum/maximum/multipleOf, a <select> becomes an enum, required populates required[]. Password and file inputs are left out: the first for safety, the second because it can't be set programmatically.

Native vs polyfilled — the part we won't overstate

@dornick/webmcp is zero-dependency and never clobbers: it stands down for a native implementation and for another vendor's polyfill. But a polyfill is page JavaScript, and native document.modelContext is a browser IPC surface.

EnvironmentWho can see your tools
Chrome 149+ with the origin trial or chrome://flags/#enable-webmcp-testing the browser's own agent, extensions, DevTools, page script
Anything else (polyfilled) extensions, CDP/Playwright drivers, the MCP relay, page script — not a browser-native agent

The polyfill buys you one authoring API that works everywhere today, and extension reach. It does not buy browser-agent reach, and no polyfill can. Check which you have:

dornick.capabilities.current.apis.webmcp.implementation
// "native" | "polyfill" | "none"

Going native

  • Production: register for the WebMCP origin trial (Chrome 149–156) and add the token to your page as <meta http-equiv="origin-trial" content="…">.
  • Local development: enable chrome://flags/#enable-webmcp-testing.
  • Debugging: Chrome 149+ ships a WebMCP panel in DevTools → Application. It lists registered tools, shows their schemas, and lets you invoke one by hand — the fastest way to check your schema is what you think it is.

Read the full WebMCP docs →  ·  How this differs from MCP →

Make your page agent-ready this afternoon.

Drop in Dornick, set publish: true, and your existing config becomes a tool surface any agent can call.