← WebMCPCONTENT HISTORY

Update to WebMCP

Snapshot Sep 30, 2026 · 23:01 UTC · version 0.1.1

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Implement task-completing imperative WebMCP tools using document.modelContext.registerTool.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 298
    }
  ],
  "name": "webmcp-site-author",
  "skill_md_contents": "---\nname: webmcp-site-author\ndescription: Implement task-completing imperative WebMCP tools using document.modelContext.registerTool.\n---\n\n# WebMCP\n\nWebMCP is a proposed browser standard that lets websites expose their functionality directly to AI agents as structured tools.\n\nIt exposes declarative and imperative APIs, and the full specification can be found here https://webmachinelearning.github.io/webmcp/\n\nThe ChatGPT implementation only supports the imperative inerface\n\n## API structure\n\n```ts\ninterface Document {\n  readonly modelContext?: ModelContext; // Page-scoped registry; feature-detect support.\n}\n\ninterface ModelContext {\n  registerTool(\n    tool: {\n      name: string; // Unique, stable action identifier.\n      description: string; // What the tool does and when to use it.\n      inputSchema: object; // JSON Schema describing accepted input.\n      execute(input: unknown): unknown | Promise<unknown>; // Validate, act, return result.\n      title?: string; // Human-readable display label.\n      annotations?: {\n        // Behavioral hints, not security boundaries.\n        readOnlyHint?: boolean; // True only when no state changes.\n        untrustedContentHint?: boolean; // True for external or user-generated output.\n      };\n    },\n    options?: {\n      signal?: AbortSignal; // Abort to unregister this tool.\n    },\n  ): void | Promise<void>; // Register one tool for this page.\n}\n```\n\n## Example call site\n\n```ts\nconst context =\n  typeof document === \"undefined\" ? undefined : document.modelContext;\nif (!context?.registerTool) return;\nconst lifecycle = new AbortController();\n\ntry {\n  void Promise.resolve(\n    context.registerTool(\n      {\n        name: \"create_booking\",\n        title: \"Create booking\",\n        description:\n          \"Book the selected slot and update the visible reservation.\",\n        inputSchema: {\n          type: \"object\",\n          properties: { slotId: { type: \"string\" } },\n          required: [\"slotId\"],\n          additionalProperties: false,\n        },\n        annotations: { readOnlyHint: false, untrustedContentHint: false },\n        async execute(input) {\n          const booking = await bookSlot(validateInput(input));\n          return { id: booking.id, status: \"confirmed\" };\n        },\n      },\n      { signal: lifecycle.signal },\n    ),\n  ).catch(reportError);\n} catch (error) {\n  reportError(error);\n}\n\nreturn () => lifecycle.abort();\n```\n\n## Tool-design rules\n\n- Distinguish **read**, **navigate/start**, **stage/configure**, and **complete** in names and descriptions. `create_event` means an event is created; `start_event_creation` only opens or prepares a flow. Never conceal side effects in an ambiguous verb.\n- Prefer batched APIs where possible, rather than requiring clients to write loops.\n- Return concise JSON-serializable results only after the action and visible state finish updating.\n- Register once client-side, clean up with `AbortSignal`, and handle unsupported browsers and registration failures.\n"
}

SHA-256 of public snapshot: c5789b969254daa6cb63f7f6fb83c8854e372ee7ff15c195ebfb8f063e8ba2dc