Skip to main content

Crate webmcp

Crate webmcp 

Source
Expand description

Server-side toolkit for WebMCP, the W3C Community Group proposal that lets a web page register tools an in-browser AI agent can call through document.modelContext (registerTool, getTools, executeTool).

WebMCP is not the server-to-server Model Context Protocol (MCP): MCP servers (for example with rmcp) are called by desktop or CLI agents, while WebMCP tools live in a browser tab and run with the signed-in user’s session. This crate covers the server half of WebMCP and is framework-agnostic:

  • Tool::new validates a definition at boot: name 1–128 of [A-Za-z0-9_.-], WebMCP annotations read_only/untrusted_content/consequential/debugging, a strict JSON Schema subset, a same-origin endpoint, GET only when read-only.
  • Registry selects the tools each page exposes; Manifest::to_script_tag renders them as a script-safe <script type="application/json"> element.
  • RUNTIME_JS is the shared browser runtime (zero dependencies). It registers the manifest’s tools and, when an agent calls one, calls the tool’s endpoint with the user’s session cookies and CSRF token, without following redirects and without retries. Serve it and reference it with runtime_script_tag.
  • form_attrs and param_attr render the declarative form attributes.
  • Origin trial helpers, plus OriginTrialLayer behind the tower feature.

Endpoints keep authorization, CSRF checks and input validation; annotations are hints, not security controls. The same manifest format and runtime ship in the Ruby (reference), Go and Django packages. Spec baseline: WebMCP Draft CG Report 2026-10-02.

use serde_json::json;
use webmcp::{Endpoint, Manifest, ScriptTagOptions, Tool, ToolDef, Transport};
let mut definition = ToolDef::new("list_tasks", "List my tasks.",
    json!({"type": "object"}), Endpoint::new("/api/tasks", "GET"));
definition.annotations.insert("read_only".into(), true);
let tool = Tool::new(definition)?;
let manifest = Manifest::build(&[&tool], Transport::default())?;
let html = manifest.to_script_tag(&ScriptTagOptions::default());
assert!(html.contains("data-webmcp-autostart"));

With tower, OriginTrialLayer fills only missing response headers. The axum feature enables Tower support for this documentation-only example; the application supplies its own axum dependency:

ⓘ
use axum::{routing::get, Router};
use webmcp::OriginTrialLayer;
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let app: Router = Router::new().route("/", get(|| async { "ok" }))
        .layer(OriginTrialLayer::new("YOUR_TOKEN")?.warn_on_oac_opt_out(true));
    Ok(())
}

Structs§

Csrf
CSRF token location, read by the browser runtime on each invocation.
DefinitionError
Invalid tool, schema, transport, registry, or form metadata.
Endpoint
An explicit browser-to-server endpoint projection, validated by Tool::new.
Manifest
An immutable manifest containing only the tools passed to Manifest::build.
Registry
A boot-time registry. Selection is explicit; registration alone exposes nothing.
ScriptTagOptions
Script tag options. Autostart marking is enabled by default.
Tool
An owned, immutable, validated browser tool. Construction never registers it.
ToolDef
Mutable input to Tool::new; not itself a validated or exposed tool.
Transport
Explicit transport configuration. Rust supplies no implicit CSRF defaults.

Constants§

ORIGIN_TRIAL_HEADER
The HTTP response header used for an Origin Trial token.
RUNTIME_JS
The byte-for-byte copy of the shared browser runtime.
RUNTIME_SHA256
SHA-256 of the shipped runtime (also pinned in conformance/RUNTIME.sha256).

Functions§

apply_origin_trial
The plain header-list helper when the optional http feature is disabled. Fill a missing Origin-Trial header in a framework-independent header list. Matching is case-insensitive, existing empty values are preserved, and an empty token is a no-op.
apply_origin_trial_headers
The plain header-list helper when the optional http feature is disabled. Fill a missing Origin-Trial header in a framework-independent header list. Matching is case-insensitive, existing empty values are preserved, and an empty token is a no-op.
form_attrs
Render escaped, normative declarative form attributes.
origin_trial_header
Build the original 0.0.1 header pair without validating or changing the token.
origin_trial_meta_tag
Render an escaped Origin Trial meta tag, or an empty string for an empty token.
param_attr
Render an escaped toolparamdescription attribute, even for pre-escaped input.
runtime_script_tag
Render an external module script tag with an optional escaped CSP nonce. Serve RUNTIME_JS at src using your framework’s asset pipeline.

Type Aliases§

Error
An error in a tool definition or declarative form’s metadata.