Appearance
Fresh
Imperative API
Alexandra Klepper
François Beaufort
Published: May 18, 2026, Last updated: July 1, 2026
You can use the WebMCP Imperative API to define many types of tools with standard JavaScript. Your tools can execute different functions, such as form input, site navigation, and state management.
Before using this API, read about example use cases.
Provide model context
Use the modelContext interface to register tools. Tool registration requires a name, description, and input schema with relevant properties.
Use registertool to add a single tool to the model context.
WebMCPza MakerGet order statusMore
await document.modelContext.registerTool({
name: 'toggle_layer',
description: 'Control pizza layers (sauce, cheese). Use "add", "remove", or "toggle".',
inputSchema: {
type: 'object',
properties: {
layer: { type: 'string', enum: ['sauce-layer', 'cheese-layer'] },
action: { type: 'string', enum: ['add', 'remove', 'toggle'] },
},
required: ['layer'],
},
execute: async ({ layer, action }) => {
await toggleLayer(layer, action);
return `Performed ${action || 'toggle'} on layer: ${layer}`;
},
});await document.modelContext.registerTool({
name: 'get_order_status',
description: 'Search orders in a given timeframe. Returns order number, shipping status and location',
inputSchema: {
"type": "object",
"properties": {
"timeframe": { "type": "string", "oneOf": [\
{ "type": "string", "const": "today", "title": "Today" },\
{ "type": "string", "const": "yesterday", "title": "Yesterday" },\
{ "type": "string", "const": "last_7_days", "title": "Last 7 Days" },\
{ "type": "string", "const": "last_30_days", "title": "Last 30 Days" },\
{ "type": "string", "const": "last_6_months", "title": "Last 6 Months" }],
"enum": [ "today", "yesterday", "last_7_days", "last_30_days", "last_6_months" ],
"description": "Timeframe for the order lookup." }
},
"required": [ "timeframe" ]
},
execute: async ({ timeframe }) => {
// Add your API or database logic here to fetch and return the order data as a string.
},
});You can remove a tool with AbortSignal, when passed as an optional parameter.
const addTodoTool = {
name: "addTodo",
description: "Add a new item to the to-do list",
inputSchema: {
type: "object",
properties: { text: { type: "string" } },
},
execute: async ({ text }) => {
// You should handle the persistence logic here (omitted for demo)
return `Added to-do: ${text}`;
},
annotations: {
readOnlyHint: false,
untrustedContentHint: true
},
};
const controller = new AbortController();
await document.modelContext.registerTool(addTodoTool, { signal: controller.signal });
// Unregister the tool later...
controller.abort();Discover tools
Use document.modelContext.getTools() to retrieve available tools. This asynchronous method returns an alphabetically ordered list of tools that the calling document is authorized to access.
const [tool] = await document.modelContext.getTools();
console.log(tool);
// {
// annotations: { readOnlyHint: false, untrustedContentHint: true },
// description: "Add a new item to the to-do list",
// inputSchema: '{"type":"object","properties":{"text":{"type":"string"}}}',
// name: "addTodo",
// origin: "https://example.com",
// window: Window {window: Window, self: Window, ...},
// }By default, getTools() returns only same-origin tools registered by the calling document or other same-origin documents in the frame tree. To retrieve cross-origin tools, you must explicitly list their origins in the fromOrigins option. This array only supports secure origins.
Tools from cross-origin documents are only included if:
- The hosting origin is listed in the
fromOriginsoption. - The tool has been explicitly exposed to your origin.
// https://example.com
// Get same-origin tools only
const sameOriginTools = await document.modelContext.getTools();
// Get same-origin tools plus tools from specific cross-origin documents
const allTools = await document.modelContext.getTools({
fromOrigins: ['https://partner.org']
});See the WebMCP Page Agent demo for an example of how to retrieve tools from an iframe and execute them within a web-based chat interface.
Execute tool
To manually execute a tool discovered in getTools(), call document.modelContext.executeTool() with input arguments as a valid JSON string. This asynchronous method returns the result of the tool execution, or null when a navigation is triggered.
const result = await document.modelContext.executeTool(tool, '{"text": "Buy milk"}');
console.log(result);
// 'Added to-do: Buy milk'You can cancel a pending tool execution with AbortSignal, when passed as an optional parameter.
const controller = new AbortController();
document.modelContext.executeTool(tool, '{"text": "Buy milk"}', {
signal: controller.signal,
});
// Cancel tool execution later...
controller.abort();Events
Frames can listen for the toolchange event on document.modelContext to be notified when the list of available tools has changed.
document.modelContext.addEventListener("toolchange", (event) => {
// Tools have changed.
});Cross-origin iframes
WebMCP supports cross-origin iframes that use both permission policies and explicit origin gating.
Permissions policy
Tool registration is disabled by default in cross-origin iframes. A page must delegate access using the tools Permissions Policy:
<iframe src="https://example.com" allow="tools"></iframe>Origin exposure
Tools are unavailable to cross-origin documents by default. You can use the exposedTo array within registerTool to list specific origins allowed to view and execute a tool. This array only supports secure origins.
// https://partner.org
await document.modelContext.registerTool({
name: 'my_shared_tool',
description: 'Shared across origins',
// ...
}, {
exposedTo: ['https://example.com']
});Angular support
Angular has experimental support for WebMCP. If your application is already written with Angular, you can register tools tied to the application's dependency injection lifecycle and turn your Signal Forms into WebMCP tools.
Engage and share feedback
WebMCP is under active discussion and subject to change in the future. If you try this API and have feedback, we'd love to hear it.
- Read the WebMCP explainer, raise questions and participate in discussion.
- Read WebMCP best practices.
- Review the implementation for Chrome on Chrome Status.
- Join the early preview program for an early look at new APIs and access to our mailing list.
- If you have feedback on Chrome's implementation, file a Chromium bug.