feat(client): expose agent-flagged client RPC functions over WebMCP - #366
Conversation
◈ PR Lens
Architecture 6 components touched across 4 lanes. Inside the changed components — 2 viewsComponent view — WebMCP Client Integration Internal modules bridging browser-side RPC functions to the WebMCP model context. Component view — Inspector Client Surface Components and modules powering the inspector's Client tab and function metadata projection. Data flow
The other flows — 1 sequence
Drill down
|
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…ection swallow, Chromium fake strictness
What
The
agentfield on an RPC function definition now also works on the browser side, and the inspector can inspect that surface.Client RPC over WebMCP (
devframe/client): a client RPC function registered onrpc.client(or via a scopedclient.scope(ns).rpc.register(...)) that carries anagentfield is mirrored onto the page's WebMCP model context (document.modelContext/navigator.modelContext) as a callable tool, so in-page and browser-integrated agents can drive browser-side functionality directly.Inspector Client tab (
@devframes/plugin-inspect): a new tab inspecting the browser side of the connection — every client RPC function (same metadata, schemas, and inline invoke as the Functions tab, executed locally in the page) and the page's WebMCP tools (read live via the model context'sgetTools()when the browser supports discovery, executable viaexecuteTool(); projected fromagent-flagged client functions otherwise).How
registerWebMcpTools(collector)indevframe/client: projectsagent-flagged definitions onto the model context using the exact pieces the node-side MCP adapter uses (toAgentToolNamewire names,argsToJsonSchemaarg0/argNinput schemas,coerceAgentPositionalArgs, safety →readOnlyHint/destructiveHint), keeps the tool set in sync with laterregister/updatecalls, and returns a dispose. Handles both WebMCP unregistration generations (AbortSignalper the current draft, legacyunregister()handles).connectDevframe()wires it automatically (no-op when the browser provides no model context); the newwebmcp: falseoption opts out, andclose()unregisters the tools.agentfield are never exposed, andagentstill requiresjsonSerializable: true.WebMcpModelContexttype carries the draft'sgetTools()/executeTool()discovery surface; the inspector handles both wire generations (Chromium's current build carries args/results/schemas as JSON strings; the spec draft uses dictionaries — the string form is tried first, and a dictionary implementation rejects it during argument conversion before the tool runs, so the fallback is side-effect free).plugins/inspect/src/function-info.ts, shared by the node-sidelist-functionsRPC and the browser-side Client tab so the two listings cannot drift.webmcprow in the Browser-Side API reference, Client tab in the inspect plugin page; API snapshots updated; ClientView storybook stories added.Verified end to end in Chromium's live WebMCP implementation (tool registered by the page appears on the Client tab with origin + schema, and invoking it through
executeTool()renders the MCP result). No new dependencies.Created with the help of an agent.