Skip to content

Add WebMCP registration, discovery, and execution - #1

Draft
MiguelsPizza wants to merge 9 commits into
mainfrom
alex/core-polyfill
Draft

MiguelsPizza wants to merge 9 commits into
mainfrom
alex/core-polyfill

Conversation

@MiguelsPizza

@MiguelsPizza MiguelsPizza commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Still in WIP but getting closer to something ready for review. Below is AI generated and will change:

This adds document-local WebMCP registration, discovery, and execution, combining the original implementation with the execution work in #2. It follows the Community Group draft and uses released webmcp-types@0.1.8 after the upstream execution types merged; the temporary type augmentation is removed.

The package provides registerTool(), getTools(), executeTool(), and ontoolchange on document.modelContext. Registration signals unregister tools. Execution takes object input, returns JSON-serialized results, and gives each callback a separate cancellation signal. Installation preserves existing native implementations. Event handlers and iterators are invoked without consulting author-defined function properties. A handler returning false cancels cancelable events, matching native behavior.

Review follow-ups

  • Remove the fixture's redundant discovery call after unregistering; the application test asserts that discovery returns no tools. Discussion
  • Document that the Origin-Agent-Cluster header is optional in current Chrome, while retaining deterministic opt-in and opt-out test fixtures. README comment, testing comment
  • Disable only WebMCP in both browser runners; remove the obsolete WebMCPTesting flag. WPT comment, Playwright comment
  • Run every WebMCP testharness file at the pin, including imperative/getTools.https.html, with standard WPT expectation files. Unexpected passes and failures fail the run. Coverage comment, expectations comment

Validation and scope

  • Lint, build, type checking, and 106 browser tests pass on Chromium 153.0.8010.12, Firefox 155.0, and Playwright WebKit 26.6, including native Chromium preservation.
  • The packed consumer passes public type inference, package contents, and server-side import checks.
  • WPT at 1a21db9 on Chrome Canary 156.0.8062.0 runs 58 files and 139 subtests: 72 PASS, 23 expected FAIL, 25 expected TIMEOUT, and 19 expected NOTRUN. All 22 IDL subtests pass; there are no unexpected results. Non-testharness tests are outside this lane.
  • The implementation was compared with draft source df2d824.

Tools remain in their registering document. Cross-document routing, declarative forms, lifecycle events, and exact native task/policy behavior are unsupported or approximated. Known draft/WPT disagreements and all limitations are recorded in TESTING.md; this does not claim full conformance.

Extension integration remains separate in #3.

@MiguelsPizza MiguelsPizza mentioned this pull request Sep 14, 2026
@MiguelsPizza
MiguelsPizza force-pushed the alex/core-polyfill branch 7 times, most recently from 855027d to 843ec28 Compare September 15, 2026 17:12
Match the published official types with a document-local implementation and real-browser, package-consumer, and pinned WPT checks.

Resolve package dependencies with fresh registry metadata so clean CI runners do not depend on a warm offline cache. Allow only the downloaded Chrome executable to create user namespaces on Ubuntu, keeping its sandbox enabled, and expose WPT startup logs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Implement executeTool() against the current draft: object input, JSON-serialized results, and abort handling that gives the callback its own signal and a default AbortError while the caller receives its own reason. Extend the WPT selection from 13 files to 18, and from 27 assertions to 56, now that the interface is complete enough for the IDL harness.

Record as per-subtest expected failures in wpt-metadata the four upstream files that disagree with the draft on omitted input and on result serialization, rather than patching tests or relaxing the implementation. Carry a temporary ModelContext augmentation mirroring webmcp-types#3 until that ships.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@beaufortfrancois beaufortfrancois left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @MiguelsPizza for starting this effort! See comments below

Comment thread fixtures/app.js Outdated
Comment thread README.md Outdated
Comment thread TESTING.md Outdated
Comment thread wpt.mjs Outdated
Comment thread playwright.config.ts Outdated
Comment thread wpt.mjs Outdated
"imperative/non-secure.html",
"imperative/register-tool-title.https.html",
"imperative/register_tool_with_empty_annotation.https.html",
"imperative/getTools-imperative-annotations.https.html",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is imperative/getTools.https.html not covered? I may have missed others as well. Can you explain which ones you picked?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason other than things were (are) still in WIP. They should all be covered now

Comment thread wpt.mjs Outdated
Use released webmcp-types 0.1.8 and remove the temporary executeTool
augmentation. Shorten comments and test setup while preserving Web IDL
conversion, cancellation, and native-installation behavior.

Run every pinned WebMCP testharness file with standard WPT expectations
instead of a selected list. Record failures, timeouts, and blocked subtests
separately so the supported scope is visible. Apply the review's fixture,
header, and Chrome flag corrections.

Validate blob URLs using their inherited origin; a browser regression
demonstrates the former SecurityError for trustworthy blob origins.

Validated with pnpm test (100 browser tests), pnpm test:package, and
pnpm test:wpt (58 files; all results match their explicit expectations).

References:
#1
#2
https://github.com/webmachinelearning/webmcp-types/releases/tag/v0.1.8
https://url.spec.whatwg.org/#concept-url-origin
Browser tests and their type checks used separate filename allowlists, so a
new test could be silently omitted. Discover test files by convention while
keeping the native Chromium test in its own project. Share execution-test
setup and use resolved promises instead of definitely-assigned test state.

CI and the local WPT runner now read one unchanged revision from
wpt-revision.txt. Preserve the full testharness selection and reviewed
expectations established after Francois's review:
#1 (comment)

Use URL.parse for invalid-origin handling, keeping the same security errors
without exception-driven parsing. Expand the installer's public JSDoc with
its no-op cases, frame scope, example, and first-party references. Keep Web
IDL boundary checks and document the native validation behind their casts.
https://url.spec.whatwg.org/#dom-url-parse
https://webmachinelearning.github.io/webmcp/#document-extension

Validation: pnpm test (100 passes), pnpm test:package, formatting, and
pnpm test:wpt on Canary 156.0.8062.0. All 58 WPT files match expectations:
72 PASS, 23 expected FAIL, 25 expected TIMEOUT, and 19 expected NOTRUN.
The implementation was compact but made readers unpack argument conversion,
security checks, and asynchronous execution at the same time. Put installation
and public operations first, move Web IDL conversion into named local helpers,
and distinguish the caller's settlement from the callback's completion.

Make discovery an explicit copy, sort, and return sequence. Preserve optional
member omission and Web IDL property order, with an assertion in the existing
metadata test. Expand guards and give stored schemas and signals names that
explain their roles. This deliberately favors reading order over line count.

Flatten browser tests so each action finishes before its outcome is asserted.
Record the readability convention for future edits. No public API, dependency,
WPT selection, or expectation changes.

References:
https://webidl.spec.whatwg.org/#es-dictionary
https://webmachinelearning.github.io/webmcp/

Validation: pnpm test (100 passes), pnpm test:package, formatting, and
pnpm test:wpt on Canary 156.0.8062.0. All 58 WPT files match expectations:
72 PASS, 23 expected FAIL, 25 expected TIMEOUT, and 19 expected NOTRUN.
Expand dense test phases, fixture code, and the WPT runner so the combined
registration and execution work is easier to follow. Review every tracked
file and comment; explain actual WPT blockers without changing expectations.

Replace Reflect.get/apply in origin conversion while retaining a single
iterator lookup and the original receiver. Cover both registration and
discovery with an iterator whose function properties cannot be read.

Run all 15 Rook anti-slop rules externally without adding the plugin here.
Keep required Web IDL boundary types and browser checks. Document the schema
JSON/type mismatch instead of claiming an unchecked cast is safe.

Reference: https://webidl.spec.whatwg.org/#es-sequence

Validation: 100 browser tests, lint, build, typecheck, packed consumer,
formatting, and diff checks pass. WPT: 58 files / 139 subtests, no unexpected
results (72 pass, 23 expected fail, 25 expected timeout, 19 expected notrun).
Use plain conditionals for schema serialization, title conversion, and the
Permissions Policy fallback. Each step now reads in execution order without
mixing an optional value, conversion, and fallback into one expression.

Preserve the existing undefined/null checks and property access order.

Validation: lint, build, typecheck, 100 browser tests, packed consumer,
formatting, and WPT pass with no unexpected results. All 29 previously
documented anti-slop diagnostics are unchanged.
Calling a toolchange handler through its own call property skips valid
callbacks when authors shadow that property. Invoke it with Reflect.apply,
and honor a false return value by cancelling cancelable events. Both bugs
were reproduced against native Chromium and are covered by browser tests.

Use the same direct invocation for origin iterators instead of the less
readable Function.prototype.call.bind workaround. Keep concise conditional
assignments and remove workflow labels from the remaining comments.

References:
https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-processing-algorithm
https://webidl.spec.whatwg.org/#es-sequence

Validation: pnpm test (106 browser tests), pnpm test:package, formatting,
and git diff --check passed. Pinned WPT ran 58 files and 139 subtests with
no unexpected results: 72 PASS, 23 expected FAIL, 25 expected TIMEOUT,
and 19 expected NOTRUN. All 22 IDL subtests passed.
@MiguelsPizza MiguelsPizza changed the title Add WebMCP registration and discovery Add WebMCP registration, discovery, and execution Sep 17, 2026
Separate the implementation, local tests, and upstream WPT runner into
src/, tests/, and wpt/ so contributors can find each part without scanning
the repository root. Run the Node scripts directly as TypeScript on Node
24 and include them, plus the browser fixture JavaScript, in strict type
checking. Update CI, documentation, and ignored cache paths while keeping
the package entry points and WPT expectations unchanged.

Use the caller signal and native promise settlement instead of duplicate
execution state. Share USVString conversion and load the official global
types through the test config. Preserve a reflexive sort comparator and
cover cancellation during result serialization, before queued delivery.

References:
https://nodejs.org/docs/latest-v24.x/api/typescript.html#type-stripping
https://webidl.spec.whatwg.org/#es-USVString
https://tc39.es/ecma262/multipage/indexed-collections.html#sec-sortindexedproperties
https://webmachinelearning.github.io/webmcp/#dom-modelcontext-executetool

Validation: lint, type checking, formatting, 109 browser tests, and the
packed-consumer checks passed. Pinned WPT ran 58 files and 139 subtests
with no unexpected results: 72 PASS, 23 expected FAIL, 25 expected TIMEOUT,
and 19 expected NOTRUN. All 22 IDL subtests passed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants