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
},
});
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"
}
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:
Declarative Scan
Query the DOM for form[toolname] elements and extract tool metadata from HTML attributes.
Fast, no JavaScript execution required.
Imperative Scan
Check for navigator.modelContext and enumerate programmatically registered tools. Catches
dynamic tools without DOM representation.
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.
{
"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.