Make Your Website Usable by AI Agents: WebMCP, Step by Step
DEV Community

Make Your Website Usable by AI Agents: WebMCP, Step by Step

Make Your Website Usable by AI Agents: WebMCP, Step by Step

There's a new visitor in your logs: the AI agent, acting on someone's behalf. Right now it "uses" your site by reading the DOM and guessing which button does what. WebMCP replaces the guessing with a contract - your page declares structured tools an in-browser agent can call directly. It's a draft W3C standard (Google + Microsoft) that shipped as an early preview in Chrome 146. Here's how to add it, step by step, with copy-paste code.

The Mental Model (Read This First)

A WebMCP tool is three things:

  • A name
  • A description the agent reads to decide when to call it
  • An inputSchema describing its parameters

When the agent calls it, your code runs in the user's own tab, with their session and permissions, and returns a result. There are two ways to declare a tool - start with declarative.

Step 1 - Declarative: Expose a Form (The Easy Win)

If the action is already a <form> (search, subscribe, log in), add two attributes to the form and one to each input. It keeps working for humans; the browser synthesizes a tool from it.

<form tool-name="search-products" tool-description="Search the product catalog by keyword" action="/search" method="get">
  <input name="query" tool-param-description="Keywords to search for, e.g. 'running shoes'" required />
  <button type="submit">Search</button>
</form>

Because the tool lives in your HTML, it survives your build step and is trivial to verify. Make this your default: every important form gets tool-name and tool-description.

Step 2 - Imperative: Register a Tool in JS (For Everything Else)

For logic a form can't express, register a tool with JavaScript. Feature-detect first so non-WebMCP browsers are unaffected. The current entry point is document.modelContext (older previews used navigator.modelContext):

const mc = document.modelContext || navigator.modelContext;
if (mc) {
  mc.registerTool({
    name: "add-to-cart",
    description: "Add a product to the cart by SKU.",
    inputSchema: {
      type: "object",
      properties: {
        sku: { type: "string", description: "Product SKU, e.g. 'SHOE-42'" },
        quantity: { type: "integer", description: "How many to add" }
      },
      required: ["sku"],
      additionalProperties: false
    },
    async execute({ sku, quantity = 1 }) {
      const result = await addToCart(sku, quantity); // your existing app logic
      return { content: [{ type: "text", text: JSON.stringify(result) }] };
    }
  });
}

The key move: execute calls the same function your UI already calls. You're exposing logic you already have, not building a second integration.

Step 3 - Return the Right Shape

Whatever execute does, return the MCP content-block shape so the agent gets a usable result:

return { content: [{ type: "text", text: JSON.stringify(data) }] };

Step 4 - Verify It

Two things worth knowing:

  • Declarative tools are easy to confirm - they're right there in your HTML.
  • Imperative tools aren't - they only exist after your JS runs, and in a minified bundle you can't eyeball them.

Any static "is my site ready" check confirms your form-based tools but sees only a code reference for JS-registered ones. That's the nature of static analysis, not a flaw in your site.

Quick Loop

Here's what I use:

  1. Generate correct snippets (both formats, with the feature-detection shim): https://toolhq.dev/tool/webmcp-generator/
  2. Check your page - paste HTML or scan your URL; it also flags forms you could expose and hands you the attributes to add: https://toolhq.dev/tool/webmcp-checker/
  3. For a true end-to-end test, open the page in a WebMCP-capable browser (Chrome 146+ with the flag) and have its agent call the tool.

Deeper walkthrough: https://toolhq.dev/learn/make-your-website-webmcp-ready/

Best Practices

  • Name tools in kebab-case; write the description like you're briefing a teammate.
  • Describe every parameter - vague inputs cause wrong calls.
  • Least privilege: only expose actions the user could already perform; the tool runs with their session.
  • Guard destructive actions (delete/pay/send) with confirmation; treat tool input as untrusted.
  • Keep the human UI working - WebMCP augments your page, never replaces it.

Where WebMCP Fits

Three layers, not one:

  • llms.txt โ†’ tells an assistant what your site is and points at key pages.
  • robots.txt โ†’ decides who may crawl.
  • WebMCP โ†’ declares what an agent can do once it's there.

Search optimized your site for crawlers; this optimizes it for actors.

Wrap-Up

WebMCP is early - the spec (especially the declarative attribute names) can still shift, so feature-detect and keep your human UI intact. But it's cheap to adopt: a couple of attributes on forms you already have, plus a thin registerTool wrapper around logic you already wrote. Ten minutes. Start with one form.

Have you made anything agent-ready yet, or hit a rough edge in the spec? Compare notes in the comments.

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.