Tutorial

How to use WebMCP on your website

Updated · Checked against the WebMCP draft of 20 October 2026 · By the Convertlyft research team

On this page
  1. Before you start
  2. Step 1: Pick which actions become tools
  3. How do I turn a form into a WebMCP tool? (Step 2, option A)
  4. How do I register a script tool with JavaScript? (Step 2, option B)
  5. Step 3: Test it
  6. Step 4: Make it safe
  7. By platform

To use WebMCP, you register “tools” on your page that an AI agent in the browser can call. You can do this with a few HTML attributes on an existing form, or with document.modelContext.registerTool() in JavaScript. Then you test the tools in Chrome with the WebMCP testing flag and the WebMCP pane in DevTools.

This tutorial follows the current draft spec, dated 20 October 2026. The API has changed many times in 2026, so older blog posts may show code that no longer works. Our spec tracker lists those changes.

Before you start

WebMCP is still experimental. Here is where it stands:

  • Chrome: a developer trial started in Chrome 146. An origin trial runs from Chrome 149 to Chrome 156. Chrome plans to ship it in Chrome 157.
  • Edge: the WebMCP repository lists an origin trial in Edge 150. Microsoft’s trial page says that trial expires on 30 March 2027.
  • Other browsers: Mozilla’s position is neutral and WebKit’s position is oppose. See WebMCP in Chrome for details.

Two more things to know:

  • The API only works in a secure context. Your page must be served over HTTPS (or from localhost while you develop).
  • The spec is a Community Group draft, not a W3C standard. Expect more changes.

If WebMCP is new to you, read what WebMCP is first.

Step 1: Pick which actions become tools

A tool is one action an agent can take on your page. Each tool has a name, a description in plain language, and an input schema. The agent reads the description and decides whether to call the tool.

Start with the actions people already do most on your site. Good first tools are:

  • Searching the site or a catalog.
  • Looking up one item, such as a product or an article.
  • Filling in a contact or booking form.
  • Checking something that belongs to the signed-in user, such as an order.

WebMCP tools run inside the page. Chrome’s comparison page says they can use the live session, cookies and the DOM. So a tool can act for a signed-in user without its own login step.

Keep the list short and clear. Chrome’s best-practices page says there is no maximum number of tools. But Lighthouse warns when a page registers more than 40, and every extra tool is one more thing an agent must read and choose between.

For each action, write down three things before you code:

  1. A name. 1 to 128 characters. Only ASCII letters, digits, _, - and .. For example search_articles.
  2. A description. One or two sentences: what the tool does and what it returns. It must not be empty.
  3. The inputs. Each input needs a name, a type and a short description.

Then choose a form tool or a script tool for each action:

Form tool (declarative) Script tool (imperative)
Use when You already have a working HTML form The action needs logic, returns data, or has no form
How Add toolname, tooldescription and other attributes to the form Call document.modelContext.registerTool() in JavaScript
Remove Remove toolname or tooldescription from the form Call abort() on the controller whose signal you passed
Spec status as of 24 Oct 2026 Removed from the spec “for now” on 8 October 2026 (#338); still in the explainer and in Chrome In the current draft spec, dated 20 October 2026

How do I turn a form into a WebMCP tool? (Step 2, option A)

If you already have an HTML form, you can turn it into a tool by adding attributes. Chrome documents four of them:

  • toolname on the <form>: the tool’s name.
  • tooldescription on the <form>: the tool’s description.
  • toolparamdescription on each form control: describes that input. If it is missing, Chrome uses the control’s <label>, then its aria-description.
  • toolautosubmit on the <form>: when the agent calls the tool, the form submits. Without it, the user must press submit. The explainer says the browser moves focus to the submit button.

Here is a site search form as a tool:

<form action="/search" method="get"
      toolname="search_site"
      tooldescription="Search this site by keyword and open the results page."
      toolautosubmit>
  <label for="q">Search</label>
  <input id="q" name="q" type="search" required
         toolparamdescription="Words to search for, for example 'shipping times'.">
  <button type="submit">Search</button>
</form>

You need both toolname and tooldescription. If you remove either one, the tool is unregistered. Give every field a name attribute too. Lighthouse fails a form tool when a required field has no name.

To send a result back to the agent instead of loading a new page, listen for the submit event. SubmitEvent.agentInvoked is true when an agent submitted the form. Call preventDefault() first, then pass a Promise to respondWith():

<script>
  const form = document.querySelector('form[toolname="search_site"]');
  form.addEventListener('submit', (event) => {
    if (!event.agentInvoked) return; // A person submitted it. Keep normal behaviour.
    event.preventDefault();
    const q = new FormData(form).get('q');
    event.respondWith(
      fetch(`/api/search?q=${encodeURIComponent(q)}`).then((res) => res.json()),
    );
  });
</script>

Replace /api/search with your own endpoint.

Chrome also adds two CSS pseudo-classes, :tool-form-active and :tool-submit-active. Chrome’s default style for them is a dashed outline. You can restyle them so people see when an agent is using a form.

One caution. On 8 October 2026 the editors removed the declarative API from the spec “for now” (#338). It still lives in the declarative explainer and in Chrome’s implementation. Use only the four attributes above. Attributes such as tooltitle and toolparamtitle appear in some tutorials, but we found no primary source for them.

How do I register a script tool with JavaScript? (Step 2, option B)

A script tool is a JavaScript function you register with document.modelContext.registerTool(). Use it when the action needs logic, returns data, or has no form.

The method takes two arguments:

  1. The tool. Fields: name, title (optional), description, inputSchema (optional), execute, and annotations (optional).
  2. Options. signal (an AbortSignal) and exposedTo (a list of origins).

Here is a complete, minimal script tool:

const tools = new AbortController();

async function registerSearchTool() {
  if (!document.modelContext?.registerTool) return; // No WebMCP in this browser.

  try {
    await document.modelContext.registerTool(
      {
        name: 'search_articles',
        title: 'Search articles',
        description: 'Search the articles on this site by keyword. Returns up to 10 matches, each with a title and URL.',
        inputSchema: {
          type: 'object',
          properties: {
            query: { type: 'string', description: 'Words to search for, for example "return policy".' },
          },
          required: ['query'],
        },
        annotations: { readOnlyHint: true },
        async execute({ query }, { signal }) {
          const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal });
          if (!res.ok) throw new Error(`Search failed with status ${res.status}`);
          const results = await res.json();
          return results.slice(0, 10).map((r) => ({ title: r.title, url: r.url }));
        },
      },
      { signal: tools.signal },
    );
  } catch (err) {
    // Rejects on an invalid or duplicate name, an empty description,
    // or when the page is not allowed to use the "tools" feature.
    console.warn('WebMCP tool not registered:', err.name, err.message);
  }
}

registerSearchTool();

// Later, to remove every tool registered with this signal:
// tools.abort();

What each part does:

  • Feature detection. document.modelContext?.registerTool is only there in browsers that support WebMCP. The entry point is document, not navigator. The spec moved it on 19 May 2026.
  • title is a top-level field on the tool. It does not go inside annotations.
  • inputSchema is a JSON Schema object. Describe every property.
  • annotations has four booleans, all false by default: readOnlyHint, untrustedContentHint, consequentialHint and debugging. Chrome documents debugging from Chrome 156.
  • execute receives the input object and an options object with a signal. Pass that signal on to fetch so a cancelled call stops its work.
  • await and catch. registerTool() returns a Promise. It rejects with InvalidStateError for an invalid name, an empty description or a duplicate name in the same document. It rejects with NotAllowedError when the page lacks the tools permission. It also rejects if the signal is already aborted. Always catch it, or you get unhandled rejections.
  • Teardown. There is no unregisterTool() in the current spec. To remove a tool, call abort() on the controller whose signal you passed. One controller can remove a whole group of tools at once.

Older code may call navigator.modelContext, provideContext(), clearContext() or unregisterTool(). They were removed or replaced between March and May 2026. Update that code.

Sharing a tool with another origin

By default, other origins cannot see your tools. To share one, list the trusted origin in exposedTo. It goes in the options argument, next to signal, not inside the tool:

await document.modelContext.registerTool(tool, {
  signal: tools.signal,
  exposedTo: ['https://partner.example'],
});

The caller must also name your origin in fromOrigins when it calls getTools(). Both lists accept only secure origins. An origin that cannot be parsed, or is not trustworthy, throws SecurityError.

Step 3: Test it

You can test locally without an origin trial token:

  1. Turn on the flag. Open chrome://flags/#enable-webmcp-testing, enable it and restart Chrome.
  2. Open the WebMCP pane. In DevTools, go to the Application panel and open the WebMCP pane. It lists registered tools with call counts. It logs each call with its input and output. You can also run a tool by hand from there.
  3. Check from code. document.modelContext.getTools() returns the registered tools. Chrome’s docs say it returns them in alphabetical order.
  4. Run Lighthouse. The “Agentic browsing” category arrived in Lighthouse 13.2.0 and is on by default from 13.3.0. It is informational and has no score benchmark. It needs Chrome 150 or later, and the WebMCP audits need the origin trial. The audits list your tools (with a warning above 40), check form tools for schema problems, and flag forms that have no declarative attributes.

If you use a coding agent, Chrome’s DevTools MCP server (chrome-devtools-mcp) offers list_webmcp_tools and execute_webmcp_tool behind the --categoryExperimentalWebmcp flag.

To reach real visitors, register for the WebMCP origin trial. It covers Chrome 149 to 156. Add the token it gives you to your pages.

To see how your site looks to agents overall, you can run our free checker. Convertlyft, which publishes this site, also offers a full agent-readiness report.

Step 4: Make it safe

Chrome’s security guide says it is “impossible to guarantee safety inside of a large language model”. The spec lists prompt injection, misleading tools and privacy leaks as risks. These steps reduce them:

  • Mark actions that matter. Set consequentialHint: true on tools that buy, send, delete or change data. Chrome says this lets the agent or browser ask the user to confirm first.
  • Mark untrusted output. Set untrustedContentHint: true when a tool returns content you did not write, such as reviews, comments or other web content.
  • Mark read-only tools. Set readOnlyHint: true on tools that only read data.
  • Never ask for passwords in tool inputs. A tool runs in the user’s live session, so it does not need credentials. The spec also warns that too many inputs can leak private data, a “personalization-to-fingerprinting pipeline”. Ask only for what the action needs.
  • Only expose tools to trusted origins. Leave exposedTo out unless you need it. Chrome’s advice is: “Only expose your tools to origins that you trust.”
  • Turn WebMCP off where you do not want it. Send Permissions-Policy: tools=() on those pages. The feature is called tools, and its default allowlist is 'self'. A cross-origin iframe needs allow="tools" to register tools.
  • Write honest descriptions. The spec notes that agents cannot check what a tool does before calling it. Say exactly what happens, especially for anything that costs money.

Chrome also says WebMCP is “primarily designed for local browser workflows with a human in the loop”. Design your tools so a person can follow what the agent does.

By platform

Shopify

On 5 August 2026 Shopify announced WebMCP support for Liquid and Hydrogen storefronts. The tools are live on every Liquid storefront, with nothing to install or configure. Hydrogen support is in developer preview.

Shopify lists ten tools: search_catalog, browse_store, get_product, show_variant, get_cart, update_cart, cancel_cart, proceed_to_checkout, manage_orders and search_shop_policies_and_faqs.

So on a Liquid store, do not start by adding tools. First open your storefront with the flag on and look at the WebMCP pane to see what is already registered. Do not register a tool with the same name as an existing one: a duplicate name in the same document makes registerTool() reject. Add custom tools only for actions Shopify does not cover, and give them distinct names. We found no documented way to turn Shopify’s tools off.

WordPress

WordPress has no official WebMCP support today. The WordPress AI plugin has an open issue, “Add WebMCP experiment” (#448, opened 20 April 2026). A draft pull request, #1081, adds 14 block-editor tools, but it is not merged.

For now, add tools yourself. Put the script tool code from Step 2 in your theme’s script or in a custom block, and load it on the pages where the tools make sense. For forms, add the declarative attributes in the form’s HTML if your form plugin lets you edit it.

Webflow

We found no official Webflow documentation for WebMCP. Webflow’s own “MCP server” is a separate server-side product, not WebMCP.

The likely route is to add the script tool code through Webflow’s custom code embed. This is not officially documented, and we only found it in a third-party tutorial. Test carefully with the DevTools pane before you rely on it.

Next.js and React

Neither Next.js nor React has official WebMCP support. The API is browser-only, so register tools in a client component, inside useEffect, and abort in the cleanup function:

'use client';
import { useEffect } from 'react';

export function SiteTools() {
  useEffect(() => {
    if (!document.modelContext?.registerTool) return;
    const controller = new AbortController();

    document.modelContext
      .registerTool(
        {
          name: 'search_articles',
          description: 'Search the articles on this site by keyword. Returns up to 10 matches.',
          inputSchema: {
            type: 'object',
            properties: { query: { type: 'string', description: 'Words to search for.' } },
            required: ['query'],
          },
          annotations: { readOnlyHint: true },
          async execute({ query }, { signal }) {
            const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal });
            return res.json();
          },
        },
        { signal: controller.signal },
      )
      .catch((err) => {
        if (err.name !== 'AbortError') console.warn('WebMCP tool not registered:', err);
      });

    return () => controller.abort(); // Removes the tool when the component unmounts.
  }, []);

  return null;
}

Render <SiteTools /> on the pages that should offer the tool. The cleanup matters: without it, a remount tries to register the same name again and the Promise rejects.

For TypeScript, the README mentions the webmcp-types npm package for typings.

There are also community packages from the WebMCP-org (MCP-B) project. They are community work, not official:

  • @mcp-b/webmcp-polyfill: its installWebMCP() keeps native support when present.
  • @mcp-b/react-webmcp: React hooks.
  • usewebmcp: core-only hooks.
  • @mcp-b/global: a polyfill plus an MCP bridge.

The older @mcp-b/mcp-react-hooks package is deprecated. For ready-made tool definitions to adapt, see our WebMCP examples.

Questions people ask

Do I need the Chrome origin trial to use WebMCP?

Not for local testing. Turn on chrome://flags/#enable-webmcp-testing in your own browser. To reach real visitors on Chrome 149 to 156, register for the WebMCP origin trial. Chrome plans to ship WebMCP in Chrome 157.

Should I build a form tool or a script tool?

Use a form tool when you already have a working HTML form. Use a script tool when the action needs logic, returns data, or has no form. Note that the form (declarative) API was removed from the spec on 8 October 2026 and now lives in the explainer and in Chrome.

Is there a limit on how many tools I can register?

Chrome's best-practices page says there is no maximum number of tools. Lighthouse shows a warning when a page registers more than 40 tools. That is a Lighthouse threshold, not a browser limit.

Does WebMCP replace my MCP server?

No. Chrome describes MCP as the backend option and WebMCP as the frontend option, with tools tied to an open tab. Chrome's comparison page recommends using both.

Sources

  1. WebMCP, Draft Community Group Report, 20 October 2026 (read 2026-10-23)
  2. WebMCP repository (README) (read 2026-10-23)
  3. WebMCP implementation status (read 2026-10-23)
  4. WebMCP declarative API explainer (read 2026-10-23)
  5. WebMCP commit history (read 2026-10-23)
  6. WebMCP-org community npm packages (read 2026-10-23)
  7. Chrome for Developers: WebMCP overview (read 2026-10-23)
  8. Chrome for Developers: WebMCP imperative API (read 2026-10-23)
  9. Chrome for Developers: WebMCP declarative API (read 2026-10-23)
  10. Chrome for Developers: Secure your WebMCP tools (read 2026-10-23)
  11. Chrome for Developers: WebMCP best practices (read 2026-10-23)
  12. Chrome for Developers: WebMCP vs MCP (read 2026-10-23)
  13. Blink-dev: Intent to Experiment, WebMCP (read 2026-10-23)
  14. Chrome blog: Join the WebMCP origin trial (read 2026-10-23)
  15. Microsoft Edge origin trial: WebMCP (read 2026-10-23)
  16. Chrome DevTools: WebMCP pane (read 2026-10-23)
  17. Chrome blog: agent-ready toolkit (read 2026-10-23)
  18. Lighthouse: Agentic browsing audits (read 2026-10-23)
  19. Lighthouse: Registered WebMCP tools audit (read 2026-10-23)
  20. Lighthouse: Forms missing declarative WebMCP (read 2026-10-23)
  21. Shopify changelog: WebMCP support for Liquid and Hydrogen storefronts (read 2026-10-23)
  22. WordPress AI plugin: Add WebMCP experiment (issue #448) (read 2026-10-23)
  23. Webflow developer changelog (MCP filter) (read 2026-10-23)