Skip to content

Repository files navigation

WebMCP polyfill

A document-local registration and discovery implementation of the WebMCP draft, using the official webmcp-types. This is an initial implementation for review, not a complete implementation of the proposal.

Use

Serve the page over HTTPS with the Origin-Agent-Cluster: ?1 response header. This is required for the origin-keyed agent cluster expected by the draft; Firefox and WebKit need the explicit header in our browser tests. The runtime rejects operations with SecurityError when the browser reports originAgentCluster === false (except file: documents).

Import the auto-install entry before registering tools:

import "webmcp-polyfill/auto";

const context = document.modelContext;
if (!context) throw new Error("WebMCP requires a secure browser context");

const registration = new AbortController();
await context.registerTool(
  {
    name: "greet",
    description: "Greet someone by name",
    inputSchema: {
      type: "object",
      properties: { name: { type: "string" } },
      required: ["name"],
    },
    execute({ name }, { signal }) {
      signal.throwIfAborted();
      return { greeting: `Hello, ${name}` };
    },
  },
  { signal: registration.signal },
);

console.log(await context.getTools());

registration.abort();

For explicit installation, import installWebMCP from webmcp-polyfill and call it. Importing that entry alone does not install anything. The installer does nothing outside a secure browser context or when document.modelContext already exists. It does not patch a partial native implementation.

For a classic script, use the bundled dist/auto.js. It installs automatically, without imports or runtime dependencies. The package name and initial version are provisional; develop from this checkout until it is published.

Supported scope

Behavior This implementation
Imperative registration, discovery, toolchange Supported within one document
JSON metadata and schema-based input inference Uses webmcp-types; inference does not validate runtime inputs
Execution Deferred to a separate PR, following types PR #3
Registration lifetime Aborting registration removes the tool and emits toolchange
Browser API shape Document.prototype.modelContext, ModelContext, EventTarget
Cross-document discovery Not supported, including same-origin frames
exposedTo / fromOrigins Empty sequences supported; nonempty sequences reject
Declarative forms, CSS tool states, tool lifecycle window events Not included in this first implementation
Navigation, BFCache and browser agent integration Require further work / native support

The runtime checks tool descriptors and JSON serialization. Application callbacks remain responsible for validating their inputs. It does not install a schema validator, MCP server, transport, navigator alias, or removed testing API.

Where exposed by the browser, the tools Permissions Policy is checked. Without that policy surface, cross-origin frames fail closed. Page JavaScript cannot reproduce browser permissions or authenticate messages from other page scripts.

Draft alignment

The initial implementation was compared with draft source 97da8f5. Timing uses tasks rather than microtasks, but a JavaScript timer cannot reproduce the browser's dedicated WebMCP task source.

This initial change matches the registration/discovery surface in webmcp-types@0.1.7 directly, without augmenting its declarations. executeTool() and its execution tests are deferred to a follow-up alongside types PR #3. Registered callbacks are retained, but this version does not provide an invocation API.

This package tracks the evolving draft. Breaking API changes will use a major release and migration notes.

Develop

Use Node.js 22 or newer and pnpm:

pnpm install
pnpm exec playwright install chromium firefox webkit
pnpm typecheck
pnpm test
pnpm test:package

See testing and upstream tracking for the browser matrix, WPT selection, artifacts, and excluded coverage. pnpm test runs real pages in Chromium, Firefox, and WebKit, including native API preservation in Chromium. pnpm test:package checks a packed consumer. pnpm test:wpt runs 13 upstream registration/discovery files with 27 passing assertions and no expected failures. Execution and full IDL coverage belong to the follow-up.

Keep webmcp-types and webmcp-polyfill as sibling checkouts for local iteration. To try a types change, run pnpm link ../webmcp-types here, then pnpm typecheck. Restore the published dependency with pnpm install --force before the final package check, and do not commit a local dependency override.

Before proposing a release: review the draft diff, run applicable upstream WPT and IDL checks, and record unsupported assertions separately from regressions. The focused browser suite is not a claim of full WPT conformance. Declarative support can be brought over from MCP-B as a separate entry once its execution behavior is aligned.

License

MIT. The implementation builds on the document-local runtime in MCP-B; see LICENSE.

About

WebMCP polyfill

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages