@mcp-b/webmcp-polyfill 5.0.3 → 6.0.0-beta.20261001010549

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 WebMCP polyfill contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,186 +1,122 @@
1
1
  # @mcp-b/webmcp-polyfill
2
2
 
3
- A browser polyfill for the current core WebMCP API on `document.modelContext`.
4
- It implements tool registration, discovery, lifecycle events, and Chromium's
5
- optional `executeTool()` extension. MCP features such as prompts, resources,
6
- browser transport, and a composed MCP server belong to the MCP-B runtime built
7
- by `@mcp-b/global`.
3
+ This package is a temporary compatibility distribution of the upstream
4
+ [WebMCP polyfill](https://github.com/webmachinelearning/webmcp-polyfill), distributed
5
+ under the existing MCP-B package name with vendored upstream source.
8
6
 
9
- The current WebMCP draft is published at
10
- [webmachinelearning.github.io/webmcp](https://webmachinelearning.github.io/webmcp/).
7
+ **This package will eventually be removed.** There is no removal date yet. Sites
8
+ using declarative tools should keep this package until the upstream polyfill
9
+ supports them. For other sites, follow the
10
+ [upstream installation instructions](https://github.com/webmachinelearning/webmcp-polyfill#readme)
11
+ when its distribution is available.
11
12
 
12
- ## Install
13
+ Until then, this package bundles upstream revision
14
+ `439c6c341f1c632c63498ba206e2bd8471cb8efb`. It installs the standard
15
+ `document.modelContext` API when the browser does not provide one, plus a
16
+ temporary declarative tools layer. The upstream implementation and types are the
17
+ source of truth for the core runtime. Use [`@mcp-b/global`](../global/README.md)
18
+ for transports, prompts, resources, or MCP `outputSchema` support; MCP-B schema
19
+ helpers live in `@mcp-b/webmcp-ts-sdk/schema`.
20
+
21
+ The [package reference](https://docs.mcp-b.ai/packages/webmcp-polyfill/reference)
22
+ documents the installer, the declarative layer, and the browser baseline.
23
+
24
+ ## Use the compatibility package
13
25
 
14
26
  ```bash
15
27
  pnpm add @mcp-b/webmcp-polyfill
16
28
  ```
17
29
 
18
- ## Initialize
30
+ ## Install the polyfill
19
31
 
20
- ES modules initialize explicitly:
32
+ Call `installWebMCP()` before your app registers tools:
21
33
 
22
34
  ```ts
23
- import { initializeWebMCPPolyfill } from '@mcp-b/webmcp-polyfill';
24
-
25
- initializeWebMCPPolyfill();
26
- ```
27
-
28
- The standalone IIFE initializes when loaded:
29
-
30
- ```html
31
- <script src="https://unpkg.com/@mcp-b/webmcp-polyfill@latest/dist/index.iife.js"></script>
32
- ```
35
+ import { installWebMCP } from '@mcp-b/webmcp-polyfill';
33
36
 
34
- Set testing options before loading the IIFE only when a test harness needs the
35
- deprecated Chromium testing surface:
37
+ installWebMCP();
36
38
 
37
- ```html
38
- <script>
39
- window.__webMCPPolyfillOptions = { installTestingShim: true };
40
- </script>
39
+ const context = document.modelContext;
40
+ if (!context) throw new Error('WebMCP is unavailable');
41
41
  ```
42
42
 
43
- ## Declare a form tool
43
+ The call is idempotent and preserves an existing native context. It does
44
+ nothing when no browser document is available, on an insecure page, or on
45
+ engines older than Chrome 126, Firefox 126, or Safari 18, so
46
+ `if (!document.modelContext)` remains a valid feature check. The upstream
47
+ runtime has no uninstall operation and does not provide the deprecated
48
+ `navigator.modelContext` alias.
44
49
 
45
- When the polyfill owns `document.modelContext`, it observes annotated forms in
46
- the document and its open shadow roots and registers them as tools. It derives
47
- input schemas from native named controls and keeps registrations synchronized
48
- with DOM changes.
50
+ For a script tag, load the IIFE before registering tools:
49
51
 
50
52
  ```html
51
- <form toolname="search_catalog" tooldescription="Search the product catalog" toolautosubmit>
52
- <input name="query" required toolparamdescription="Words to match" />
53
- <button type="submit">Search</button>
54
- </form>
55
-
56
- <script>
57
- document.querySelector('form').addEventListener('submit', (event) => {
58
- if (!event.agentInvoked) return;
59
-
60
- event.preventDefault();
61
- event.respondWith(Promise.resolve({ matches: [] }));
62
- });
63
- </script>
53
+ <script src="https://unpkg.com/@mcp-b/webmcp-polyfill@6/dist/index.iife.js"></script>
64
54
  ```
65
55
 
66
- Without `toolautosubmit`, invocation fills the form and waits for the user to
67
- submit it. With `toolautosubmit`, the polyfill validates the form and calls
68
- `requestSubmit()`. Agent submissions expose `SubmitEvent.agentInvoked` and
69
- `SubmitEvent.respondWith()`.
70
-
71
- CI checks the standalone polyfill against the upstream
72
- [declarative Web Platform Tests](https://github.com/web-platform-tests/wpt/tree/master/webmcp/declarative).
73
- Repository-specific browser tests cover the polyfill and composed MCP-B runtime.
74
- See Chrome's
75
- [declarative API documentation](https://developer.chrome.com/docs/ai/webmcp/declarative-api)
76
- for the evolving API. The Community Group draft's
77
- [declarative section](https://webmachinelearning.github.io/webmcp/#declarative-webmcp)
78
- is still incomplete.
56
+ The IIFE calls `installWebMCP()` automatically and exposes it as
57
+ `WebMCPPolyfill.installWebMCP`.
79
58
 
80
59
  ## Register a tool
81
60
 
61
+ Tool registrations follow the upstream WebMCP API. Pass an `AbortSignal` when
62
+ the registration has a lifecycle:
63
+
82
64
  ```ts
83
65
  const registration = new AbortController();
84
66
 
85
- await document.modelContext.registerTool(
67
+ await context.registerTool(
86
68
  {
87
- name: 'get-page-title',
88
- description: 'Return the current page title',
89
- inputSchema: { type: 'object', properties: {} },
90
- execute: async () => ({ title: document.title }),
69
+ name: 'page-title',
70
+ description: 'Get the title of this page',
71
+ execute() {
72
+ return { title: document.title };
73
+ },
91
74
  },
92
75
  { signal: registration.signal }
93
76
  );
94
77
 
95
- // Remove the registration later.
96
- registration.abort();
97
- ```
98
-
99
- `registerTool()` resolves after the local `toolchange` notification. Duplicate
100
- names, invalid descriptors, aborted registrations, and non-serializable schemas
101
- reject the returned promise.
102
-
103
- ## Discover and execute
104
-
105
- ```ts
106
- import type { ChromeModelContext } from '@mcp-b/webmcp-types';
107
-
108
- const context = document.modelContext as ChromeModelContext;
109
- const [tool] = await context.getTools();
110
-
111
- if (tool && context.executeTool) {
112
- const result = await context.executeTool(tool, JSON.stringify({}));
78
+ const tools = await context.getTools();
79
+ const tool = tools.find((item) => item.name === 'page-title');
80
+ if (tool) {
81
+ const result = await context.executeTool(tool);
113
82
  console.log(result);
114
83
  }
115
- ```
116
-
117
- `executeTool()` is a Chromium extension, not part of the core `ModelContext`
118
- interface. Feature-detect it.
119
-
120
- The local polyfill cannot securely implement cross-document discovery or
121
- exposure. Non-empty `fromOrigins` and `exposedTo` arrays reject with
122
- `NotSupportedError`; use native WebMCP for those capabilities. Where the host
123
- browser exposes the `tools` Permissions Policy, the polyfill enforces it. In
124
- browsers without that policy feature, cross-origin frames fail closed.
125
-
126
- ## API
127
-
128
- ### `initializeWebMCPPolyfill(options?)`
129
84
 
130
- Installs `window.ModelContext` and `document.modelContext` when native WebMCP is
131
- absent. It also keeps `navigator.modelContext` as the repository's deprecated
132
- compatibility alias.
133
-
134
- ```ts
135
- interface WebMCPPolyfillInitOptions {
136
- installTestingShim?: boolean; // default: false
137
- }
85
+ registration.abort();
138
86
  ```
139
87
 
140
- Initialization is idempotent and does not replace an existing native context or
141
- testing implementation.
142
-
143
- ### `cleanupWebMCPPolyfill()`
144
-
145
- Removes registrations, detaches their abort listeners, and restores every
146
- property descriptor changed by initialization.
147
-
148
- ## Testing shim
88
+ See the [WebMCP draft](https://webmachinelearning.github.io/webmcp/) and the
89
+ [upstream polyfill](https://github.com/webmachinelearning/webmcp-polyfill) for
90
+ the standard API and implementation details.
149
91
 
150
- `installTestingShim: true` installs the deprecated, testing-only
151
- `navigator.modelContextTesting` compatibility surface when it is absent:
92
+ ## Declare a tool in HTML
152
93
 
153
- - `listTools()`
154
- - `executeTool(name, inputJson, options?)`
155
- - `toolchange` events and `ontoolchange`
94
+ The declarative layer registers a tool for each form with `toolname` and
95
+ `tooldescription` in the document and its open shadow roots. The input schema
96
+ comes from the form's named controls.
156
97
 
157
- Prefer `getTools()` plus feature-detected `executeTool()` for native-browser
158
- coverage.
159
-
160
- ## Schema helpers
161
-
162
- The `@mcp-b/webmcp-polyfill/schema` entry owns shared browser-runtime adapters
163
- used by MCP-B packages. `normalizeInputSchema()` accepts plain JSON Schema and
164
- Standard Schema v1 implementations that expose `~standard.jsonSchema.input()`.
165
- This conversion is an MCP-B adapter feature; the strict WebMCP registration
166
- boundary itself accepts JSON Schema.
98
+ ```html
99
+ <form toolname="search_catalog" tooldescription="Search the product catalog" toolautosubmit>
100
+ <input name="query" required toolparamdescription="Words to match" />
101
+ <button type="submit">Search</button>
102
+ </form>
167
103
 
168
- For literal-schema TypeScript inference, install `@mcp-b/webmcp-types` and use
169
- `JsonSchemaForInference`. Runtime-defined schemas safely fall back to
170
- object-or-array input.
104
+ <script>
105
+ document.querySelector('form').addEventListener('submit', (event) => {
106
+ if (!event.agentInvoked) return;
171
107
 
172
- ## Compatibility boundary
108
+ event.preventDefault();
109
+ event.respondWith(Promise.resolve({ matches: [] }));
110
+ });
111
+ </script>
112
+ ```
173
113
 
174
- - `document.modelContext` is canonical.
175
- - `navigator.modelContext` is deprecated compatibility.
176
- - Tool lifetime is owned by the `AbortSignal` passed to `registerTool()`.
177
- - `unregisterTool()`, `provideContext()`, and `clearContext()` are not exposed.
178
- - Importing the ESM entry has no initialization side effect.
179
- - Declarative forms do not emulate native CSS tool-state pseudo-classes,
180
- `toolcancel`, cross-navigation responses, file inputs, or custom
181
- form-associated elements.
182
- - Closed shadow roots cannot be inspected.
114
+ An invocation fills the controls and either submits the form (`toolautosubmit`)
115
+ or focuses its submit button for the user. The
116
+ [declarative tools reference](https://docs.mcp-b.ai/packages/webmcp-polyfill/reference#declarative-tools)
117
+ covers results, lifecycle events, cancellation, failures, and native browser
118
+ hooks.
183
119
 
184
120
  ## License
185
121
 
186
- MIT
122
+ The package includes the upstream polyfill's MIT license notice.
package/dist/index.d.ts CHANGED
@@ -1,17 +1,24 @@
1
+ import { WebMCP } from "webmcp-types";
2
+
1
3
  //#region src/index.d.ts
2
- interface WebMCPPolyfillInitOptions {
3
- /**
4
- * Controls installation of navigator.modelContextTesting when this polyfill provides modelContext.
5
- * The shim is testing-only and never replaces an existing implementation.
6
- *
7
- * Off by default so the polyfill stays spec-pure; modelContextTesting is a removed
8
- * Chromium preview API. `@mcp-b/global` deliberately opts in (its own default is true).
9
- * @default false
10
- */
11
- installTestingShim?: boolean;
4
+ /**
5
+ * Installs upstream WebMCP and the temporary declarative tools layer.
6
+ * Engines missing an API the vendored core calls are left untouched: upstream defines
7
+ * the document getter before it constructs the context, so a failed construction would
8
+ * leave `document.modelContext` throwing.
9
+ */
10
+ declare function installWebMCP(): void;
11
+ declare global {
12
+ interface SubmitEvent {
13
+ readonly agentInvoked?: boolean;
14
+ respondWith?(agentResponse: Promise<unknown>): void;
15
+ }
16
+ /** Web IDL interface object used for branding and `instanceof`. */
17
+ var ModelContext: (Function & {
18
+ readonly prototype: WebMCP.ModelContext;
19
+ [Symbol.hasInstance](value: Parameters<Function[typeof Symbol.hasInstance]>[0]): value is WebMCP.ModelContext;
20
+ }) | undefined;
12
21
  }
13
- declare function initializeWebMCPPolyfill(options?: WebMCPPolyfillInitOptions): void;
14
- declare function cleanupWebMCPPolyfill(): void;
15
22
  //#endregion
16
- export { WebMCPPolyfillInitOptions, cleanupWebMCPPolyfill, initializeWebMCPPolyfill };
23
+ export { type WebMCP, installWebMCP };
17
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1,6 @@
1
- var WebMCPPolyfill=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t=`Tool was executed but the invocation failed. For example, the script function threw an error`,n=/^[A-Za-z0-9_.-]{1,128}$/u;function r(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function i(e){if(typeof e==`symbol`)throw TypeError(`Symbol values cannot be converted to a DOMString`);return String(e)}function a(e){let t=Reflect.get(e,`name`),n=Reflect.get(e,`description`),a=Reflect.get(e,`title`);if(t===void 0)throw TypeError(`Tool "name" is required`);if(n===void 0)throw TypeError(`Tool "description" is required`);let o=Reflect.get(e,`annotations`),s=r(o)?o:{},c=Reflect.get(e,`inputSchema`),l=Reflect.get(e,`outputSchema`),u=Reflect.get(e,`execute`);return{name:i(t),...a===void 0?{}:{title:i(a).toWellFormed()},description:i(n),...c===void 0?{}:{inputSchema:c},...l===void 0?{}:{outputSchema:l},execute:u,...o===void 0?{}:{annotations:{...s.title===void 0?{}:{title:i(s.title).toWellFormed()},readOnlyHint:!!s.readOnlyHint,...s.destructiveHint===void 0?{}:{destructiveHint:!!s.destructiveHint},...s.idempotentHint===void 0?{}:{idempotentHint:!!s.idempotentHint},...s.openWorldHint===void 0?{}:{openWorldHint:!!s.openWorldHint},untrustedContentHint:!!s.untrustedContentHint}}}}function o(e){return new DOMException(e,`UnknownError`)}function s(e){return o(e instanceof Error?`${t}: ${e.message}`:t)}function c(e){return new DOMException(e,`InvalidStateError`)}function l(e){if(e.name===``)throw c(`Tool "name" must be a non-empty string`);if(typeof e.name!=`string`||!n.test(e.name))throw c(`Tool "name" must be 1–128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period`);if(typeof e.description!=`string`||e.description.length===0)throw c(`Tool "description" must be a non-empty string`);if(typeof e.execute!=`function`)throw TypeError(`Tool "execute" must be a function`)}function u(e){return{readOnlyHint:e.readOnlyHint??!1,untrustedContentHint:e.untrustedContentHint??!1}}function d(e){try{let t=JSON.parse(e);if(Array.isArray(t)||r(t))return t}catch{}throw o(`Failed to parse input arguments`)}function f(e){if(typeof e==`object`&&e||typeof e==`function`)try{let t=JSON.stringify(e);if(t)return t}catch{}return String(e)||`Operation succeeded`}function p(e,t,n=()=>t?.reason){return t?t.aborted?Promise.reject(n()):new Promise((r,i)=>{let a=()=>{o(),i(n())},o=()=>t.removeEventListener(`abort`,a);t.addEventListener(`abort`,a,{once:!0}),e.then(e=>{o(),r(e)},e=>{o(),i(e)})}):e}function m(e){let t=e.origin===`null`?e:new URL(e.origin),n=t.protocol;if([`https:`,`wss:`,`file:`,`chrome-extension:`,`moz-extension:`].includes(n))return!0;let r=t.hostname.toLowerCase(),i=r.split(`.`),a=i.length===4&&i.every(e=>/^\d{1,3}$/u.test(e)&&Number(e)<=255)&&Number(i[0])===127;return r===`::1`||r===`[::1]`||r===`localhost`||r===`localhost.`||r.endsWith(`.localhost`)||r.endsWith(`.localhost.`)||a}function h(e){for(let t of e??[]){let e;try{e=new URL(t)}catch{throw new DOMException(`Invalid or untrustworthy origin: ${String(t)}`,`SecurityError`)}if(!m(e))throw new DOMException(`Invalid or untrustworthy origin: ${t}`,`SecurityError`)}}function g(e){if(ee(),!e)return;let t=e.defaultView?.DOMException??DOMException,n=!1;try{let t=e.defaultView;n=!!(t&&t.document===e)}catch{}if(!n)throw new t(`The associated document is not fully active`,`InvalidStateError`);let r=Reflect.get(e,`permissionsPolicy`)??Reflect.get(e,`featurePolicy`);if(r&&typeof r==`object`){let e=Reflect.get(r,`features`),n=Reflect.get(r,`allowsFeature`);if(typeof e==`function`&&typeof n==`function`){let i=Reflect.apply(e,r,[]);if(Array.isArray(i)&&i.includes(`tools`)){if(Reflect.apply(n,r,[`tools`])===!0)return;throw new t(`WebMCP is disabled by Permissions Policy`,`NotAllowedError`)}}}let i=e.defaultView;if(!(!i||i.parent===i)){try{i.parent.document;return}catch{}throw new t(`WebMCP in cross-origin frames requires native Permissions Policy support`,`NotAllowedError`)}}function ee(){if(globalThis.originAgentCluster===!1&&globalThis.location?.protocol!==`file:`)throw new DOMException(``,`SecurityError`)}function te(e){try{if(new URL(String(e)).origin!==`null`)return}catch{}throw new DOMException(`Unsupported tool origin: ${String(e)}`,`NotSupportedError`)}function ne(e){if(e===null||typeof e!=`object`&&typeof e!=`function`)throw TypeError(`inputSchema must be an object`);let t=JSON.stringify(e);if(t===void 0)throw TypeError(`inputSchema must be JSON-serializable`);return t}let _=new WeakSet,v=new WeakMap,y=new WeakMap;function b(e){return e.isTrusted&&(_.has(e)||e.eventPhase!==Event.NONE&&e.target instanceof HTMLFormElement&&y.has(e.target))}function re(e,t){if(!b(e))throw new DOMException(`respondWith() is only available during an agent-invoked submit event`,`InvalidStateError`);if(!e.defaultPrevented)throw new DOMException(`respondWith() requires preventDefault() during an agent-invoked submit event`,`InvalidStateError`);if(e.eventPhase===Event.NONE)throw new DOMException(`respondWith() is only available while the submit event is being dispatched`,`InvalidStateError`);_.add(e);let n=Promise.resolve(t);v.set(e,n),e.target instanceof HTMLFormElement&&y.get(e.target)?.respond(e)}let x=new Set([`email`,`password`,`search`,`tel`,`text`,`url`]),ie=new Set([...x,`date`,`datetime-local`,`month`,`number`,`time`,`week`]);function S(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function C(e){return Reflect.get(HTMLFormElement.prototype,`elements`,e)}function w(e,t){return Reflect.apply(Element.prototype.getAttribute,e,[t])}function T(e,t){return Reflect.apply(Element.prototype.hasAttribute,e,[t])}function ae(e){return Reflect.get(Node.prototype,`isConnected`,e)}function oe(e){return Reflect.get(Element.prototype,`shadowRoot`,e)}function se(e){return Reflect.apply(HTMLFormElement.prototype.checkValidity,e,[])}function ce(e,t){Reflect.apply(HTMLFormElement.prototype.requestSubmit,e,t?[t]:[])}function le(e){return[...C(e)].filter(e=>S(e)&&!e.matches(`:disabled`)&&!(`readOnly`in e&&e.readOnly&&(e instanceof HTMLTextAreaElement||ie.has(e.type))))}function E(e){let t=new Map;for(let n of le(e)){let e=n.name.trim(),r=t.get(e);r?r.push(n):t.set(e,[n])}return t}function D(e){return[...e.labels??[]].map(e=>{let t=e.cloneNode(!0);return t instanceof HTMLElement?(t.querySelectorAll(`button, input, meter, output, progress, select, textarea`).forEach(e=>e.remove()),t.textContent?.trim()??``):``}).filter(Boolean).join(`; `)}function ue(e,t){for(let n=t[0]?.parentElement;n&&n!==e;n=n.parentElement)if(n instanceof HTMLFieldSetElement&&t.every(e=>n.contains(e)))return n}function de(e,t){if(t.length===1){let e=t[0];return e&&(e.getAttribute(`toolparamdescription`)||D(e)||e.getAttribute(`aria-description`))||void 0}return ue(e,t)?.getAttribute(`toolparamdescription`)||void 0}function O(e,t,n,r){let i=de(t,n),a=i&&r?`${i} (${r})`:i||r;return a?{...e,description:a}:e}function k(e,t){let n=e.getAttribute(t);if(n===null||n.trim()===``)return;let r=Number(n);return Number.isFinite(r)?r:void 0}function fe(e,t){let n=e/t;return Math.abs(n-Math.round(n))<2**-52*16}function A(e){let t=e.getAttribute(`pattern`);if(t!==null)try{return new RegExp(t,`v`),t}catch{return}}function j(e,t=!0){let n={type:`number`},r=k(e,`min`),i=k(e,`max`);r!==void 0&&(n.minimum=r),i!==void 0&&(n.maximum=i);let a=e.getAttribute(`step`);if(a!==`any`){let t=a===null||a===``?1:Number(a),i=Number.isFinite(t)&&t>0?t:1,o=Number(e.getAttribute(`value`));fe(r??(Number.isFinite(o)?o:0),i)&&(n.multipleOf=i)}let o=t?A(e):void 0;return o!==void 0&&(n.pattern=o),n}function M(e,t){let n=e.getAttribute(`step`),r=n===null||n===``?60:Number(n),i=Number.isFinite(r)&&r>0?r:60;return i<1?`${t}(:[0-5][0-9](\\.[0-9]{1,3})?)?$`:i<60?`${t}(:[0-5][0-9])?$`:`${t}$`}function pe(e){return{anyOf:e.map(e=>({type:`string`,const:e.value,title:e.textContent??``})),enum:e.map(e=>e.value)}}function N(e){return{anyOf:e.map(e=>{let t=D(e);return{type:`string`,const:e.value,...t?{title:t}:{}}}),enum:e.map(e=>e.value)}}function P(e,t){let n=t[0];if(n){if(t.length>1)return t.every(e=>e instanceof HTMLInputElement)?t.every(e=>e.type===`checkbox`)?O({type:`array`,items:{type:`string`,...N(t)},uniqueItems:!0},e,t):t.every(e=>e.type===`radio`)?O({type:`string`,...N(t)},e,t):void 0:void 0;if(n instanceof HTMLTextAreaElement)return O({type:`string`},e,t);if(n instanceof HTMLSelectElement){let r=pe([...n.options]);return O(n.multiple?{type:`array`,items:{type:`string`,...r},uniqueItems:!0}:{type:`string`,...r},e,t)}if(x.has(n.type)){let r={type:`string`},i=A(n);return i!==void 0&&(r.pattern=i),O(r,e,t)}if(n.type===`hidden`)return n.getAttribute(`toolparamdescription`)?O({type:`string`},e,t):void 0;if(n.type===`number`)return O(j(n),e,t);if(n.type===`range`){let r=j(n,!1);return r.minimum??=0,r.maximum??=100,O(r,e,t)}if(n.type===`checkbox`)return O({type:`boolean`},e,t);if(n.type===`radio`)return O({type:`string`,...N([n])},e,t);if(n.type===`date`)return O({type:`string`,format:`date`},e,t,`Dates MUST be provided in 'YYYY-MM-DD' format.`);if(n.type===`month`)return O({type:`string`,format:`^[0-9]{4}-(0[1-9]|1[0-2])$`},e,t);if(n.type===`week`)return O({type:`string`,format:`^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$`},e,t);if(n.type===`time`)return O({type:`string`,format:M(n,`^([01][0-9]|2[0-3]):[0-5][0-9]`)},e,t);if(n.type===`datetime-local`)return O({type:`string`,format:M(n,`^[0-9]{4}-(0[1-9]|1[0-2])-[0-9]{2}T([01][0-9]|2[0-3]):[0-5][0-9]`)},e,t);if(n.type===`color`)return O({type:`string`,format:`^#[0-9a-zA-Z]{6}$`},e,t)}}function me(e){let t={},n=[];for(let[r,i]of E(e)){if(!r)continue;let a=P(e,i);a&&(Object.defineProperty(t,r,{configurable:!0,enumerable:!0,value:a,writable:!0}),i.some(e=>e.required)&&n.push(r))}return{type:`object`,properties:t,required:n}}function he(e){return{name:w(e,`toolname`)??``,title:w(e,`tooltitle`)??``,description:w(e,`tooldescription`)??``,inputSchema:me(e),autosubmit:T(e,`toolautosubmit`)}}function F(e){if(typeof e==`string`||typeof e==`boolean`||typeof e==`number`&&Number.isFinite(e))return String(e)}function I(e){if(typeof e==`boolean`)return e;if(typeof e==`number`&&Number.isInteger(e))return e!==0;if(typeof e==`string`){if(e===`1`||e.toLowerCase()===`true`)return!0;if(e===`0`||e.toLowerCase()===`false`)return!1}}function L(e,t){if(!Array.isArray(e))return!1;let n=new Set(t);for(let t of e){let e=F(t);if(e===void 0||!n.delete(e))return!1}return!0}function ge(e,t){if(t===``)return e.type!==`number`&&e.type!==`range`;let n=e.ownerDocument.createElement(`input`);return n.type=e.type,n.value=t,n.value!==``}function _e(e,t,n){let r=t[0];if(!r||!P(e,t))return!1;if(t.length>1){if(!t.every(e=>e instanceof HTMLInputElement))return!1;if(t.every(e=>e.type===`checkbox`))return L(n,new Set(t.map(e=>e.value)));if(t.every(e=>e.type===`radio`)){let e=F(n);return e!==void 0&&t.some(t=>t.value===e)}return!1}if(r instanceof HTMLSelectElement){let e=new Set([...r.options].map(e=>e.value));if(r.multiple)return L(n,e);let t=F(n);return t!==void 0&&e.has(t)}if(r instanceof HTMLTextAreaElement)return F(n)!==void 0;if(r.type===`checkbox`)return I(n)!==void 0;if(r.type===`radio`){let e=F(n);return e!==void 0&&r.value===e}let i=F(n);return i!==void 0&&ge(r,i)}function R(e){e.dispatchEvent(new Event(`input`,{bubbles:!0,composed:!0})),e.dispatchEvent(new Event(`change`,{bubbles:!0}))}function ve(e,t){let n=e instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype;Object.getOwnPropertyDescriptor(n,`value`)?.set?.call(e,t)}function z(e,t){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,`checked`)?.set?.call(e,t)}function ye(e,t){let n=e[0];if(!n)return;if(e.length>1&&e.every(e=>e instanceof HTMLInputElement)){if(e.every(e=>e.type===`checkbox`)&&Array.isArray(t)){let n=new Set(t.map(F));for(let t of e){let e=n.has(t.value);t.checked!==e&&(z(t,e),R(t))}return}let n=F(t),r=e.find(e=>e.value===n);r&&!r.checked&&(z(r,!0),R(r));return}if(n instanceof HTMLSelectElement){if(n.multiple&&Array.isArray(t)){let e=new Set(t.map(F)),r=!1;for(let t of n.options){let n=e.has(t.value);t.selected!==n&&(t.selected=n,r=!0)}r&&R(n);return}let e=F(t);e!==void 0&&n.value!==e&&(n.value=e,R(n));return}if(n instanceof HTMLInputElement&&n.type===`checkbox`){let e=I(t);e!==void 0&&n.checked!==e&&(z(n,e),R(n));return}if(n instanceof HTMLInputElement&&n.type===`radio`){F(t)===n.value&&!n.checked&&(z(n,!0),R(n));return}let r=F(t);r!==void 0&&n.value!==r&&(ve(n,r),R(n))}function be(e,t){if(Array.isArray(t))throw TypeError(`Declarative tool input must be an object`);let n=E(e);for(let[r,i]of Object.entries(t)){let t=n.get(r);if(!t||!_e(e,t,i))throw TypeError(`Invalid value for declarative form parameter "${r}"`)}for(let[e,r]of Object.entries(t))ye(n.get(e)??[],r)}function xe(e){return[...C(e)].find(e=>!e.matches(`:disabled`)&&(e instanceof HTMLButtonElement&&e.type===`submit`||e instanceof HTMLInputElement&&[`image`,`submit`].includes(e.type)))}function Se(e){let t=[...C(e)].filter(e=>S(e)&&e.willValidate&&!e.validity.valid).map(e=>`${e.name.trim()||`{unknown}`}: ${e.validationMessage}`).join(`. `);return new DOMException(`Form validation failed: ${t}`,`UnknownError`)}function B(e){let t=new Event(`toolactivated`);return Object.defineProperty(t,`toolName`,{enumerable:!0,value:e}),t}function Ce(e,t,n,r){let{form:i}=e;return e.cancelPending?.(new DOMException(`Tool execution cancelled`,`UnknownError`)),new Promise((a,o)=>{let s=!1,c=()=>{Reflect.apply(EventTarget.prototype.removeEventListener,i,[`invalid`,f,!0]),y.delete(i),e.cancelPending===u&&delete e.cancelPending},l=e=>{s||(s=!0,c(),e())},u=e=>l(()=>o(e)),d=e=>{e.then(e=>l(()=>a(e)),e=>l(()=>o(e)))},f=e=>{e.isTrusted&&queueMicrotask(()=>{se(i)||u(Se(i))})};if(y.set(i,{complete(e){queueMicrotask(()=>{let t=v.get(e);t?d(t):e.defaultPrevented?u(new DOMException(`preventDefault() requires respondWith()`,`UnknownError`)):l(()=>a(void 0))})},direct(){l(()=>a(void 0))},respond(e){queueMicrotask(()=>{let t=v.get(e);t&&d(t)})}}),e.cancelPending=u,Reflect.apply(EventTarget.prototype.addEventListener,i,[`invalid`,f,!0]),!n){r?.focus(),window.dispatchEvent(B(t));return}try{ce(i,r),window.dispatchEvent(B(t))}catch(e){u(e)}})}function we(e,t){let n=!0,r=new Map,i=new Map,a=new Map,o=e=>{if(!(e instanceof SubmitEvent)||!e.isTrusted||!(e.target instanceof HTMLFormElement))return;let t=y.get(e.target);t&&(_.add(e),t.complete(e))},s=e=>{if(!e.isTrusted||!(e.target instanceof HTMLFormElement))return;let t=e.target;queueMicrotask(()=>{e.defaultPrevented||r.get(t)?.cancelPending?.(new DOMException(`Tool execution cancelled by form reset`,`UnknownError`))})};function c(e){a.get(e)?.disconnect(),a.delete(e),e.removeEventListener(`reset`,s,!0),e.removeEventListener(`submit`,o,!0)}function l(e){if(a.has(e))return;let t=new MutationObserver(u);a.set(e,t),t.observe(e,{attributes:!0,characterData:!0,childList:!0,subtree:!0}),e.addEventListener(`reset`,s,!0),e.addEventListener(`submit`,o,!0)}function u(){l(e);for(let e of a.keys())e instanceof ShadowRoot&&!Reflect.get(Node.prototype,`isConnected`,e.host)&&c(e);let n=new Set,o=new Map,s=new Map;for(let e of a.keys())for(let t of e.querySelectorAll(`*`)){let e=oe(t);if(e&&l(e),!(t instanceof HTMLFormElement)||!T(t,`toolname`)||!T(t,`tooldescription`)||!ae(t))continue;let r=t;n.add(r);let a=he(r),c=JSON.stringify(a),u=i.get(r);if(u===c)continue;let d=u!==void 0;i.delete(r);let f=s.get(a.name);if(f&&!d){i.set(r,c);continue}if(f){let e=o.get(f);e&&(i.set(f,e.fingerprint),o.delete(f))}s.set(a.name,r),o.set(r,{definition:a,fingerprint:c})}for(let e of i.keys())n.has(e)||i.delete(e);for(let[e,t]of r)o.get(e)?.fingerprint!==t.fingerprint&&(t.cancelPending?.(new DOMException(`Tool execution cancelled because its form changed`,`UnknownError`)),t.controller.abort(),r.delete(e));for(let[e,{definition:n,fingerprint:i}]of o){if(r.has(e))continue;let a=new AbortController,o={controller:a,fingerprint:i,form:e};r.set(e,o),t.registerTool({name:n.name,title:n.title,description:n.description,inputSchema:n.inputSchema,execute(t){let r=xe(e);if(!n.autosubmit&&!r)throw new DOMException(`A declarative form without toolautosubmit requires a submit button`,`UnknownError`);return be(e,t),Ce(o,n.name,n.autosubmit,r)}},{signal:a.signal}).catch(e=>{a.abort(),e?.name!==`AbortError`&&console.error(`[webmcp] declarative form tool "${n.name}" was not registered:`,e)})}}let d=()=>{},f=e.defaultView?.Element.prototype,p=f?Object.getOwnPropertyDescriptor(f,`attachShadow`):void 0;if(f&&p?.configurable){let t=f.attachShadow,r=function(r){let i=t.call(this,r);return n&&i.mode===`open`&&Reflect.get(Node.prototype,`ownerDocument`,this)===e&&Reflect.get(Node.prototype,`isConnected`,this)&&l(i),i};Object.defineProperty(f,`attachShadow`,{...p,value:r}),d=()=>{f.attachShadow===r&&Object.defineProperty(f,`attachShadow`,p)}}let m=()=>{},h=e.defaultView?.HTMLFormElement.prototype,g=h?Object.getOwnPropertyDescriptor(h,`submit`):void 0;if(h&&g?.configurable){let e=h.submit,t=function(){e.call(this),n&&y.get(this)?.direct()};Object.defineProperty(h,`submit`,{...g,value:t}),m=()=>{h.submit===t&&Object.defineProperty(h,`submit`,g)}}return u(),()=>{n=!1,m(),d();for(let e of a.keys())c(e);i.clear();for(let e of r.values())e.cancelPending?.(new DOMException(`Tool execution cancelled`,`UnknownError`)),e.controller.abort();r.clear()}}let V=Symbol(`registeredInputSchema`),H=Symbol(`registrationSignal`),U=Symbol(`registrationAbort`),W=[],G=null,K=null;function q(){return typeof globalThis.origin==`string`?globalThis.origin:globalThis.location?.origin??``}function J(e,t,n){let r=Object.getOwnPropertyDescriptor(e,t);try{Object.defineProperty(e,t,n)}catch(e){throw $(),e}W.push({target:e,key:t,previous:r})}var Y=class extends EventTarget{#e=new Map;#t=null;#n=null;#r=e=>{this.#n?.call(this,e)};#i;#a;constructor(e){super(),this.#a=e,this.#i=e?.defaultView?.DOMException??DOMException,Object.defineProperty(this,`__isWebMCPPolyfill`,{value:!0,enumerable:!1,writable:!1,configurable:!1})}get ontoolchange(){return this.#n}set ontoolchange(e){let t=typeof e==`function`?e:null;if(t===null){this.#n=null,super.removeEventListener(`toolchange`,this.#r);return}this.#n===null&&super.addEventListener(`toolchange`,this.#r),this.#n=t}async registerTool(e,t={}){g(this.#a);let n=t?.signal,r=Ee(e,this.#e);if(n?.throwIfAborted(),h(t?.exposedTo),n?.throwIfAborted(),t?.exposedTo?.length)throw new this.#i(`Cross-document tool exposure requires native WebMCP`,`NotSupportedError`);if(this.#e.set(r.name,r),n){let e=()=>{this.#o(r.name,r)&&this.#c()};r[H]=n,r[U]=e,n.addEventListener(`abort`,e,{once:!0})}if(await this.#c(),n?.aborted)throw n.reason}async getTools(e={}){if(g(this.#a),h(e?.fromOrigins),e?.fromOrigins?.length)throw new this.#i(`Cross-document tool discovery requires native WebMCP`,`NotSupportedError`);let t=[...this.#e.values()].map(e=>{let t=e[V],n=t===void 0?void 0:JSON.parse(t);return{name:e.name,title:e.title??``,description:e.description,...r(n)?{inputSchema:n}:{},origin:q(),window:globalThis.window,...e.annotations?{annotations:u(e.annotations)}:{}}}).sort((e,t)=>e.name<t.name?-1:+(e.name>t.name));return await new Promise(e=>setTimeout(e,0)),t}async executeTool(e,t,n={}){if(g(this.#a),typeof e!=`object`||!e)throw TypeError(`RegisteredTool must be an object`);for(let t of[`name`,`description`,`window`,`origin`])if(!(t in e))throw TypeError(`RegisteredTool.${t} is required`);if(te(e.origin),e.window!==globalThis.window||e.origin!==q())throw o(`Tool not found: ${e.name}`);return this.#s(e.name,t,n)}static getTestingShim(e){return e.#t??=new Te(e),e.#t}static getToolInfos(e){return[...e.#e.values()].map(e=>({name:e.name,description:e.description,...e[V]===void 0?{}:{inputSchema:e[V]}}))}static executeToolForTesting(e,t,n,r){return g(e.#a),e.#s(t,n,r)}static dispose(e){for(let t of e.#e.keys())e.#o(t);e.ontoolchange=null,e.#t?.dispose()}#o(e,t){let n=this.#e.get(e);if(!n||t&&n!==t)return!1;let r=n[H],i=n[U];return r&&i&&r.removeEventListener(`abort`,i),this.#e.delete(e)}async#s(e,t,n){n?.signal?.throwIfAborted();let r=this.#e.get(e);if(!r)throw o(`Tool not found: ${e}`);let i=d(t);if(n?.signal?.throwIfAborted(),r[H]?.aborted)throw o(`Tool unregistered`);let a;try{let e=r[H];a=await p(p(Promise.resolve(r.execute(i)),e,()=>o(`Tool unregistered`)),n?.signal)}catch(e){throw n?.signal?.aborted&&e===n.signal.reason||r[H]?.aborted?e:s(e)}return f(a)}async#c(){await new Promise(e=>setTimeout(e,0)),this.dispatchEvent(new Event(`toolchange`)),this.#t?.dispatchToolChange()}};let X=function(){throw TypeError(`Illegal constructor`)};Object.defineProperty(X,`name`,{value:`ModelContext`}),Object.defineProperty(X,`prototype`,{value:Y.prototype,writable:!1}),Object.setPrototypeOf(X,EventTarget),Object.defineProperty(Y.prototype,`constructor`,{configurable:!0,writable:!0,value:X}),Object.defineProperty(Y.prototype,Symbol.toStringTag,{configurable:!0,value:`ModelContext`});for(let e of[`registerTool`,`getTools`,`executeTool`,`ontoolchange`]){let t=Object.getOwnPropertyDescriptor(Y.prototype,e);t&&Object.defineProperty(Y.prototype,e,{...t,enumerable:!0})}var Te=class extends EventTarget{_ontoolchange=null;ontoolchangeListener=e=>{this._ontoolchange?.call(this,e)};#e;constructor(e){super(),this.#e=e}listTools(){return Y.getToolInfos(this.#e)}executeTool(e,t,n){return Y.executeToolForTesting(this.#e,e,t,n)}get ontoolchange(){return this._ontoolchange}set ontoolchange(e){let t=typeof e==`function`?e:null;if(t===null){this._ontoolchange=null,super.removeEventListener(`toolchange`,this.ontoolchangeListener);return}this._ontoolchange===null&&super.addEventListener(`toolchange`,this.ontoolchangeListener),this._ontoolchange=t}dispatchToolChange(){this.dispatchEvent(new Event(`toolchange`))}dispose(){this.ontoolchange=null}};function Ee(e,t){if(!e||typeof e!=`object`)throw TypeError(`registerTool(tool) requires a tool object`);let n=a(e);if(l(n),t.has(n.name))throw c(`Tool already registered: ${n.name}`);let r=n.inputSchema===void 0?void 0:ne(n.inputSchema);return{name:n.name,...n.title===void 0?{}:{title:n.title},description:n.description,...n.inputSchema===void 0?{}:{inputSchema:n.inputSchema},...n.annotations===void 0?{}:{annotations:n.annotations},execute:e=>Reflect.apply(n.execute,void 0,[e]),...r===void 0?{}:{[V]:r}}}let Z=!1,De=new WeakMap,{modelContext:Oe}={modelContext(){if(!(this instanceof Document))throw TypeError(`Illegal invocation`);return De.get(this)}};Object.defineProperty(Oe,`name`,{value:`get modelContext`});function ke(e,t){De.set(e,t),!Object.hasOwn(Document.prototype,`modelContext`)&&J(Document.prototype,`modelContext`,{configurable:!0,enumerable:!0,get:Oe})}function Ae(e,t){J(e,`modelContext`,{configurable:!0,enumerable:!0,get(){return Z||(Z=!0,console.warn(`[WebMCPPolyfill] navigator.modelContext is deprecated. The May 27, 2026 WebMCP draft moved the modelContext getter from Navigator to Document — use document.modelContext instead. See https://github.com/webmachinelearning/webmcp/pull/184.`)),t}})}function je(){let e=SubmitEvent.prototype;`agentInvoked`in e||J(e,`agentInvoked`,{configurable:!0,enumerable:!0,get(){return b(this)}}),`respondWith`in e||J(e,`respondWith`,{configurable:!0,enumerable:!0,writable:!0,value(e){re(this,e)}})}function Q(e){if(globalThis.isSecureContext===!1)return;let t=typeof navigator>`u`?null:navigator,n=typeof document>`u`?null:document;if(!t||!n||typeof window>`u`||n.modelContext)return;let r=t.modelContext;if(W.length>0&&$(),r){ke(n,r);return}let i=Object.getOwnPropertyDescriptor(window,`ModelContext`);if(i&&!i.configurable){if(!Object.is(Reflect.get(window,`ModelContext`),X))throw TypeError(`Cannot install ModelContext over a non-configurable global`)}else J(window,`ModelContext`,{configurable:!0,enumerable:!1,writable:!0,value:X});let a=new Y(n);G=a,ke(n,a),Z=!1,Ae(t,a),je(),e?.installTestingShim&&!t.modelContextTesting&&J(t,`modelContextTesting`,{configurable:!0,enumerable:!0,writable:!1,value:Y.getTestingShim(a)}),K=we(n,a)}function $(){K?.(),K=null,G&&Y.dispose(G),G=null;for(let{target:e,key:t,previous:n}of[...W].reverse())n?Object.defineProperty(e,t,n):Reflect.deleteProperty(e,t);W.length=0,Z=!1}try{Q(window.__webMCPPolyfillOptions)}catch(e){console.error(`[WebMCPPolyfill] Auto-initialization failed:`,e)}return e.cleanupWebMCPPolyfill=$,e.initializeWebMCPPolyfill=Q,e})({});
1
+ var WebMCPPolyfill=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});let t=[`consequentialHint`,`debugging`,`readOnlyHint`,`untrustedContentHint`],n=`webmcp-polyfill`,r=globalThis.DOMException;var i=class{#e;#t;#n;#r=new Set;#i=new Set;#a=Promise.withResolvers();#o=new Map;#s=new Set;#c;#l=!1;constructor(e,t){this.#t=e,this.#e=e.document,this.#n=t,this.#t.addEventListener(`message`,e=>this.#d(e),!0),this.#t.addEventListener(`pagehide`,()=>{this.#l=!0;for(let e of this.#s)e.end()}),this.#t.addEventListener(`pageshow`,e=>{e.persisted&&(this.#l=!1,this.#x())});for(let e of this.#x())this.#i.add(e);this.#i.size===0?this.#a.resolve():setTimeout(()=>{this.#i.clear(),this.#a.resolve()},500)}async allowed(){return this.#l?!1:this.#h(this.#e)}async getTools(e){await this.#a.promise;let t=this.#t.origin,n=[t,...e];return(await Promise.all(this.#b().map(async e=>{if(e===this.#t)return this.#n.getTools(t).map(e=>d(e,this.#t,t));try{let t=await this.#u(e,n,{kind:`getTools`});if(!Array.isArray(t.value))throw TypeError(`Expected a tool list from the frame`);return t.value.map(n=>d(f(n),e,t.origin))}catch(e){return e instanceof r&&e.name===`UnknownError`||console.warn(`WebMCP: could not read tools from a frame.`,e),[]}}))).flat()}async execute(e,t,n,r,i){let a=await this.#u(e,[t],{kind:`execute`,name:n,input:r},i);if(typeof a.value!=`string`)throw g();return a.value}async notify(e){await this.#a.promise;let t=[this.#t.origin,...e];for(let e of this.#b()){if(e===this.#t){await this.#n.changed();continue}try{await this.#u(e,t,{kind:`changed`})}catch{}}}#u(e,t,r,i){return new Promise((a,o)=>{if(i?.throwIfAborted(),this.#l||!this.#v(e)){o(g());return}let s=crypto.randomUUID(),{port1:c,port2:l}=new MessageChannel,u,d=()=>{clearTimeout(v),y(),i?.removeEventListener(`abort`,p),this.#o.delete(s),c.close()},f=(e=g())=>{c.postMessage({kind:`cancel`}),d(),o(e)},p=()=>f(i?.reason),h=()=>{u===void 0&&this.#C(e),f()},_=n=>{if(n.source===e){if(this.#o.delete(s),t&&!t.includes(n.origin)){f();return}u=n.origin,clearTimeout(v),r.kind!==`execute`&&r.kind!==`changed`&&(v=setTimeout(h,500)),c.postMessage(r)}},v=setTimeout(h,500),y=this.#w(e,f);c.onmessage=e=>{let t=m(e.data);if(t?.kind===`error`){f();return}t?.kind!==`result`||u===void 0||(d(),a({value:t.value,origin:u}))},c.onmessageerror=()=>f(),i?.addEventListener(`abort`,p,{once:!0}),this.#o.set(s,_);try{e.postMessage(`${n}:connect:${s}`,`*`,[l])}catch{l.close(),f()}})}#d(e){let t=p(e.data);if(!t)return;e.stopImmediatePropagation();let r=e.source;if(!e.isTrusted||!r||!h(r)||!this.#v(r)||e.origin===`null`||this.#l)return;if(t.kind===`announce`){let t=!this.#r.has(r);if(this.#S(r),r.postMessage(`${n}:present`,e.origin),!t||this.#t!==this.#t.top)return;for(let e of this.#r)e!==r&&e.postMessage(`${n}:refresh`,`*`);return}if(t.kind===`present`){this.#S(r);return}if(t.kind===`refresh`){r===this.#t.top&&this.#x();return}if(t.kind===`ready`){this.#o.get(t.id)?.(e);return}let[i]=e.ports;t.kind!==`connect`||!t.id||!i||e.ports.length!==1||(this.#S(r),this.#f(r,e.origin,t.id,i))}#f(e,t,r,i){let a=new AbortController,o=!1,s=()=>{clearTimeout(u),d(),i.close()},c=()=>{a.abort(),s()},l=()=>{i.postMessage({kind:`error`}),c()},u=setTimeout(l,500),d=this.#w(e,l);i.onmessageerror=l,i.onmessage=async n=>{let r=m(n.data);if(r?.kind===`cancel`){c();return}if(!o){o=!0,clearTimeout(u);try{let n=await this.#p(e,t,r,a.signal);i.postMessage({kind:`result`,value:n}),s()}catch{l()}}},e.postMessage(`${n}:ready:${r}`,t)}async#p(e,t,n,r){if(!n||!this.#v(e))throw g();if(n.kind===`permission`){let{childIndex:e,childOrigin:t}=n;if(typeof e!=`number`||!Number.isInteger(e)||e<0||typeof t!=`string`)throw g();return this.#m(e,t)}if(!await this.allowed()||!await this.#g(e,t)||!this.#v(e))throw g();if(r.throwIfAborted(),n.kind===`getTools`)return this.#n.getTools(t);if(n.kind===`execute`&&typeof n.name==`string`&&typeof n.input==`string`)return this.#n.execute(t,n.name,n.input,r);if(n.kind===`changed`){await this.#n.changed();return}throw g()}async#m(e,t){let n=this.#t[e];return n!==void 0&&await this.allowed()&&a(this.#e,n,t)}async#h(e){let t=l(e);if(!t)return!1;let n=u(e);if(n!==void 0)return n;if(t===t.parent)return!0;let r=t.location.ancestorOrigins?.[0],i=o(t.parent,r===void 0||r===t.origin);return i?a(i,t,t.origin)&&await this.#h(i):this.#_(t,t.origin)}async#g(e,t){let n=o(e,t===this.#t.origin);return n?this.#h(n):this.#_(e,t)}async#_(e,t){let n=e.parent;if(n===e)return!0;let r=-1;for(let t=0;t<n.length;t++)if(n[t]===e){r=t;break}if(r<0)return!1;if(n===this.#t)return await this.allowed()&&a(this.#e,e,t);if(await this.#a.promise,!this.#r.has(n))return!1;try{let e=await this.#u(n,void 0,{kind:`permission`,childIndex:r,childOrigin:t});return e.value===!0&&await this.#g(n,e.origin)}catch{return!1}}#v(e){try{return!e.closed&&e!==this.#t&&e.top===this.#t.top}catch{return!1}}#y(){if(this.#t.closed)return[];for(let e of this.#r)this.#v(e)||this.#r.delete(e);let e=[this.#t,...this.#r];for(let t=this.#t.parent;t!==t.parent;t=t.parent)e.push(t);let t=new Set,n=[this.#t.top];for(;n.length;){let r=n.pop();if(t.has(r))continue;t.add(r);let i=[];for(let e=0;e<r.length;e++){let t=r[e];t&&i.push(t)}for(let t of e)t!==r&&t.parent===r&&!i.includes(t)&&i.push(t);n.push(...i.reverse())}return Array.from(t).filter(e=>e===this.#t||this.#v(e))}#b(){return this.#y().filter(e=>e===this.#t||this.#r.has(e))}#x(){let e=this.#y().filter(e=>e!==this.#t);for(let t of e)t.postMessage(`${n}:announce`,`*`);return e}#S(e){this.#r.add(e),this.#i.delete(e),this.#i.size===0&&this.#a.resolve()}#C(e){this.#r.delete(e),this.#v(e)&&e.postMessage(`${n}:announce`,`*`)}#w(e,t){let n={peer:e,end:t};return this.#s.add(n),this.#c===void 0&&(this.#c=this.#t.setInterval(()=>{for(let e of this.#s)this.#v(e.peer)||e.end()},100)),()=>{this.#s.delete(n),this.#s.size===0&&(this.#t.clearInterval(this.#c),this.#c=void 0)}}};function a(e,t,n){let r=e.defaultView?.origin,i=s(e,t,n===r);if(!i)return!1;let a=(i.getAttribute(`allow`)??``).split(`;`).map(e=>e.trim().split(/\s+/u)).find(([e])=>e===`tools`);if(!a)return n===r;let o=a.length===1?[`'src'`]:a.slice(1);if(o.includes(`'none'`))return!1;let c=i.hasAttribute(`srcdoc`)?null:i.getAttribute(`src`),l=c?URL.parse(c,e.baseURI):null,u=!c||l?.protocol===`about:`?r:l?.origin;return o.some(e=>e===`*`||e===`'self'`&&n===r||e===`'src'`&&n===u||e===n)}function o(e,t){if(t)try{return e.document}catch{return}}function s(e,t,n){if(n)try{let n=t.frameElement;if(n?.ownerDocument===e)return n}catch{}return c(e,t)}function c(e,t){let n=e.querySelectorAll(`iframe, frame`);for(let e of n)if(e.contentWindow===t)return e;for(let n of e.querySelectorAll(`*`)){if(!n.shadowRoot)continue;let e=c(n.shadowRoot,t);if(e)return e}}function l(e){let t=e.defaultView;return t&&!t.closed&&t.document===e?t:void 0}function u(e){let t=e,n=m(t.permissionsPolicy??t.featurePolicy);if(typeof n?.features!=`function`||typeof n.allowsFeature!=`function`)return;let r=n.features();return Array.isArray(r)&&r.includes(`tools`)?!!n.allowsFeature(`tools`):void 0}function d(e,t,n){let r=e.serializedSchema===void 0?void 0:JSON.parse(e.serializedSchema);return{...e.annotations!==void 0&&{annotations:{...e.annotations}},description:e.description,...r!==void 0&&{inputSchema:r},name:e.name,origin:n,title:e.title,window:t}}function f(e){let n=m(e);if(!n||typeof n.name!=`string`||typeof n.title!=`string`||typeof n.description!=`string`||n.serializedSchema!==void 0&&typeof n.serializedSchema!=`string`)throw TypeError(`Invalid tool metadata from the frame`);let r={name:n.name,title:n.title,description:n.description,annotations:void 0,serializedSchema:n.serializedSchema};if(n.annotations===void 0)return r;let i=m(n.annotations);if(!i)throw TypeError(`Invalid tool annotations from the frame`);let a={};for(let e of t){let t=i[e];if(t!==void 0){if(typeof t!=`boolean`)throw TypeError(`Invalid ${e} annotation from the frame`);a[e]=t}}return r.annotations=a,r}function p(e){if(typeof e!=`string`)return;let[t,r=``,i=``,a]=e.split(`:`);return t===n&&a===void 0?{kind:r,id:i}:void 0}function m(e){if(!(typeof e!=`object`||!e||Array.isArray(e)))return e}function h(e){try{return`postMessage`in e&&`window`in e}catch{return!1}}function g(){return new r(`Tool execution failed`,`UnknownError`)}let _=new WeakSet,v=new WeakMap,y=new WeakMap;function b(e){return e.isTrusted&&(_.has(e)||e.eventPhase!==Event.NONE&&e.target instanceof HTMLFormElement&&y.has(e.target))}function ee(e,t){if(!b(e))throw new DOMException(`respondWith() is only available during an agent-invoked submit event`,`InvalidStateError`);if(!e.defaultPrevented)throw new DOMException(`respondWith() requires preventDefault() during an agent-invoked submit event`,`InvalidStateError`);if(e.eventPhase===Event.NONE)throw new DOMException(`respondWith() is only available while the submit event is being dispatched`,`InvalidStateError`);_.add(e);let n=Promise.resolve(t);v.set(e,n),e.target instanceof HTMLFormElement&&y.get(e.target)?.respond(e)}let x=new Set([`email`,`password`,`search`,`tel`,`text`,`url`]),te=new Set([...x,`date`,`datetime-local`,`month`,`number`,`time`,`week`]);function ne(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function S(e){return Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,`elements`)?.get?.call(e)}function C(e,t){return Element.prototype.getAttribute.call(e,t)}function w(e,t){return Element.prototype.hasAttribute.call(e,t)}function T(e){return Object.getOwnPropertyDescriptor(Node.prototype,`isConnected`)?.get?.call(e)}function re(e){return Object.getOwnPropertyDescriptor(Element.prototype,`shadowRoot`)?.get?.call(e)}function ie(e){return HTMLFormElement.prototype.checkValidity.call(e)}function ae(e,t){HTMLFormElement.prototype.requestSubmit.call(e,t)}function oe(e){return[...S(e)].filter(e=>ne(e)&&!e.matches(`:disabled`)&&!(`readOnly`in e&&e.readOnly&&(e instanceof HTMLTextAreaElement||te.has(e.type))))}function se(e){let t=new Map;for(let n of oe(e)){let e=n.name.trim(),r=t.get(e);r?r.push(n):t.set(e,[n])}return t}function ce(e){return[...e.labels??[]].map(e=>{let t=e.cloneNode(!0);return t instanceof HTMLElement?(t.querySelectorAll(`button, input, meter, output, progress, select, textarea`).forEach(e=>e.remove()),t.textContent?.trim()??``):``}).filter(Boolean).join(`; `)}function le(e,t){for(let n=t[0]?.parentElement;n&&n!==e;n=n.parentElement)if(n instanceof HTMLFieldSetElement&&t.every(e=>n.contains(e)))return n}function ue(e,t){if(t.length===1){let e=t[0];return e&&(e.getAttribute(`toolparamdescription`)||ce(e)||e.getAttribute(`aria-description`))||void 0}return le(e,t)?.getAttribute(`toolparamdescription`)||void 0}function de(e,t,n,r){let i=ue(t,n),a=i&&r?`${i} (${r})`:i||r;return a?{...e,description:a}:e}function fe(e,t){let n=e.getAttribute(t);if(n===null||n.trim()===``)return;let r=Number(n);return Number.isFinite(r)?r:void 0}function pe(e,t){let n=Number(e.getAttribute(`step`));return Number.isFinite(n)&&n>0?n:t}function me(e,t){let n=e/t;return Math.abs(n-Math.round(n))<2**-52*16}function E(e,t){let n=t.getAttribute(`pattern`);if(n===null)return e;try{new RegExp(n,`v`)}catch{return e}return{...e,pattern:n}}function D(e){let t={type:`number`},n=fe(e,`min`),r=fe(e,`max`);if(n!==void 0&&(t.minimum=n),r!==void 0&&(t.maximum=r),e.getAttribute(`step`)!==`any`){let r=pe(e,1),i=Number(e.getAttribute(`value`));me(n??(Number.isFinite(i)?i:0),r)&&(t.multipleOf=r)}return t}function O(e,t){let n=pe(e,60);return n<1?`${t}(:[0-5][0-9](\\.[0-9]{1,3})?)?$`:n<60?`${t}(:[0-5][0-9])?$`:`${t}$`}function he(e){return{anyOf:e.map(e=>({type:`string`,const:e.value,title:e.textContent??``})),enum:e.map(e=>e.value)}}function k(e){return{anyOf:e.map(e=>{let t=ce(e),n={type:`string`,const:e.value};return t&&(n.title=t),n}),enum:e.map(e=>e.value)}}function A(e,t){return e instanceof HTMLInputElement&&e.type===t}function ge(e){if(x.has(e.type))return E({type:`string`},e);switch(e.type){case`hidden`:return e.getAttribute(`toolparamdescription`)?{type:`string`}:void 0;case`number`:return E(D(e),e);case`range`:{let t=D(e);return t.minimum??=0,t.maximum??=100,t}case`checkbox`:return{type:`boolean`};case`date`:return{type:`string`,format:`date`};case`month`:return{type:`string`,format:`^[0-9]{4}-(0[1-9]|1[0-2])$`};case`week`:return{type:`string`,format:`^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$`};case`time`:return{type:`string`,format:O(e,`^([01][0-9]|2[0-3]):[0-5][0-9]`)};case`datetime-local`:return{type:`string`,format:O(e,`^[0-9]{4}-(0[1-9]|1[0-2])-[0-9]{2}T([01][0-9]|2[0-3]):[0-5][0-9]`)};case`color`:return{type:`string`,format:`^#[0-9a-zA-Z]{6}$`};default:return}}function j(e,t){let[n]=t;if(!n)return;let r;if(t.every(e=>A(e,`radio`)))r={type:`string`,...k(t)};else if(t.length>1)t.every(e=>A(e,`checkbox`))&&(r={type:`array`,items:{type:`string`,...k(t)},uniqueItems:!0});else if(n instanceof HTMLTextAreaElement)r={type:`string`};else if(n instanceof HTMLSelectElement){let e=he([...n.options]);r=n.multiple?{type:`array`,items:{type:`string`,...e},uniqueItems:!0}:{type:`string`,...e}}else r=ge(n);let i=n.type===`date`?`Dates MUST be provided in 'YYYY-MM-DD' format.`:void 0;return r&&de(r,e,t,i)}function _e(e){let t={},n=[];for(let[r,i]of se(e)){if(!r)continue;let a=j(e,i);a&&(Object.defineProperty(t,r,{configurable:!0,enumerable:!0,value:a,writable:!0}),i.some(e=>e.required)&&n.push(r))}return{type:`object`,properties:t,required:n}}function ve(e){return{name:C(e,`toolname`)??``,title:C(e,`tooltitle`)??``,description:C(e,`tooldescription`)??``,inputSchema:_e(e),autosubmit:w(e,`toolautosubmit`)}}function M(e){if(typeof e==`string`||typeof e==`boolean`||typeof e==`number`&&Number.isFinite(e))return String(e)}function N(e){if(typeof e==`boolean`)return e;if(typeof e==`number`&&Number.isInteger(e))return e!==0;if(typeof e==`string`){if(e===`1`||e.toLowerCase()===`true`)return!0;if(e===`0`||e.toLowerCase()===`false`)return!1}}function P(e,t){if(!Array.isArray(e))return!1;let n=new Set(t);for(let t of e){let e=M(t);if(e===void 0||!n.delete(e))return!1}return!0}function ye(e,t){if(t===``)return e.type!==`number`&&e.type!==`range`;let n=e.ownerDocument.createElement(`input`);return n.type=e.type,n.value=t,n.value!==``}function be(e,t,n){let[r]=t;if(!r||!j(e,t))return!1;let i=M(n);if(t.every(e=>A(e,`radio`)))return t.some(e=>e.value===i);if(t.length>1)return P(n,new Set(t.map(e=>e.value)));if(r instanceof HTMLSelectElement){let e=new Set([...r.options].map(e=>e.value));return r.multiple?P(n,e):i!==void 0&&e.has(i)}return r instanceof HTMLTextAreaElement?i!==void 0:r.type===`checkbox`?N(n)!==void 0:i!==void 0&&ye(r,i)}function F(e){e.dispatchEvent(new Event(`input`,{bubbles:!0,composed:!0})),e.dispatchEvent(new Event(`change`,{bubbles:!0}))}function xe(e,t){if(e.value===t)return;let n=e instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype;Object.getOwnPropertyDescriptor(n,`value`)?.set?.call(e,t),F(e)}function I(e,t){e.checked!==t&&(Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,`checked`)?.set?.call(e,t),F(e))}function Se(e,t){let[n]=e,r=M(t),i=new Set(Array.isArray(t)?t.map(M):[]);if(e.every(e=>A(e,`radio`))){let t=e.find(e=>e.value===r);t&&I(t,!0)}else if(e.length>1)for(let t of e)t instanceof HTMLInputElement&&I(t,i.has(t.value));else if(n instanceof HTMLSelectElement)if(n.multiple){let e=!1;for(let t of n.options){let n=i.has(t.value);t.selected!==n&&(t.selected=n,e=!0)}e&&F(n)}else r!==void 0&&n.value!==r&&(n.value=r,F(n));else if(n&&A(n,`checkbox`)){let e=N(t);e!==void 0&&I(n,e)}else n&&r!==void 0&&xe(n,r)}function Ce(e,t){if(Array.isArray(t))throw g();let n=se(e),r=[];for(let[i,a]of Object.entries(t)){let t=n.get(i);if(!t||!be(e,t,a))throw g();r.push({controls:t,value:a})}for(let{controls:e,value:t}of r)Se(e,t)}function we(e){return[...S(e)].find(e=>!e.matches(`:disabled`)&&(e instanceof HTMLButtonElement&&e.type===`submit`||e instanceof HTMLInputElement&&[`image`,`submit`].includes(e.type)))}function L(e,t){let n=new Event(e);return Object.defineProperty(n,"toolName",{enumerable:!0,value:t}),n}function Te(e,t,n,r,i){let{form:a}=t;return t.cancelPending?.(g()),new Promise((o,s)=>{let c=!1,l=()=>{EventTarget.prototype.removeEventListener.call(a,`invalid`,p,!0),i.removeEventListener(`abort`,m),y.delete(a),t.cancelPending===d&&delete t.cancelPending},u=e=>{c||(c=!0,l(),e())},d=e=>u(()=>s(e)),f=e=>{e.then(e=>u(()=>o(e??null)),e=>u(()=>s(e)))},p=e=>{e.isTrusted&&queueMicrotask(()=>{ie(a)||d(g())})},m=()=>{u(()=>{e.dispatchEvent(L(`toolcancel`,n.name)),s(i.reason)})};if(y.set(a,{complete(e){queueMicrotask(()=>{let t=v.get(e);t?f(t):e.defaultPrevented?d(g()):u(()=>o(null))})},direct(){u(()=>o(null))},respond(e){queueMicrotask(()=>{let t=v.get(e);t&&f(t)})}}),t.cancelPending=d,EventTarget.prototype.addEventListener.call(a,`invalid`,p,!0),i.addEventListener(`abort`,m,{once:!0}),!n.autosubmit){r?.focus(),e.dispatchEvent(L(`toolactivated`,n.name));return}try{ae(a,r),e.dispatchEvent(L(`toolactivated`,n.name))}catch(e){d(e)}})}function Ee(e){let t=SubmitEvent.prototype;if(`agentInvoked`in t&&`respondWith`in t)return;`agentInvoked`in t||Object.defineProperty(t,"agentInvoked",{configurable:!0,enumerable:!0,get(){return b(this)}}),`respondWith`in t||Object.defineProperty(t,"respondWith",{configurable:!0,enumerable:!0,writable:!0,value(e){ee(this,e)}});let n=new Map,r=new Map,i=new Map,a=e=>{if(!(e instanceof SubmitEvent)||!e.isTrusted||!(e.target instanceof HTMLFormElement))return;let t=y.get(e.target);t&&(_.add(e),t.complete(e))},o=e=>{if(!e.isTrusted||!(e.target instanceof HTMLFormElement))return;let t=e.target;queueMicrotask(()=>{e.defaultPrevented||n.get(t)?.cancelPending?.(g())})};function s(e){i.get(e)?.disconnect(),i.delete(e),e.removeEventListener(`reset`,o,!0),e.removeEventListener(`submit`,a,!0)}function c(e){if(i.has(e))return;let t=new MutationObserver(l);i.set(e,t),t.observe(e,{attributes:!0,characterData:!0,childList:!0,subtree:!0}),e.addEventListener(`reset`,o,!0),e.addEventListener(`submit`,a,!0)}function l(){c(document);for(let e of i.keys())e instanceof ShadowRoot&&!e.host.isConnected&&s(e);let t=new Set,a=new Map,o=new Map;for(let e of i.keys())for(let n of e.querySelectorAll(`*`)){let e=re(n);if(e&&c(e),!(n instanceof HTMLFormElement)||!w(n,`toolname`)||!w(n,`tooldescription`)||!T(n))continue;let i=n;t.add(i);let s=ve(i),l=JSON.stringify(s),u=r.get(i);if(u===l)continue;r.delete(i);let d=o.get(s.name);if(d){if(u===void 0){r.set(i,l);continue}let e=a.get(d);e&&r.set(d,e.fingerprint),a.delete(d)}o.set(s.name,i),a.set(i,{definition:s,fingerprint:l})}for(let e of r.keys())t.has(e)||r.delete(e);for(let[e,t]of n)a.get(e)?.fingerprint!==t.fingerprint&&(t.cancelPending?.(g()),t.controller.abort(),n.delete(e));for(let[t,{definition:r,fingerprint:i}]of a){if(n.has(t))continue;let a=new AbortController,o={controller:a,fingerprint:i,form:t};n.set(t,o),e.registerTool({name:r.name,title:r.title,description:r.description,inputSchema:r.inputSchema,execute(n,i){let a=we(t);if(!r.autosubmit&&!a)throw g();return Ce(t,n),Te(e,o,r,a,i.signal)}},{signal:a.signal}).catch(e=>{a.abort(),!(e instanceof DOMException&&e.name===`AbortError`)&&console.error(`[webmcp] declarative form tool "${r.name}" was not registered:`,e)})}}let u=Object.getOwnPropertyDescriptor(Element.prototype,`attachShadow`);if(u?.configurable){let e=Element.prototype.attachShadow,t=function(t){let n=e.call(this,t);return n.mode===`open`&&Object.getOwnPropertyDescriptor(Node.prototype,`ownerDocument`)?.get?.call(this)===document&&T(this)&&c(n),n};Object.defineProperty(Element.prototype,"attachShadow",{...u,value:t})}let d=Object.getOwnPropertyDescriptor(HTMLFormElement.prototype,`submit`);if(d?.configurable){let e=HTMLFormElement.prototype.submit,t=function(){e.call(this),y.get(this)?.direct()};Object.defineProperty(HTMLFormElement.prototype,"submit",{...d,value:t})}l()}
2
+ /*!
3
+ * Copyright (c) 2026 WebMCP polyfill contributors
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ let R=globalThis.DOMException,De=Object.getOwnPropertyDescriptor(globalThis,`window`)?.get,z=new WeakMap;function Oe(){if(typeof document>`u`||!globalThis.isSecureContext||`modelContext`in document)return;let e=Document.prototype,t=Object.getOwnPropertyDescriptor(e,`defaultView`).get,n=Object.getOwnPropertyDescriptor(globalThis,`ModelContext`);if(!Object.isExtensible(e)||n&&!n.configurable||!n&&!Object.isExtensible(globalThis))throw TypeError(`Cannot install WebMCP on this realm`);Object.defineProperty(globalThis,"ModelContext",{value:H,configurable:!0,writable:!0});let{getModelContext:r}={getModelContext(){t.call(this);let e=z.get(this);return e||(e=new B(this),z.set(this,e)),e}};Object.defineProperty(r,"name",{value:`get modelContext`}),Object.defineProperty(e,"modelContext",{configurable:!0,enumerable:!0,get:r}),document.modelContext}var B=class extends EventTarget{#e;#t=new Map;#n;#r=null;#i=e=>{let t=this.#r;typeof t==`function`&&Reflect.apply(t,this,[e])===!1&&Event.prototype.preventDefault.call(e)};constructor(e){super(),this.#e=e;let t=l(e);t&&(this.#n=new i(t,{getTools:e=>this.#s(e),execute:(t,n,r,i)=>{let a=Z(e).origin;return this.#a(n,r,a,t,i)},changed:()=>this.#c()}))}get ontoolchange(){return this.#r}set ontoolchange(e){let t=W(e)?e:null;!this.#r&&t&&this.addEventListener(`toolchange`,this.#i),this.#r&&!t&&this.removeEventListener(`toolchange`,this.#i),this.#r=t}async registerTool(e,t={}){let n=this.#e,{name:r,title:i,description:a,annotations:o,inputSchema:s,execute:c}=ke(e),l=G(t),u=Ne(l.exposedTo),d=Me(l.signal);Z(n);let f=()=>{if(this.#t.has(r))throw new R(`A tool named ${r} is already registered`,`InvalidStateError`)};if(f(),!/^[A-Za-z0-9_.-]{1,128}$/u.test(r))throw new R(`Tool names are 1 to 128 characters of ASCII alphanumerics, "_", "-" or ".": ${r}`,`InvalidStateError`);if(!a)throw new R(`A tool description cannot be empty`,`InvalidStateError`);let p=s===void 0?void 0:Y(s);d?.throwIfAborted();let m=X(u),h={metadata:{name:r,title:i,description:a,annotations:o,serializedSchema:p},execute:c,exposedTo:m},g=await this.#o();return d?.throwIfAborted(),f(),new Promise((e,t)=>{d?.addEventListener(`abort`,()=>{this.#t.delete(r),g.notify(m),t(d.reason)},{once:!0}),this.#t.set(r,h),g.notify(m).then(e,t)})}async getTools(e={}){let t=this.#e,n=Ne(G(e).fromOrigins);Z(t);let r=await this.#o(),i=X(n),a=await r.getTools(i);return a.sort((e,t)=>e.name===t.name?0:e.name<t.name?-1:1),new Promise(e=>{$(()=>e(a))})}async executeTool(e,t={},n={}){let r=this.#e,i=Ae(e),a=Me(G(n).signal);Z(r);let o=URL.parse(i.origin)?.origin;if(!o||o===`null`)throw new R(`Invalid or opaque origin`,`NotSupportedError`);if(!W(t))throw TypeError(`inputObject must be an object`);let s=Y(t);a?.throwIfAborted();let c=await this.#o();a?.throwIfAborted();let l=Z(r);return i.window===l?this.#a(i.name,s,o,l.origin,a):c.execute(i.window,o,i.name,s,a)}#a(e,t,n,r,i){return new Promise((a,o)=>{i?.throwIfAborted();let s=new AbortController,c=!1,l=()=>{o(i.reason),$(()=>{c||s.abort()})},u=()=>{c=!0,$(()=>{i?.removeEventListener(`abort`,l),o(g())})},d=e=>{if(c=!0,!i?.aborted)try{let t=Y(e);$(()=>{i?.removeEventListener(`abort`,l),a(t)})}catch{u()}};i?.addEventListener(`abort`,l,{once:!0}),$(()=>{if(!i?.aborted)try{let i=Z(this.#e),a=this.#t.get(e);if(!a||n!==i.origin||!V(a,i.origin,r)){u();return}let o=JSON.parse(t);if(!W(o)){u();return}let c=a.execute,l=c(o,{signal:s.signal});Promise.resolve(l).then(d,u)}catch{u()}})})}async#o(){let e=this.#n;if(!e||!await e.allowed())throw new R(`WebMCP is disabled by Permissions Policy`,`NotAllowedError`);return Z(this.#e),e}#s(e){let t=Z(this.#e).origin,n=[];for(let r of this.#t.values())V(r,t,e)&&n.push(r.metadata);return n}#c(){return new Promise(e=>{$(()=>{this.dispatchEvent(new Event(`toolchange`)),e()})})}};function V(e,t,n){return t===n||e.exposedTo.includes(n)}let H=function(){throw TypeError(`Illegal constructor`)};Object.defineProperty(H,"name",{value:`ModelContext`}),Object.defineProperty(H,"prototype",{value:B.prototype,writable:!1}),Object.setPrototypeOf(H,EventTarget),Object.defineProperties(B.prototype,{constructor:{value:H,configurable:!0,writable:!0},[Symbol.toStringTag]:{value:`ModelContext`,configurable:!0},registerTool:{enumerable:!0},getTools:{enumerable:!0},executeTool:{enumerable:!0},ontoolchange:{enumerable:!0}});function ke(e){let t=G(e),n=je(t.annotations),r=K(J(t.description,`description`)),i=J(t.execute,`execute`);if(typeof i!=`function`)throw TypeError(`execute must be a function`);let a=i,o=U(t.inputSchema),s=K(J(t.name,`name`)),c=t.title;return{name:s,title:c===void 0?``:q(c),description:r,annotations:n,inputSchema:o,execute:a}}function Ae(e){let t=G(e);je(t.annotations),K(J(t.description,`description`)),U(t.inputSchema);let n=K(J(t.name,`name`)),r=q(J(t.origin,`origin`)),i=t.title;i!==void 0&&K(i);let a=J(t.window,`window`);if(!W(a))throw TypeError(`window must be a Window`);return De.call(a),{name:n,origin:r,window:a}}function U(e){if(e!==void 0&&!W(e))throw TypeError(`inputSchema must be an object`);return e}function W(e){return typeof e==`object`&&!!e||typeof e==`function`}function G(e){if(e==null)return{};if(!W(e))throw TypeError(`Expected a dictionary`);return e}function je(e){if(e===void 0)return;let n=G(e),r={};for(let e of t)r[e]=!!n[e];return r}function K(e){if(typeof e==`symbol`)throw TypeError(`Cannot convert a Symbol to a string`);return String(e)}function q(e){return K(e).toWellFormed()}function J(e,t){if(e===void 0)throw TypeError(`${t} is required`);return e}function Y(e){let t=JSON.stringify(e);if(t===void 0)throw TypeError(`Value is not JSON-serializable`);return t}function Me(e){if(e!==void 0)return AbortSignal.any([e])}function Ne(e){if(e===void 0)return[];if(!W(e))throw TypeError(`Origins must be a sequence`);let t=G(e)[Symbol.iterator];if(typeof t!=`function`)throw TypeError(`Origins must be a sequence`);let n={[Symbol.iterator](){let n=Reflect.apply(t,e,[]);if(!W(n))throw TypeError(`Iterator must be an object`);let r=G(n).next;if(typeof r!=`function`)throw TypeError(`Iterator next must be a function`);return{next(){return Reflect.apply(r,n,[])}}}};return Array.from(n,q)}function X(e){return e.map(e=>{let t=URL.parse(e)?.origin;if(t===void 0)throw new R(`Invalid origin`,`SecurityError`);let n=URL.parse(t);if(!n||!Pe(n))throw new R(`Origin is not potentially trustworthy`,`SecurityError`);return t})}function Pe({protocol:e,hostname:t}){if([`https:`,`wss:`].includes(e))return!0;let n=t===`[::1]`||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t),r=t===`localhost`||t===`localhost.`||t.endsWith(`.localhost`)||t.endsWith(`.localhost.`);return[`http:`,`ws:`].includes(e)&&(n||r)}function Z(e){let t=l(e);if(!t)throw new R(`The document is not fully active`,`InvalidStateError`);if(t.originAgentCluster===!1&&t.location.protocol!==`file:`)throw new R(`An origin-keyed agent cluster is required`,`SecurityError`);if(u(e)===!1)throw new R(`WebMCP is disabled by Permissions Policy`,`NotAllowedError`);return t}let Q,Fe=[];function $(e){if(!Q){let e=new MessageChannel;e.port1.onmessage=()=>Fe.shift()?.(),Q=e.port2}Fe.push(e),Q.postMessage(void 0)}function Ie(){if(typeof document>`u`||!globalThis.isSecureContext||typeof Promise.withResolvers!=`function`||typeof AbortSignal.any!=`function`||typeof String.prototype.toWellFormed!=`function`||typeof URL.parse!=`function`)return;Oe();let e=document.modelContext;e&&Ee(e)}try{Ie()}catch(e){console.error(`[WebMCPPolyfill] Auto-initialization failed:`,e)}return e.installWebMCP=Ie,e})({});