WebMCP Tools

Hand your docs to an agent driving the browser as read-only WebMCP tools

Overview

WebMCP lets a page register tools on document.modelContext for whatever agent is driving the browser. With the webmcp feature, dioxus-docs-kit registers your docs as four read-only tools, so an agent searches the index and reads Markdown source instead of scraping the rendered page.

This site has them on. Open it in a WebMCP-capable browser or agent and call docs_list_pages.

Setup

1

Enable the feature

toml
dioxus-docs-kit = { version = "0.7", features = ["webmcp"] }

It is off by default because it pulls webmcp-rs and schemars into the wasm.

2

Mount the component

Put DocsWebMcp {} anywhere below use_docs_providers. It renders nothing. The registrations live exactly as long as the mount, so leaving the docs section unregisters them.

rust
rsx! {
    DocsLayout {
        header: rsx! { /* ... */ },
        DocsWebMcp {}
        Outlet::<Route> {}
    }
}
3

Load the polyfill

Chrome 153+ has document.modelContext natively; 149 to 152 need the origin trial or chrome://flags/#enable-webmcp-testing. Every other browser needs Google's WebMCP polyfill (Apache-2.0), and it has to run before the wasm starts, because the tools register on first render. That rules out a component: it goes in index.html.

The polyfill is not part of the crate. Copy it from this repo's assets/webmcp-polyfill.js, then pin it as an unhashed asset so the URL is stable:

<head>
  <script src="/assets/webmcp-polyfill.js"></script>
</head>

The polyfill returns early when the browser has the native API.

Tools

Every tool replies with one JSON text block. Paths are content paths, the same ones you list in _nav.json, and every result carries the page URL so the agent can send the visitor there.

Tool Arguments Returns
docs_search query, optional limit (default 10, max 50) Ranked section-level hits with title, heading, breadcrumb, a snippet and the URL
docs_get_page path The page's Markdown source plus title, description and tab
docs_list_pages none Every page grouped like the sidebar, API endpoints included
docs_get_api_operation path One OpenAPI operation: method, endpoint, parameters, request body, responses and a ready curl command

docs_get_page and docs_get_api_operation accept whatever shape an agent hands back: a full URL, a leading slash, the docs base path, a .md suffix or a #anchor are all stripped. A miss returns a soft error that names the nearest real pages.

Calling them by hand

Open the console on this site:

javascript
const ctx = document.modelContext;
const search = (await ctx.getTools()).find(t => t.name === "docs_search");
// Chrome 153 and 154 only parse JSON-string arguments and return the result
// JSON-stringified; the polyfill and Chrome 155+ take and return objects.
let reply = await ctx.executeTool(search, JSON.stringify({ query: "theme toggle" }));
if (typeof reply === "string") reply = JSON.parse(reply);
JSON.parse(reply.content[0].text).results;

scripts/browser-smoke.py in the repo runs the same calls against every tool in CI.

Navigation