webmcp-tool

WebMCP

The declarative API: tools from forms you already have

The cheapest possible entry into WebMCP is annotating a form and letting the browser derive the schema. It is also the part of the specification that is least finished — here is the state of it, without inventing attribute names.

Last reviewed 27 August 2026

Most of what an agent wants to do on an ordinary website is already expressed as a form. Search, contact, quote request, booking, filter, newsletter — each is a set of named fields with types and a submit target. The declarative half of WebMCP exists on the observation that this is already a tool definition, badly disguised.

The idea: annotate the form, and the browser synthesises the tool. Field names become schema properties, input types become JSON Schema types, labels become property descriptions, and the form's own submission becomes the handler. No JavaScript, no separate definition to keep in sync.

The state of it, stated plainly

The declarative form is described in the explainer as a counterpart to the imperative API, but the concrete attribute names are still marked TODO in the specification repository, and the dedicated Chrome documentation page returned 404 when this article was reviewed. We are not going to print attribute names we cannot verify — a wrong attribute in a tutorial is worse than no tutorial, and this page would be exactly the wrong place to guess.

What you can do today, which is most of the value

Here is the useful part: almost all of the work the declarative API will ask of you is work you should do anyway, and it pays off immediately with agents that do not implement WebMCP at all.

When the browser derives a schema from your form, it derives it from labels, names, types and autocomplete tokens. A form with <input name="field_7"> and no label produces a useless tool. The same form done properly produces a good one — and in the meantime it is also the form that a DOM-reading agent, a screen reader and a password manager can all handle.

<form action="/api/quote" method="post">
  <label for="service">What do you need?</label>
  <select id="service" name="service" required>
    <option value="webmcp-implementation">WebMCP implementation</option>
    <option value="agent-readiness-audit">Agent readiness audit</option>
    <option value="monitoring">Ongoing monitoring</option>
  </select>

  <label for="email">Work email</label>
  <input id="email" name="email" type="email"
         autocomplete="email" required
         aria-describedby="email-hint">
  <p id="email-hint">We reply within one business day.</p>

  <label for="volume">Monthly page views</label>
  <input id="volume" name="volume" type="number"
         min="0" step="1000" inputmode="numeric">

  <button type="submit">Request a quote</button>
</form>
A form that will synthesise well, and works now regardless

Read that markup as a schema and the mapping is obvious:

MarkupBecomes
name attributeProperty key
type / inputmodeProperty type
<label> textProperty description
<option> valuesenum constraint
requiredEntry in the required list
min, max, step, patternNumeric and string constraints
aria-describedby textAdditional guidance for the agent
action and methodWhere the invocation goes

Every row of that table is also a row in our forms guide, because it is the same work. Do it, and adopting the declarative API later is an annotation pass rather than a rewrite.

When to prefer the imperative API anyway

  • Anything multi-step. A form is one submission. Comparing two products, or checking compatibility before adding to a cart, is a conversation — that wants handlers.
  • Anything that reads. Forms are built to write. A tool that returns the current cart, or a specification sheet, has no natural form to be derived from.
  • Anything conditional. Tool lists that change with login state are a lifecycle concern, and lifecycle lives in JavaScript with an AbortSignal.
  • Anything that needs annotations. readOnlyHint and confirmation before a destructive call are properties of the tool definition.

A sensible sequence

  1. Fix the form semantics now. Labels, names, types, autocomplete tokens, aria-describedby. This pays off with every agent that exists today.
  2. Register your two or three highest-value read actions imperatively, with readOnlyHint: true.
  3. Watch the explainer for the declarative attribute names to settle, then annotate the forms you already cleaned up.
  4. Only then consider write tools, and put a confirmation step in front of each one.
What we check

Our scanner reports declarative annotations when it finds them and excludes the check entirely when a page serves no forms — a page with nothing to annotate is not failing at annotation. The forms check, which grades labels, names, types and autocomplete coverage, applies regardless and is worth 7 points.

Sources

Primary documents, checked on 27 August 2026

  1. github.com/webmachinelearning/webmcpExplainer repository, imperative and declarative API
  2. webmachinelearning.github.io/webmcpW3C Web Machine Learning Community Group draft — WebIDL, annotations, permissions policy
  3. developer.chrome.com/docs/ai/webmcpOrigin trial, flags, permissions policy directive
  4. html.spec.whatwg.org — autofillThe autocomplete token list a synthesised schema can lean on

Keep reading

Check your own site against this

The Agent Readiness Score measures exactly what this article describes, and shows the evidence behind every finding.

Run the check →