Skip to main content
widgentic has always had two authors who never met on one screen: an agent that learns the authoring contract over MCP and drafts JSON, and a person who imports that JSON into a designer, fixes it and saves. WebMCP — an experimental W3C standard shipping in ChatGPT Desktop’s browser and in the Chrome 149+ / Edge 150 origin trial — lets a page register tools the browser’s agent calls under the person’s own session. @widgentic/webmcp registers the designers as those tools.
Beta. The API may change in minor versions before 1.0, and browser support is moving. Verified against the specification’s document.modelContext shape on 2026-09-02.

One call after mounting

Sources are getters, resolved on every tool call, because hosts remount designers when the person switches tabs. A getter may bring its section on screen first — then “the agent asked for the theme designer” is something the person watches happen. In a browser without a model context the call resolves with supported: false, registers nothing and throws nothing.

The loop

  1. The person opens the authoring page in ChatGPT Desktop’s browser (or a flagged Chrome) and asks for a widget.
  2. The agent calls widgentic_widget_draft_get to see what is open, then widgentic_widget_draft_load with a definition. The designer validates it exactly as its Import panel would: applied, with the designer’s diagnostics — or refused, with the designer’s own error strings.
  3. Fix, restyle, ask again: example data (widgentic_widget_example_data_set), preview theme (widgentic_widget_theme_set), a theme entry, a shared schema, an action.
  4. The person saves. No tool persists anything; the host’s save controls remain the only write path. On the MCP endpoint’s next render_widget, any agent with a key renders the widget the two of them made.

The tools

Twelve tools under a configurable prefix (default widgentic); only the designers you supply a source for get tools, the token reference is always present. Read tools carry annotations.readOnlyHint, so agents run them without a confirmation step. Every result is MCP-shaped text content carrying one JSON document with a boolean ok. Refusals are results, never rejections: NOT_MOUNTED, INVALID_INPUT (naming the argument) and REJECTED (with the designer’s errors).

Browsers, flags and polyfills

  • Native: document.modelContext (the specification, ChatGPT Desktop) is resolved first, navigator.modelContext (Chrome origin trial) second; an explicit { modelContext } option wins over both.
  • Chrome / Edge without a token: chrome://flags/#enable-webmcp-testing, or --enable-features=WebMCPTesting,DevToolsWebMCPSupport and navigator.modelContextTesting.getTools() / executeTool() for driverless checks. With an origin-trial token on your page, no flag is needed on your origin.
  • Polyfills: nothing is bundled — a polyfill supplies the API, not the agent, and cannot make Firefox or Safari agent-capable. To reach extension-based agents, load one such as @mcp-b/webmcp-polyfill (it installs document.modelContext and defers to a native one) before exposeDesigners; the resolver finds whatever the page has.
Tools register on the top-level page only; browsers do not read tools from iframes.

Your own tools

registerTools(tools, { modelContext?, signal? }) registers any descriptors in the same shape under one abort signal, and exposeDesigners takes extra ones as { tools }. designerTools(sources, { prefix }) returns the descriptors without registering. Build results with okResult() / failResult() so agents see one vocabulary. The self-host example (Self-hosting) is the reference host: its authoring page registers the tools, and its web service can forward /mcp so one origin serves both surfaces.