Skip to content

WebMCP

If MCP is the “USB” for connecting data sources, WebMCP is the “USB” for connecting user interfaces. A WebMCP server runs in the browser and exposes widgets, renderers, and UI actions that the agent can call exactly like a remote MCP tool.

WebMCP is a protocol complementary to MCP, designed for client-side rendering. It rests on two pillars:

  1. A browser API (navigator.modelContext) standardized by the W3C WebMCP Draft CG Report (2026-03-27), allowing any web page to register tools accessible by AI agents.
  2. A local server framework (createWebMcpServer) that structures these tools into thematic servers with widgets, recipes, and JSON schemas.
graph LR
subgraph "Browser"
WM1["autoui<br/>24+ native widgets"]
WM2["chartjs<br/>Interactive charts"]
WM3["cytoscape<br/>Graphs & networks"]
WM4["leaflet<br/>Interactive maps"]
MC["navigator.modelContext"]
end
subgraph "Agent"
LLM["LLM"]
end
LLM -->|widget_display| WM1
LLM -->|chartjs_webmcp_widget_display| WM2
LLM -->|cytoscape_webmcp_widget_display| WM3
LLM -->|leaflet_webmcp_widget_display| WM4
WM1 -.->|registerTool| MC
WM2 -.->|registerTool| MC

MCP vs WebMCP: the fundamental distinction

Section titled “MCP vs WebMCP: the fundamental distinction”
MCPWebMCP
RoleRetrieve dataDisplay the data
Where it runsRemote server (HTTP/SSE)In the browser (in-memory)
TransportJSON-RPC 2.0 over HTTP POSTJavaScript function calls
Typical toolsquery_sql, search, list_tableswidget_display, canvas, recall
Example serversTricoteuses, iNaturalist, Hacker Newsautoui, chartjs, cytoscape, leaflet
SpecAnthropic MCP specificationW3C WebMCP Draft CG Report

A WebMCP server is created with createWebMcpServer from the @webmcp-auto-ui/core package. It registers widgets — renderers that take JSON data and produce HTML/SVG/Canvas.

import { createWebMcpServer } from '@webmcp-auto-ui/core';
const myServer = createWebMcpServer('my-charts', {
widgets: [
{
name: 'bar-chart',
description: 'Renders a bar chart',
schema: {
type: 'object',
properties: {
labels: { type: 'array', items: { type: 'string' } },
values: { type: 'array', items: { type: 'number' } },
},
required: ['labels', 'values'],
},
renderer: (container, data) => {
// Render using Chart.js, D3, or vanilla DOM
// Return an optional cleanup function
},
vanilla: true, // Mark as vanilla (non-Svelte) renderer
},
],
recipes: [rawMarkdownRecipe],
});
// Expose as a tool layer for the agent
const layer = myServer.layer();
ModeFlagWhen to use
Vanillavanilla: trueThird-party libraries (Chart.js, Cytoscape, D3, Plotly, Three.js) — the renderer receives an HTMLElement and draws into it
Sveltevanilla: false (default)Svelte 5 components — the renderer is a .svelte component with props

Vanilla renderers receive a deep-cloned copy of the data (via JSON.parse(JSON.stringify(data))) to avoid conflicts between Svelte 5 $state proxies and libraries that use Object.defineProperty.

The @webmcp-auto-ui/agent package provides a pre-configured WebMCP server named autoui with 24+ native widgets:

CategoryWidgets
Simplestat, kv, list, chart, alert, code, text, actions, tags
Richstat-card, data-table, timeline, profile, trombinoscope, json-viewer, hemicycle, chart-rich, cards, grid-data, sankey, log, gallery, carousel, map, d3, js-sandbox

The agent calls widget_display({ name, params }) to render any of these widgets.

Beyond autoui, the project includes 10+ thematic WebMCP servers in packages/servers/:

ServerLibraryWidgets
chartjsChart.jsbar, line, pie, radar, doughnut, scatter, polar-area
cytoscapeCytoscape.jsforce-graph, concentric-rings, spread-layout, physics-simulation
d3D3.jstreemap, force-directed, chord, sunburst
leafletLeafletmarkers, GeoJSON, heatmap, choropleth
plotlyPlotly.jsscatter, 3D surface, contour, histogram
mermaidMermaidflowchart, sequence, gantt, class, state
threejsThree.jsmesh, lights, animations
pixijsPixiJSsprites, particles
roughRough.jshand-drawn style sketches
canvas2dCanvas APIcustom 2D drawings

Each server exposes its own widgets and recipes. The agent discovers them via search_recipes() and get_recipe().

The W3C WebMCP protocol defines a standard browser API for web pages to expose tools to AI agents:

// Register a tool accessible by the agent
navigator.modelContext.registerTool({
name: 'todo_add',
description: 'Add a new todo item',
inputSchema: { type: 'object', properties: { text: { type: 'string' } } },
execute: (args) => {
addTodo(args.text);
return { content: [{ type: 'text', text: 'Todo added' }] };
},
});
// Unregister a tool
navigator.modelContext.unregisterTool('todo_add');

In webmcp-auto-ui, each widget rendered on the canvas auto-registers via this API with three tools:

  • widget_{id}_get — read the widget’s current data
  • widget_{id}_update — update the data
  • widget_{id}_remove — remove the widget

This allows the agent (or a browser extension) to interact with already-rendered widgets.

For cases where Svelte is not available (vanilla JS, React, Vue), the @webmcp-auto-ui/core package provides mountWidget():

import { mountWidget } from '@webmcp-auto-ui/core';
const container = document.getElementById('my-widget');
const cleanup = mountWidget(container, myServer, 'bar-chart', {
labels: ['Q1', 'Q2', 'Q3'],
values: [120, 340, 250],
});
// Later, clean up
cleanup?.();

mountWidget deep-clones the data, resolves the server’s renderer, and calls it with the DOM container. It is the framework-agnostic entry point for WebMCP rendering.

sequenceDiagram
participant U as User
participant A as LLM Agent
participant MCP as MCP Server<br/>(remote data)
participant WM as WebMCP Server<br/>(local rendering)
participant C as Canvas
U->>A: "Show sales by region"
A->>MCP: query_sql({sql: "SELECT region, total FROM sales"})
MCP-->>A: [{region: "North", total: 42000}, ...]
A->>WM: widget_display({name: "chart-rich", params: {type: "bar", labels: [...], data: [...]}})
WM-->>A: {widget: "chart-rich", id: "w_a3f2"}
A->>WM: widget_display({name: "data-table", params: {columns: [...], rows: [...]}})
WM-->>A: {widget: "data-table", id: "w_b7c1"}
A-->>C: Two widgets rendered on canvas
C-->>U: Sales by region dashboard
  • MCP — retrieves the data that WebMCP displays
  • Tool Layers — WebMCP servers produce WebMcpLayer entries
  • Recipes — each WebMCP server ships recipes to guide the agent
  • widget_display — the unified tool that dispatches to the right WebMCP renderer
  • UI Widgets — the Svelte components that render widgets