WebMCP types
TypeScript types for the preview WebMCP surface (document.modelContext): what Chrome ships plus what the polyfill adds.
TypeScript types for the preview WebMCP surface (document.modelContext): what Chrome ships plus what the polyfill adds. Reach for them when you read tools, call registerTool yourself or listen to the lifecycle events. Anything that differs between Chrome and the polyfill is optional.
Import
import type {
JSONSchema,
ModelContext,
ModelContextExecuteOptions,
ModelContextTool,
ModelContextToolInfo,
ModelContextToolResult,
ToolEvent,
} from "@webmcp-agents/core";
The types are declared as globals and re-exported by name, so other packages can import them explicitly, which also pulls the global declarations into their emitted .d.ts.
Example
Read a result’s text, list the page’s tools and listen for calls.
import type {
ModelContextToolInfo,
ModelContextToolResult,
ToolEvent,
} from "@webmcp-agents/core";
/** The first text of a result, or "" when it has none. */
export const textOf = (result: ModelContextToolResult): string =>
result.content.find((part) => part.type === "text")?.text ?? "";
/** Every tool the page has, by name. */
export async function toolNames(): Promise<string[]> {
const tools: ModelContextToolInfo[] =
(await document.modelContext?.getTools()) ?? [];
return tools.map((tool) => tool.name);
}
// Chrome 156: events are on document.modelContext, not on window.
document.modelContext?.addEventListener(
"toolactivated",
(e: ToolEvent) => console.debug("an agent called", e.toolName),
);
Options
Each type’s members. Optional members (?) differ between Chrome and the polyfill or between Chrome versions.
JSONSchema
type JSONSchema = { [key: string]: unknown }: a JSON Schema object, as WebMCP carries tool parameters.
ModelContext
What document.modelContext is: an EventTarget with these members.
| Name | Type | Default | Description |
|---|---|---|---|
registerTool |
(tool: ModelContextTool, options?: { signal?: AbortSignal }) => void |
required | Make a tool callable by agents. Aborting options.signal unregisters it. Prefer registerWebTool, which adds validation, confirmation and result handling. |
unregisterTool |
(name: string) => void |
optional | Remove a tool by name, when the browser has it. |
getTools |
() => Promise<ModelContextToolInfo[]> |
required | The tools registered right now. Chrome serialises each inputSchema to a JSON string. |
executeTool |
(tool: ModelContextToolInfo | string, args?: Record<string, unknown> | string, options?: { signal?: AbortSignal }) => Promise<ModelContextToolResult | string> |
required | Call a tool. Chrome: executeTool(toolFromGetTools, args), with args an object in Chrome 156 and a JSON string in Chrome 150, and a result that may be a JSON string. Polyfill: executeTool(name, argsObject) resolving to a result object. Aborting options.signal cancels the pending call. From library UI use executeTool, which hides the difference. |
cancelTool |
(name: string) => boolean |
optional | Non-standard, polyfill only: cancel a call someone else started (the devtools). Use executeTool’s signal for your own. |
ontoolchange |
((ev: Event) => void) | null |
optional | Handler for toolchange: the set of tools changed. |
ontoolactivated |
((ev: ToolEvent) => void) | null |
optional | Handler for toolactivated: a tool run started. Present from Chrome 156; earlier builds dispatch the event on window. |
ontoolcancel |
((ev: ToolEvent) => void) | null |
optional | Handler for toolcancel. Present from Chrome 156; earlier builds dispatch the event on window. |
addEventListener |
typed for "toolchange", "toolactivated", "toolcancel" |
required | Listen to the three events with their event types. |
ModelContextTool<Args>
A tool as passed to registerTool. Args defaults to Record<string, unknown>.
| Name | Type | Default | Description |
|---|---|---|---|
name |
string |
required | The tool’s name, which agents call it by. |
title |
string |
optional | A human name (Chrome 156 and later). |
description |
string |
optional | What the tool does and when to use it: the agent decides from this text. |
inputSchema |
JSONSchema |
optional | The parameters, as a JSON Schema object. |
annotations |
Record<string, unknown> |
optional | Hints such as readOnlyHint and destructiveHint. |
execute |
(args: Args, options: ModelContextExecuteOptions) => unknown |
required | Runs the call. Its return value is the agent’s answer. |
ModelContextToolInfo
A tool as returned by getTools().
| Name | Type | Default | Description |
|---|---|---|---|
name |
string |
required | The tool’s name. |
title |
string |
optional | A human name, when the browser has one. |
description |
string |
optional | The tool’s description. |
inputSchema |
JSONSchema | string |
optional | The parameters. Native Chrome returns a JSON string; the polyfill an object. |
annotations |
Record<string, unknown> |
optional | The tool’s hints. |
ModelContextExecuteOptions
| Name | Type | Default | Description |
|---|---|---|---|
signal |
AbortSignal |
required | Aborts when the call is cancelled. Pass it to your fetches. |
ModelContextToolResult
What a call answers with.
| Name | Type | Default | Description |
|---|---|---|---|
content |
Array<{ type: string; text?: string; [key: string]: unknown }> |
required | The answer, as MCP content parts; text parts have type: "text" and a text. |
isError |
boolean |
optional | True for a failed call. |
structuredContent |
Record<string, unknown> |
optional | MCP structured output. A failed call may carry { error: { code, retryable } }; see toolError. |
ToolEvent
Dispatched as toolactivated and toolcancel; extends Event.
| Name | Type | Default | Description |
|---|---|---|---|
toolName |
string |
required | The name of the tool the event concerns. |
Global augmentations
Importing @webmcp-agents/core (even for types) also declares:
| Global | Addition |
|---|---|
Document |
readonly modelContext?: ModelContext |
WindowEventMap |
toolactivated: ToolEvent, toolcancel: ToolEvent (Chrome before 156 dispatches them on window) |
ModelContextEventMap |
toolchange: Event, toolactivated: ToolEvent, toolcancel: ToolEvent |
SubmitEvent |
readonly agentInvoked?: boolean and respondWith?(result: Promise<unknown>): void, for declarative tools: an agent-driven submit can answer the agent |
Notes
- WebMCP is an origin-trial API whose shapes move: it went from
navigator.modelContexttodocument.modelContext, and its events moved fromwindowtodocument.modelContextin Chrome 156. - Native
getTools()returnsinputSchemaas a string; parse it before reading properties. - Use
executeToolinstead ofdocument.modelContext.executeToolfrom library UI: the argument and result shapes differ by Chrome version. - Only
@webmcp-agents/core(which holds the polyfill), the devtools and the chat touchdocument.modelContext; keep feature detection (isWebMCPAvailable) there.
See also
- How it works, where WebMCP sits
executeTool, calling tools across Chrome buildstoModelContextTool, aWebToolas aModelContextToolisWebMCPAvailable, feature detection