FrontMcpProvider registers it with the server through server.registerTool(), so it is listed like any other tool, runs through the server’s tools:call-tool flow (plugin hooks, authorities, quota and availableWhen apply), reaches every client — including in-browser agents through the WebMCP plugin — and connected clients get notifications/tools/list_changed when it appears or goes away.
useDynamicTool
Registers an MCP tool for the lifetime of the component. Supports both zod schemas (recommended) and raw JSON Schema.With Zod Schema (Recommended)
schema is provided:
- The schema is converted to JSON Schema automatically via
toJSONSchemafromzod/v4 - Input is validated via
safeParsebefore reaching yourexecutecallback - Invalid input returns an error
CallToolResultwith issue details - The
executecallback receives fully typed, validated args
With JSON Schema (Backward Compat)
Options
Name Conflicts
Dynamic tool names share the server’s namespace. A dynamic tool whose name a server tool (or another provider’s dynamic tool) already has is not registered: the provider reports it through itsonError prop, or with a console.warn when there is none, and the component keeps rendering. Names must be 1–64 characters. Registering the tool again (a remount, say) tries it again.
Servers With Several Apps
A dynamic tool joins one of the server’s apps, whose plugin hooks then apply to it. A server made withcreate() has a single app, so there is nothing to choose. A server with several local apps (FrontMcpInstance.createDirect({ apps: [...] })) refuses a tool that doesn’t say which app it joins, so name the app once per server on the provider. That covers every dynamic tool: useDynamicTool, mcpComponent, store actions and useApiClient.
dynamicToolApps is keyed by server name: the primary server goes by the provider’s name ('default' unless set), and each entry of servers by its key. A tool can name its own app instead, with useDynamicTool({ ..., app: 'billing' }).
Offering a Tool Only to In-Browser Agents
With the WebMCP plugin installed,availableWhen decides which callers see a tool:
Conditional Registration
Useenabled to conditionally register/unregister tools based on application state:
Stale Closure Prevention
The execute function is stored in a ref internally, so it always captures the latest closure values. You don’t need to memoize it.Execution
A call runs yourexecute through the server’s flows, but your code itself runs outside the server’s request turn. In a browser build (which has no AsyncContext, so the server serves one request at a time) a tool that calls the server back or waits on the network does not block other requests.
useDynamicResource
Registers an MCP resource for the lifetime of the component.Options
useComponentTree
Exposes the DOM subtree under a ref as a JSON MCP resource. Useful for giving agents visibility into the rendered component hierarchy.Options
Output Format
The resource returns a JSON tree withcomponent, tag, children, and optional props:
data-component attributes use that value as component. Others fall back to the tag name.
Mount/Unmount Lifecycle
Dynamic tools and resources follow React’s effect lifecycle:- Mount: The tool/resource is registered with the
DynamicRegistry; the provider registers tools with the server - Update: If dependencies change, the old registration is cleaned up and a new one is created
- Unmount: The tool/resource is automatically unregistered (and the tool removed from the server)