WebMCP

Draft Community Group Report,

More details about this document
This version:
https://webmachinelearning.github.io/webmcp
Issue Tracking:
GitHub
Editors:
(Microsoft)
(Google)
(Google)

Abstract

The WebMCP API enables web applications to provide JavaScript-based tools to AI agents.

Status of this document

This specification was published by the Web Machine Learning Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

WebMCP API is a new JavaScript interface that allows web developers to expose their web application functionality as “tools” - JavaScript functions with natural language descriptions and structured schemas that can be invoked by agents, browser’s agents, and assistive technologies. Web pages that use WebMCP can be thought of as Model Context Protocol [MCP] servers that implement tools in client-side script instead of on the backend. WebMCP enables collaborative workflows where users and agents work together within the same web interface, leveraging existing application logic while maintaining shared context and user control.

2. Terminology

An agent is an autonomous assistant that can understand a user’s goals and take actions on the user’s behalf to achieve them. Today, these are typically implemented by large language model (LLM) based AI platforms, interacting with users via text-based chat interfaces.

A browser’s agent is an agent provided by or through the browser that could be built directly into the browser or hosted by it, for example, via an extension or plug-in.

An AI platform is a provider of agentic assistants such as OpenAI’s ChatGPT, Anthropic’s Claude, or Google’s Gemini.

3. Supporting concepts

A model context is a struct with the following items:

tool map

a map whose keys are strings and whose values are tool definition structs.

A tool definition is a struct with the following items:

name

a string uniquely identifying a tool registered within a model context’s tool map; it is the same as the key identifying this object.

description

a string.

input schema

a string.

Note: For tools registered by the imperative form of this API (i.e., registerTool()), this is the stringified representation of inputSchema. For tools registered declaratively, this will be a stringified JSON Schema object created by the synthesize a declarative JSON Schema object algorithm. [JSON-SCHEMA]

execute steps

a set of steps to invoke the tool.

Note: For tools registered imperatively, these steps will simply invoke the supplied ToolExecuteCallback callback. For tools registered declaratively, this will be a set of "internal" steps that have not been defined yet, that describe how to fill out a form and its form-associated elements.

read-only hint

a boolean, initially false.

4. API

The Navigator interface is extended to provide access to the ModelContext.

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ModelContext modelContext;
};

Each Navigator object has an associated modelContext, which is a ModelContext instance created alongside the Navigator.

The modelContext getter steps are to return this’s modelContext.

4.2. ModelContext Interface

The ModelContext interface provides methods for web applications to register and manage tools that can be invoked by agents.

[Exposed=Window, SecureContext]
interface ModelContext {
  undefined registerTool(ModelContextTool tool);
  undefined unregisterTool(DOMString name);
};

Each ModelContext object has an associated internal context, which is a model context struct created alongside the ModelContext.

navigator.modelContext.registerTool(tool)

Registers a single tool without clearing the existing set of tools. The method throws an error, if a tool with the same name already exists, or if the inputSchema is invalid.

navigator.modelContext.unregisterTool(name)

Removes the tool with the specified name from the registered set.

The registerTool(tool) method steps are:
  1. Let tool map be this’s internal context’s tool map.

  2. Let tool name be tool’s name.

  3. If tool map[tool name] exists, then throw an InvalidStateError DOMException.

  4. If either tool name or description is the empty string, then throw an InvalidStateError DOMException.

  5. Let stringified input schema be the empty string.

  6. If tool’s inputSchema exists, then set stringified input schema to the result of serializing a JavaScript value to a JSON string, given tool’s inputSchema.

    The serialization algorithm above throws exceptions in the following cases:

    1. Throws a new TypeError when the backing "JSON.stringify()" yields undefined, e.g., "inputSchema: { toJSON() {return HTMLDivElement;}}", or "inputSchema: { toJSON() {return undefined;}}".

    2. Re-throws exceptions thrown by "JSON.stringify()", e.g., when "inputSchema" is an object with a circular reference, etc.

  7. Let read-only hint be true if tool’s annotations exists and its readOnlyHint is true. Otherwise, let it be false.

  8. Let tool definition be a new tool definition, with the following items:

    name

    tool name

    description

    tool’s description

    input schema

    stringified input schema

    execute steps

    steps that invoke tool’s execute

    read-only hint

    read-only hint

  9. Set this’s internal context[tool name] to tool definition.

The unregisterTool(name) method steps are:
  1. Let tool map be this’s internal context’s tool map.

  2. If tool map[name] does not exist, then throw an InvalidStateError DOMException.

  3. Remove tool map[name].

4.2.1. ModelContextTool Dictionary

The ModelContextTool dictionary describes a tool that can be invoked by agents.

dictionary ModelContextTool {
  required DOMString name;
  required DOMString description;
  object inputSchema;
  required ToolExecuteCallback execute;
  ToolAnnotations annotations;
};

dictionary ToolAnnotations {
  boolean readOnlyHint = false;
};

callback ToolExecuteCallback = Promise<any> (object input, ModelContextClient client);
tool["name"]

A unique identifier for the tool. This is used by agents to reference the tool when making tool calls.

tool["description"]

A natural language description of the tool’s functionality. This helps agents understand when and how to use the tool.

tool["inputSchema"]

A JSON Schema [JSON-SCHEMA] object describing the expected input parameters for the tool.

tool["execute"]

A callback function that is invoked when an agent calls the tool. The function receives the input parameters and a ModelContextClient object.

The function can be asynchronous and return a promise, in which case the agent will receive the result once the promise is resolved.

tool["annotations"]

Optional annotations providing additional metadata about the tool’s behavior.

The ToolAnnotations dictionary provides optional metadata about a tool:

readOnlyHint, of type boolean, defaulting to false

If true, indicates that the tool does not modify any state and only reads data. This hint can help agents make decisions about when it is safe to call the tool.

4.2.2. ModelContextClient Interface

The ModelContextClient interface represents an agent executing a tool provided by the site through the ModelContext API.

[Exposed=Window, SecureContext]
interface ModelContextClient {
  Promise<any> requestUserInteraction(UserInteractionCallback callback);
};

callback UserInteractionCallback = Promise<any> ();
client.requestUserInteraction(callback)

Asynchronously requests user input during the execution of a tool.

The callback function is invoked to perform the user interaction (e.g., showing a confirmation dialog), and the promise resolves with the result of the callback.

The requestUserInteraction(callback) method steps are:
  1. TODO: fill this out.

4.3. Declarative WebMCP

This section is entirely a TODO. For now, refer to the explainer draft.

The synthesize a declarative JSON Schema object algorithm, given a form element form, runs the following steps. They return a map representing a JSON Schema object. [JSON-SCHEMA]
  1. TODO: Derive a conformant JSON Schema object from form and its form-associated elements.

5. Security and privacy considerations

6. Accessibility considerations

7. Acknowledgements

Thanks to Brandon Walderman, Leo Lee, Andrew Nolan, David Bokan, Khushal Sagar, Hannah Van Opstal, Sushanth Rajasankar for the initial explainer, proposals and discussions that established the foundation for this specification.

Also many thanks to Alex Nahas and Jason McGhee for sharing early implementation experience.

Finally, thanks to the participants of the Web Machine Learning Community Group for feedback and suggestions.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[JSON-SCHEMA]
JSON Schema: A Media Type for Describing JSON Documents. URL: https://json-schema.org/draft/2020-12/json-schema-core.html
[MCP]
Model Context Protocol (MCP) Specification. URL: https://modelcontextprotocol.io/specification/latest
[WAI-ARIA-1.2]
Joanmarie Diggs; et al. Accessible Rich Internet Applications (WAI-ARIA) 1.2. URL: https://w3c.github.io/aria/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL Index

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ModelContext modelContext;
};

[Exposed=Window, SecureContext]
interface ModelContext {
  undefined registerTool(ModelContextTool tool);
  undefined unregisterTool(DOMString name);
};

dictionary ModelContextTool {
  required DOMString name;
  required DOMString description;
  object inputSchema;
  required ToolExecuteCallback execute;
  ToolAnnotations annotations;
};

dictionary ToolAnnotations {
  boolean readOnlyHint = false;
};

callback ToolExecuteCallback = Promise<any> (object input, ModelContextClient client);

[Exposed=Window, SecureContext]
interface ModelContextClient {
  Promise<any> requestUserInteraction(UserInteractionCallback callback);
};

callback UserInteractionCallback = Promise<any> ();