@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
supported: false, registers nothing and throws nothing.
The loop
- The person opens the authoring page in ChatGPT Desktop’s browser (or a flagged Chrome) and asks for a widget.
- The agent calls
widgentic_widget_draft_getto see what is open, thenwidgentic_widget_draft_loadwith 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. - 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. - 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 (defaultwidgentic); 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,DevToolsWebMCPSupportandnavigator.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 installsdocument.modelContextand defers to a native one) beforeexposeDesigners; the resolver finds whatever the page has.
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.