WebMCP at the edge.
A Cloudflare Worker that equips any website with WebMCP from a single TOML config. Browser-native agents see your site's tools automatically. Desktop MCP clients pair through a dedicated page.
Get started Source on GitHubHow it works
The Worker sits in front of your domain. On every request it does one of two things:
- If the request matches a Worker-owned path (manifest,
/mcplanding,/_webmcp/exec/*,/_webmcp/health,/llms.txt,/robots.txt,/.well-known/agents.mdand its 301 aliases,/.well-known/api-catalog,/.well-known/agent-skills/site/SKILL.mdand its case-variant aliases,/.well-known/agent-skills/index.json,/.well-known/ai-catalog.json), handle it directly. - Otherwise proxy the request to origin. Two modifications happen on the way back to the visitor:
- HTTP
Linkheader added on every proxied response - HTML, PDF, image, JSON, anything. One entry per discovery surface:rel="webmcp"to the manifest,rel="api-catalog"to the RFC 9727 catalog,rel="agent-skills"to the SKILL.md,rel="ai-catalog"to the ARD catalog. An agent doing aHEADrequest finds them all without parsing a body. - On HTML responses only (status 200,
text/html, UTF-8, path not excluded), HTMLRewriter injects matching<link>tags into<head>(rel="webmcp",rel="api-catalog",rel="agent-skills",rel="ai-catalog") and a<script src="/_webmcp/bootstrap.<hash>.js" defer>before</body>that auto-registers the tools viadocument.modelContext(falling back to the deprecatednavigator.modelContext). Non-HTML responses pass through unchanged in their body. - If a
[[forms]]block matches the current path, declarative WebMCP attributes (toolname,tooldescription,toolparamdescription,toolautosubmit) are stamped onto matching forms in the HTML response.
- HTTP
What you get
Manifest
Static tool catalogue at /.well-known/webmcp (/.well-known/webmcp.json 301s here).
Auto-registration
Site-wide document.modelContext.registerTool (falling back to navigator.modelContext) for browser-native agents.
Discovery
HTTP Link header and matching <link> tags on every page, advertising the manifest (rel="webmcp"), API catalog (rel="api-catalog"), Agent Skill (rel="agent-skills"), and ARD catalog (rel="ai-catalog").
Pairing page
/mcp lands desktop MCP clients with one-line setup.
llms.txt + robots.txt
Augmented with WebMCP discovery hints, idempotently merged.
AGENTS.md
Auto-published at /.well-known/agents.md with 301 aliases for /AGENTS.md and /agents.md.
API catalog
RFC 9727 Linkset at /.well-known/api-catalog pointing at the WebMCP manifest. Merges with origin's catalog if present.
Agent Skill + Discovery
SKILL.md at /.well-known/agent-skills/site/SKILL.md with auto-generated tool list and publisher hints. Wrapped by an index at /.well-known/agent-skills/index.json with a SHA-256 digest per the Cloudflare Agent Skills Discovery RFC v0.2.0 so spec-aware agents verify integrity before parsing.
ARD catalog
Agentic Resource Discovery catalog at /.well-known/ai-catalog.json listing the site's Agent Skill so ARD registries can index it. Publisher half only. Advertised via a robots.txt Agentmap directive, rel="ai-catalog", and llms.txt.
Form injection
Stamp toolname / tooldescription / toolparamdescription onto existing forms at the edge from a [[forms]] TOML block.
Five executors
sitemap_filter, rss_feed, dom_extract, http_json, http_get.
Every surface is opt-in
Each card above is a single boolean in your [features] block. Disagree with a convention or do not want to publish it? Flip it off and the route disappears, the link advertisement drops out, and no fingerprint is left. For example llms.txt is widely debated; if you would rather not serve it set llms_txt = false and cf-webmcp stops claiming the path. Same applies to agents.md, the API catalog, the Agent Skill, the ARD catalog, the fallback widget, form attribute injection, and the in-page <script> bootstrap.
Defaults are "on" because cf-webmcp's value is publishing discovery surfaces; opting out is one TOML edit away.
Two minutes to deploy
git clone https://github.com/basgr/cf-webmcp
cd cf-webmcp
cp templates/wordpress.toml webmcp.toml
cp wrangler.example.toml wrangler.toml
# edit webmcp.toml + wrangler.toml
npm install
npm run build
wrangler deploy
Three templates ship: default, wordpress, woocommerce.