checkout tool only after items are present. Understanding the lifecycle model helps you design tools that stay in sync with your application.
Registration with registerTool() and unregisterTool()
The WebMCP core API provides two methods for managing tools: registerTool() adds a single tool, and unregisterTool() removes one by name. Together, they support both initial setup and dynamic changes to the tool set.
registerTool() throws if a tool with the same name already exists. This is a deliberate design choice: name collisions indicate a bug (two parts of the application trying to own the same tool), and a silent override would make it harder to find.
Change notifications
When the tool set changes, connected agents need to know. The WebMCP testing API providesregisterToolsChangedCallback() on navigator.modelContextTesting, and the MCP-B runtime emits notifications/tools/list_changed over any connected transport.
The notification does not include the new tool list. It signals that the agent should call listTools() again if it needs the updated set. This design avoids sending large payloads on every change and lets agents decide when they care about updates.
In the MCP-B runtime, the notification is sent automatically after any registerTool or unregisterTool call. You do not need to emit it yourself.
Context replacement: the deeper story
The@mcp-b/global initialization sequence performs a context replacement that is worth understanding, because it affects how tools flow through the system.
Before @mcp-b/global runs, navigator.modelContext is either the native browser implementation or the polyfill. After initialization, navigator.modelContext is a BrowserMcpServer that wraps the original.
When you call navigator.modelContext.registerTool(tool), the BrowserMcpServer:
- Stores the tool descriptor (including the
executefunction) in its internal registry. - Creates a stripped copy of the descriptor (without
execute) and callsnative.registerTool(strippedCopy)on the underlying context.
navigator.modelContextTesting.listTools(). The testing API reads from the native/polyfill context. Without mirroring, the testing API would see nothing.
When an agent calls a tool (via transport, via callTool, or via modelContextTesting.executeTool), the BrowserMcpServer looks up the full descriptor in its own registry and invokes the execute function. The native context never executes tools directly in this configuration.
This two-registry approach means the BrowserMcpServer owns execution, while the native context owns discovery. Both are kept in sync by the mirroring logic described in Runtime Layering.
Ordering guarantees
When a tool call changes application state (and therefore changes which tools should be available), the ordering of events matters. The W3C proposal discusses a specific ordering contract for tool calls that trigger state changes:- Execute the tool and evaluate its body.
- Deliver the tool result to the agent.
- Recompute the tool catalog and emit
tools/list_changedif it changed. - Apply any navigation or DOM updates.
execute callback (step 1), so step 4 is handled by the developer’s own code.
Dynamic tools in practice
Good dynamic tool management follows a pattern: tools reflect the current application state, and the agent can rely on the tool list being accurate at any given moment. Some common patterns: Route-based tools. In a single-page application, unregister old tools and register new ones on each route transition. This keeps the tool set in sync with the current view. Role-based tools. UseregisterTool() to add privileged tools after authentication. Use unregisterTool() on logout to remove them.
Conditional tools. Register a tool only when its preconditions are met (e.g., a checkout tool that appears only when the cart is non-empty). Remove it with unregisterTool() when the precondition fails.
Cleanup. Iterate over registered tools and call unregisterTool() for each on page unload or component unmount to avoid stale tools lingering in the registry.
For principles on designing the tools themselves (naming, schemas, failure handling), see Tool Design.