# WebMCP

W3C proposed standard for exposing structured AI tools directly on the web

WebMCP allows web applications to expose typed JavaScript tools and annotated HTML forms directly to in-browser AI agents, replacing fragile DOM scraping.

## Overview

- **Website**: https://developer.chrome.com/docs/ai/webmcp
- **Docs**: https://blog.cloudflare.com/webmcp/
- **GitHub**: https://github.com/webmachinelearning/webmcp
- **License / Pricing**: Open Source
- **Directory Entry**: https://agentaccess.dk/enablers/webmcp

## About

WebMCP is an open web standard under incubation in the W3C Web Machine Learning Working Group and available experimentally from Chrome 146 (and Origin Trials). It enables web applications to declare callable agent tools with explicit JSON schemas directly in client-side code, rather than forcing agents to rely on fragile DOM scraping or simulated mouse clicks. WebMCP supports both a Declarative API (using native HTML form attributes like `toolname` and `toolparam`) and an Imperative API (`document.modelContext` / `navigator.modelContext`). Cloudflare provides a 1-click WebMCP edge bridge that automatically connects in-browser agents to any same-origin `/mcp` server endpoint, and Cloudflare BrowserRun supports native WebMCP tool discovery and actuation. Because tools run inside the active browser session under standard Origin Isolation and Permissions Policy, WebMCP provides a secure, human-in-the-loop mechanism for agent automation on authenticated platforms without leaking session credentials or bypass tokens.

## Key Features

- Declarative API: Annotate native HTML forms with toolname and parameter bindings
- Imperative API: Register JavaScript functions into document.modelContext with typed JSON Schemas
- Cloudflare 1-Click Edge Bridge: Connects in-browser agents to same-origin /mcp server with zero code changes
- Cloudflare BrowserRun actuation: Remote browsers autonomously discover and invoke site-registered tools
- Runs in active browser session with Origin Isolation and Permissions Policy enforcement
- Eliminates brittle CSS selector maintenance and vision-based click guessing
- Human-in-the-loop friendly for sensitive operations like payments and submissions
- Shipping experimentally in Chrome 146+ with Model Context Tool Inspector extension

## Danish System Application Recipes

### Cloudflare WebMCP Edge Bridge with Same-Origin /mcp
Enable Cloudflare WebMCP preview on your Danish platform domain. The edge bridge connects browser agents directly to your /mcp endpoint for instant, zero-maintenance agent access.

```bash
<!-- Injected at the edge by Cloudflare HTMLRewriter -->
<script type="module"
        src="/.webmcp/bridge.js"
        data-packs="c2pa,mcp-server-client"
        data-mcp-url="/mcp"></script>
```

### Declarative CVR Search on Danish Portals
Add toolname="cvr_search" and toolparam="cvr_query" attributes to native HTML search forms so in-browser agents can execute business lookups without DOM scraping.

```bash
<form action="/search" method="GET" toolname="cvr_search" tooldescription="Look up Danish registered businesses by CVR number or company name">
  <label for="cvr">CVR / Navn</label>
  <input type="text" id="cvr" name="q" toolparam="cvr_query" toolparamdescription="8-digit Danish CVR number or legal company name" required />
  <button type="submit">Søg</button>
</form>
```

### Imperative Tool Registration for MitID-Protected Self-Service
Register an imperative client-side tool with document.modelContext that handles municipal or tax form pre-filling after the user has completed MitID authentication.

```bash
if (document.modelContext) {
  document.modelContext.registerTool({
    name: 'prepare_tax_deduction',
    description: 'Pre-fills Danish commuter deduction (kørselsfradrag) for the authenticated citizen',
    inputSchema: {
      type: 'object',
      properties: {
        workDays: { type: 'integer', minimum: 1, maximum: 365 },
        distanceKmPerDay: { type: 'number', minimum: 25 }
      },
      required: ['workDays', 'distanceKmPerDay']
    },
    execute: async ({ workDays, distanceKmPerDay }) => {
      // Updates local form state; user inspects and clicks final submit
      return {
        content: [{ type: 'text', text: 'Commuter deduction updated successfully' }],
        isError: false,
      }
    }
  })
}
```

## Quickstart

```html
<!-- 1. Declarative WebMCP: Annotate standard HTML forms -->
<form action="/api/quote" toolname="request_freight_quote" tooldescription="Get freight estimate between Danish postal codes">
  <input name="fromZip" toolparam="from_postal_code" placeholder="Fra postnr (f.eks. 8000)" required />
  <input name="toZip" toolparam="to_postal_code" placeholder="Til postnr (f.eks. 1050)" required />
  <input name="weightKg" type="number" toolparam="weight_kg" placeholder="Vægt i kg" required />
  <button type="submit">Beregn fragt</button>
</form>

<!-- 2. Imperative WebMCP: Register typed tools in JavaScript -->
<script>
if (window.modelContext) {
  window.modelContext.registerTool({
    name: 'get_live_train_status',
    description: 'Fetches live train delays and track alterations for Danish stations',
    inputSchema: {
      type: 'object',
      properties: {
        stationName: { type: 'string', description: 'Station name in Denmark, e.g. Aarhus H' }
      },
      required: ['stationName']
    },
    execute: async ({ stationName }) => {
      const res = await fetch(`/api/trains?station=${encodeURIComponent(stationName)}`)
      return res.json()
    }
  })
}
</script>
```

---
Source: [AgentAccess Enablers](https://agentaccess.dk/enablers/webmcp)