Skip to main content

What Is WebMCP?

WebMCP is a W3C Community Group standard that allows websites to expose structured tools to AI agents through browser-native APIs. Websites can opt in by annotating HTML forms or registering tools via JavaScript. BAP includes first-class WebMCP support — agents using BAP do not need a separate WebMCP integration.

Two API Surfaces

Declarative (HTML Attributes)

Websites annotate forms with tool metadata:
<form toolname="search-products" tooldescription="Search the product catalog by keyword">
  <input name="query" toolparamdescription="Search keywords" />
  <input name="category" toolparamdescription="Product category filter" />
  <button type="submit">Search</button>
</form>

Imperative (JavaScript)

Websites register tools programmatically:
navigator.modelContext.addTool({
  name: "add-to-cart",
  description: "Add a product to the shopping cart",
  inputSchema: {
    type: "object",
    properties: {
      productId: { type: "string", description: "Product identifier" },
      quantity: { type: "number", description: "Number of items" },
    },
    required: ["productId"],
  },
  handler: async ({ productId, quantity }) => {
    // Site-defined logic
  },
});

Discovering WebMCP Tools

CLI

# Navigate to a page and discover tools
bap goto https://example.com
bap discover

TypeScript SDK

const tools = await client.discoverTools();
for (const tool of tools.tools) {
  console.log(`${tool.name}: ${tool.description}`);
  console.log(`  Source: ${tool.source}`); // "webmcp-declarative" or "webmcp-imperative"
}

MCP Tool

The discover_tools MCP tool is available to any MCP-native agent:
{
  "method": "tools/call",
  "params": {
    "name": "discover_tools",
    "arguments": {}
  }
}

Fused Discovery with Observe

Get interactive elements and WebMCP tools in a single call:
const obs = await client.observe({
  includeInteractiveElements: true,
  includeWebMCPTools: true,
});

// Standard interactive elements
for (const el of obs.interactiveElements ?? []) {
  console.log(`${el.ref}: ${el.role} "${el.name}"`);
}

// WebMCP tools discovered on the page
for (const tool of obs.webmcpTools ?? []) {
  console.log(`Tool: ${tool.name} (${tool.source})`);
}

Progressive Detection

BAP’s discovery implementation follows a three-step strategy:
1

Declarative Scan

Query the DOM for form[toolname] elements and extract tool metadata from HTML attributes. Fast, no JavaScript execution required.
2

Imperative Scan

Check for navigator.modelContext and enumerate programmatically registered tools. Catches dynamic tools without DOM representation.
3

Graceful Fallback

If neither API surface is present, return an empty tool list with totalDiscovered: 0. No errors — the agent proceeds with standard BAP automation.

Agent Decision Pattern

The recommended pattern for agents:
// 1. Navigate and observe with WebMCP discovery
await client.navigate("https://example.com");
const obs = await client.observe({
  includeInteractiveElements: true,
  includeWebMCPTools: true,
});

// 2. Prefer WebMCP tools when available
if (obs.webmcpTools?.length) {
  // Use site's intended agent interface
  // (agent decides which WebMCP tool to invoke)
} else {
  // Fall back to BAP automation
  await client.act({
    steps: [
      /* observe-decide-act */
    ],
  });
}
Today, discover_tools returns empty on virtually every website — WebMCP adoption is in early stages (Chrome 146 Canary behind a flag). But calling it costs nothing. Call it speculatively on every page. When adoption grows, agents automatically benefit without code changes.

Discovery Response Format

{
  "tools": [
    {
      "name": "search-products",
      "description": "Search the product catalog by keyword",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": { "type": "string" }
        }
      },
      "source": "webmcp-declarative",
      "formSelector": "form[toolname='search-products']"
    }
  ],
  "totalDiscovered": 1,
  "apiVersion": "1.0"
}
Each tool includes a source field: "webmcp-declarative" for HTML attribute-based tools or "webmcp-imperative" for JavaScript API-based tools.