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.
Quickstart Execution
index.html
Get started with WebMCP in your project.
<!-- 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>About WebMCP
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.
Danish Product & Data Recipes
How developers and agents use WebMCP to connect with Danish digital infrastructure.
Cloudflare WebMCP Edge Bridge with Same-Origin /mcp
AgentAccess.dk / Cloudflare EdgeEnable 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.
<!-- 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
CVR.dk / Virk.dkAdd toolname="cvr_search" and toolparam="cvr_query" attributes to native HTML search forms so in-browser agents can execute business lookups without DOM scraping.
<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.
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,
}
}
})
}