Goal
Expose any <.form> in a LiveView as an agent-callable tool via the WebMCP declarative API, with no separate tool registration step. The component tree IS the tool surface, same principle the terminal-side MCP integration already follows.
Spec reference (pin this commit, the API is moving): https://developer.chrome.com/docs/ai/webmcp/declarative-api
Scope
In:
- A
<.tool_form> Phoenix.Component wrapping <.form> that emits the declarative WebMCP attributes.
- A
<.tool_field> helper for field-level annotation.
- A LiveView JS hook bridging
toolactivated and toolcancel to pushEvent.
- A demo LiveView at
/demo/web_mcp with one form an agent can invoke.
- Component tests verifying rendered HTML.
- README section under
packages/raxol_liveview/ covering setup, Chrome flag, and the WebMCP-experimental caveat.
Out:
- Imperative WebMCP API (skip the
registerTool JS path entirely).
- Cross-browser support (Chrome 146+ Canary only).
- Multi-step agent flows. One form, one invocation.
- Server-side MCP wiring (already covered by
raxol_mcp).
API sketch
<.tool_form
name="search_users"
description="Search the user directory by name or email."
for={@form}
phx-submit="search"
auto_submit>
<.tool_field
field={@form[:query]}
title="Query"
description="Name or email to search for." />
</.tool_form>
Maps to:
<form toolname="search_users"
tooldescription="Search the user directory by name or email."
toolautosubmit
phx-submit="search">
<input name="query"
toolparamtitle="Query"
toolparamdescription="Name or email to search for." />
</form>
JS hook
A RaxolWebMCP hook attached to the form element. On toolactivated, push {:tool_activated, %{tool: name}} to the LiveView. On toolcancel, push {:tool_cancelled, %{tool: name}}. Apps that want to react (highlight the form, lock other UI, log telemetry) handle the event in handle_event/3.
Risks worth calling out in the PR
- WebMCP is Chrome Canary only. The demo route should print the flag instructions and degrade gracefully (the form still works as a normal form).
- LiveView's
phx-change may fire while the agent is populating fields. Verify the form ends in the expected state and document any required phx-change patterns.
- The spec changes. Pin the doc URL by commit / date in the README and treat this as experimental.
Acceptance
<.tool_form> and <.tool_field> exist in Raxol.LiveView.WebMCP.Components with @spec annotations.
- JS hook ships in
packages/raxol_liveview/priv/static/ and is documented in the README.
/demo/web_mcp route mounted in the demo app.
- Component tests cover attribute pass-through, required-attribute validation, and default behavior when WebMCP attrs are absent.
- Manual test passes: open Chrome 146 Canary with
chrome://flags/#enable-webmcp-testing enabled, navigate to the demo, invoke via a WebMCP-aware agent, observe the form fill and submit, observe toolactivated arriving in the LiveView.
- README section explaining setup, the flag, and the experimental status.
File layout
packages/raxol_liveview/
lib/raxol/live_view/web_mcp.ex # top-level module + docs
lib/raxol/live_view/web_mcp/components.ex # <.tool_form>, <.tool_field>
priv/static/web_mcp_hook.js # the JS hook
test/raxol/live_view/web_mcp/components_test.exs
README.md # add WebMCP section
Plus a demo route under whichever app currently hosts the LiveView examples.
Out of band
If the agent runner hits a wall on the spec (anything that contradicts the linked doc), stop and surface it. We don't want to land code that drifts from the standard.
Goal
Expose any
<.form>in a LiveView as an agent-callable tool via the WebMCP declarative API, with no separate tool registration step. The component tree IS the tool surface, same principle the terminal-side MCP integration already follows.Spec reference (pin this commit, the API is moving): https://developer.chrome.com/docs/ai/webmcp/declarative-api
Scope
In:
<.tool_form>Phoenix.Component wrapping<.form>that emits the declarative WebMCP attributes.<.tool_field>helper for field-level annotation.toolactivatedandtoolcanceltopushEvent./demo/web_mcpwith one form an agent can invoke.packages/raxol_liveview/covering setup, Chrome flag, and the WebMCP-experimental caveat.Out:
registerToolJS path entirely).raxol_mcp).API sketch
Maps to:
JS hook
A
RaxolWebMCPhook attached to the form element. Ontoolactivated, push{:tool_activated, %{tool: name}}to the LiveView. Ontoolcancel, push{:tool_cancelled, %{tool: name}}. Apps that want to react (highlight the form, lock other UI, log telemetry) handle the event inhandle_event/3.Risks worth calling out in the PR
phx-changemay fire while the agent is populating fields. Verify the form ends in the expected state and document any requiredphx-changepatterns.Acceptance
<.tool_form>and<.tool_field>exist inRaxol.LiveView.WebMCP.Componentswith@specannotations.packages/raxol_liveview/priv/static/and is documented in the README./demo/web_mcproute mounted in the demo app.chrome://flags/#enable-webmcp-testingenabled, navigate to the demo, invoke via a WebMCP-aware agent, observe the form fill and submit, observetoolactivatedarriving in the LiveView.File layout
Plus a demo route under whichever app currently hosts the LiveView examples.
Out of band
If the agent runner hits a wall on the spec (anything that contradicts the linked doc), stop and surface it. We don't want to land code that drifts from the standard.