webmcp (EXPERIMENTAL)

The WebMCP standard (document.modelContextnavigator.modelContext is deprecated as of Chrome 150, and this adapter still probes it) lets a page expose typed, callable tools to browser agents — but every existing integration hand-writes those tools. tosijs doesn't have to: the agent surface already knows the app's state roots, wiring, and actions, so the tool set is generated, not authored.

import { enableAgentInterface, webmcpAdapter } from 'tosijs'

// declare what the tools may reach — a bare enableAgentInterface() is
// closed, so the generated tools would refuse every path
const agent = enableAgentInterface({ expose: { roots: ['app'] } })
const mcp = webmcpAdapter(agent) // detect, generate, register
// …
mcp?.unregister()

Two layers, split like schematicSVG:

The generated set:

tool does
tosi_describe the live affordance map — start here
tosi_surface what this surface IS: version + capabilities
tosi_read serializable value at a path — scoped surfaces only
tosi_changes turn drain: final-value-per-path since your cursor — scoped surfaces only
tosi_act_<path> one named tool per discovered/declared action
tosi_write direct state writes — dev-gated (see below)

tosi_write registers only with an explicit allowWrites: true: an unvalidated write tool is an RPC endpoint with good documentation.

tosi_read and tosi_changes register only once the surface says what it exposes — expose: { roots: [...] } or expose: 'all' — or with an explicit allowReads: true. Since 1.9.0 the no-options default is closed — it exposes nothing, so those two tools would have nothing to read — and before that it was read-only over the whole registry, which a browser agent (a different principal) should not receive as a side effect of one unargumented call. The introspection tools still register in every posture: they report the shape of the surface, not its contents.

Tool names are global to the page. Where another script (or a second surface) already owns tosi_*, pass a distinct prefix — the adapter reports any generated tool the host did not take as a console.error, because a name you didn't get is a name an agent will reach someone else through.

EXPERIMENTAL. The WebMCP spec is churning; the adapter is deliberately tolerant of both registration shapes and takes an injected host for tests.