diff --git a/index.bs b/index.bs index dcc00cd..c896150 100644 --- a/index.bs +++ b/index.bs @@ -52,7 +52,8 @@ Die On: warning .XXX { color: #D50606; - background: white; + /* The value #111 is what WHATWG uses in dark mode: `--xxx-bg: #111;`. */ + background: light-dark(white, #111); border: solid #D50606; } @@ -79,6 +80,11 @@ p + dl.props { margin-top: -0.5em; } } + +

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. @@ -95,14 +101,49 @@ A browser’s agent is an [=agent=] provided by or through the browse An AI platform is a provider of agentic assistants such as OpenAI’s ChatGPT, Anthropic’s Claude, or Google’s Gemini. -

Security and privacy considerations

+

Supporting concepts

- +A model context is a [=struct=] with the following [=struct/items=]: -

Accessibility considerations

+
+ : tool map + :: a [=map=] whose [=map/keys=] are [=strings=] and whose [=map/values=] are [=tool data=] + [=structs=]. +
+ +A tool data is a [=struct=] with the following [=struct/items=]: + +
+ : name + :: a [=string=] uniquely identifying a tool registered within a [=model context=]'s [=model + context/tool map=]; it is the same as the [=map/key=] identifying this object. + + : description + :: a [=string=]. + + : input schema + :: a [=string=]. + + Note: For tools registered by the imperative form of this API (i.e., + {{ModelContext/registerTool()}}), this is the stringified representation of + {{ModelContextTool/inputSchema}}. For tools registered + [declaratively](https://github.com/webmachinelearning/webmcp/pull/76), 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](https://github.com/webmachinelearning/webmcp/pull/76), 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. +

API

@@ -143,6 +184,10 @@ interface ModelContext { }; +Each {{ModelContext}} object has an associated internal context, which +is a [=model context=] [=struct=] created alongside the {{ModelContext}}. + +
navigator.{{Navigator/modelContext}}.{{ModelContext/provideContext(options)}}
@@ -181,16 +226,76 @@ The clearContext() method steps are:
-The registerTool(tool) method steps are: +The registerTool(tool) method steps are: -1. TODO: fill this out. +1. Let |tool map| be [=this=]'s [=ModelContext/internal context=]'s [=model context/tool map=]. + +1. Let |tool name| be |tool|'s {{ModelContextTool/name}}. + +1. If |tool map|[|tool name|] [=map/exists=], then [=exception/throw=] an {{InvalidStateError}} + {{DOMException}}. + +1. If either |tool name| or {{ModelContextTool/description}} is the empty string, then + [=exception/throw=] an {{InvalidStateError}} {{DOMException}}. + +1. Let |stringified input schema| be the empty string. + +1. If |tool|'s {{ModelContextTool/inputSchema}} [=map/exists=], then set |stringified input schema| + to the result of [=serializing a JavaScript value to a JSON string=], given |tool|'s + {{ModelContextTool/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 + "innputSchema: { toJSON() {return undefined;}}".

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

  4. +
+ +

Currently, the only implementation of this spec (Chromium) does not throw + exceptions in the first case above. And for the second case, Chromium throws new {{TypeError}} + exceptions, as opposed to re-throwing the original exception. We should reconcile this difference.

+
+ +1. Let |read-only hint| be true if |tool|'s {{ModelContextTool/annotations}} [=map/exists=], and if + its {{ToolAnnotations/readOnlyHint}} [=map/exists=] and is true. Otherwise, let it be false. + +1. Let |tool data| be a new [=tool data=], with the following [=struct/items=]: + + : [=tool data/name=] + :: |tool name| + + : [=tool data/description=] + :: |tool|'s {{ModelContextTool/description}} + + : [=tool data/input schema=] + :: |stringified input schema| + + : [=tool data/execute steps=] + :: steps that invoke |tool|'s {{ModelContextTool/execute}} + + : [=tool data/read-only hint=] + :: |read-only hint| + +1. Set [=this=]'s [=ModelContext/internal context=][|tool name|] to |tool data|.
-The unregisterTool(name) method steps are: +The unregisterTool(name) method steps are: -1. TODO: fill this out. +1. Let |tool map| be [=this=]'s [=ModelContext/internal context=]'s [=model context/tool map=]. + +1. If |tool map|[|name|] does not [=map/exist=], then [=exception/throw=] an {{InvalidStateError}} + {{DOMException}}. + +1. [=map/Remove=] |tool map|[|name|].
@@ -296,6 +401,19 @@ The requestUserInteraction(callba +

Declarative WebMCP

+ +This section is entirely a TODO. For now, refer to the [explainer draft](https://github.com/webmachinelearning/webmcp/pull/76). + +
+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=]. + +
+
 {
   "mcp": {
@@ -311,6 +429,16 @@ The requestUserInteraction(callba
 }
 
+

Security and privacy considerations

+ + + +

Accessibility considerations

+ +

Acknowledgements

Thanks to