@agent-surface/webmcp
v0.26.0
Published
[Experimental] WebMCP (navigator.modelContext) transport adapter for agent-surface
Maintainers
Readme
@agent-surface/webmcp
Experimental. The WebMCP (
navigator.modelContext) surface area, permission model, and lifecycle are unstable; this adapter tracks them and absorbs the drift so nothing WebMCP-shaped leaks into@agent-surface/core. The application model stays in agent-surface — WebMCP is strictly transport/discovery.
WebMCP transport adapter for agent-surface: one wire-named tool per available capability, reconciled on every surface-changed (incremental registerTool/unregisterTool when the browser has them, a full provideContext otherwise). Unavailable capabilities are not registered (WebMCP has no disabled state today, so the availability reason is lost on this transport; accepted limitation). Observations and read-only effects carry annotations.readOnlyHint. The user agent is treated as the least-trusted consumer: scope the adapter and keep confirmations governed by the registry.
Docs: https://agent-surface.dev
Install
pnpm add @agent-surface/core @agent-surface/webmcpUse
import { createWebMcpAdapter } from "@agent-surface/webmcp";
const adapter = createWebMcpAdapter({
snapshotContext: { scope: ["devices"] }, // least-trusted peer: scope it
});
adapter.start({ registry, consumer: { id: "browser-agent", kind: "webmcp" } });If navigator.modelContext is absent, start() resolves and does nothing (feature-detect, never polyfill). Capability errors ride in tool content with code/retry/details preserved, never as protocol-level errors. stop() withdraws every tool the adapter exposed and can run repeatedly.
Confirmations complete within one tool call. By default the call waits for your host's confirmation UI to resolve the pending record, then retries with the evidence; denial or expiry returns CONFIRMATION_INVALID, and stop() aborts the wait. To prompt through WebMCP's client.requestUserInteraction instead, pass host UI; the registry still decides:
createWebMcpAdapter({
confirm: (request) => showConfirmDialog(request.summary),
});WebMCP does not revoke the agent's DOM access, and the confirmation UI lives in the same page, so the server stays the real gate.
Only the imperative API is used. The declarative API (DOM forms as tools) is a non-goal: capabilities must be compiler-authorized, not derived from rendered DOM.
Targeted WebMCP revision
The W3C Web Machine Learning CG draft (webmachinelearning/webmcp) as exposed by the Chrome early preview (Chrome 146+, chrome://flags/#enable-webmcp-testing). Assumed surface:
| Member | Use |
|---|---|
| modelContext.provideContext({ tools }) | required; fallback full-set replacement |
| modelContext.clearContext() | optional; stop() on the fallback path |
| modelContext.registerTool(tool) / unregisterTool(name) | optional, feature-detected together |
| tool { name, description, inputSchema, annotations?: { readOnlyHint? }, execute(input, client) } | tool shape |
| client.requestUserInteraction(callback) | optional; in-page confirmation |
Keep this table in sync with docs/09.
Full specification: docs/09.
MIT © Wiseair S.r.l.
