DEV Community

Cover image for Make Your Website Usable by AI Agents: WebMCP, Step by Step
ashwiniks
ashwiniks

Posted on

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>
Enter fullscreen mode Exit fullscreen mode

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) }] };
    }
  });
}
Enter fullscreen mode Exit fullscreen mode

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) }] };
Enter fullscreen mode Exit fullscreen mode

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 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.

Top comments (1)

Collapse
 
alikhatersaibreakroom profile image
Ali Khater

The three-layer framing is useful. We added llms.txt plus a dedicated AI welcome guide, but discovery still is not execution. WebMCP is the missing action contract. I would add endpoint-level idempotency and rate limits to the checklist, because an in-browser confirmation does not prevent duplicate calls after an agent retries a request.