@mcp-b/webmcp-polyfill 5.1.0 → 6.0.0

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.
package/dist/schema.js DELETED
@@ -1,274 +0,0 @@
1
- //#region src/schema.ts
2
- const DEFAULT_INPUT_SCHEMA = {
3
- type: "object",
4
- properties: {}
5
- };
6
- const FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE = "Failed to parse input arguments";
7
- const TOOL_INVOCATION_FAILED_MESSAGE = "Tool was executed but the invocation failed. For example, the script function threw an error";
8
- const STANDARD_JSON_SCHEMA_TARGETS = ["draft-2020-12", "draft-07"];
9
- const VALID_TOOL_NAME_RE = /^[A-Za-z0-9_.-]{1,128}$/u;
10
- function isPlainObject(value) {
11
- return typeof value === "object" && value !== null && !Array.isArray(value);
12
- }
13
- function toDomString(value) {
14
- if (typeof value === "symbol") throw new TypeError("Symbol values cannot be converted to a DOMString");
15
- return String(value);
16
- }
17
- function coerceWebMcpToolDescriptor(tool) {
18
- const name = Reflect.get(tool, "name");
19
- const description = Reflect.get(tool, "description");
20
- const title = Reflect.get(tool, "title");
21
- if (name === void 0) throw new TypeError("Tool \"name\" is required");
22
- if (description === void 0) throw new TypeError("Tool \"description\" is required");
23
- const annotations = Reflect.get(tool, "annotations");
24
- const annotationMembers = isPlainObject(annotations) ? annotations : {};
25
- const inputSchema = Reflect.get(tool, "inputSchema");
26
- const outputSchema = Reflect.get(tool, "outputSchema");
27
- const execute = Reflect.get(tool, "execute");
28
- return {
29
- name: toDomString(name),
30
- ...title === void 0 ? {} : { title: toDomString(title).toWellFormed() },
31
- description: toDomString(description),
32
- ...inputSchema === void 0 ? {} : { inputSchema },
33
- ...outputSchema === void 0 ? {} : { outputSchema },
34
- execute,
35
- ...annotations === void 0 ? {} : { annotations: {
36
- ...annotationMembers.title === void 0 ? {} : { title: toDomString(annotationMembers.title).toWellFormed() },
37
- readOnlyHint: Boolean(annotationMembers.readOnlyHint),
38
- ...annotationMembers.destructiveHint === void 0 ? {} : { destructiveHint: Boolean(annotationMembers.destructiveHint) },
39
- ...annotationMembers.idempotentHint === void 0 ? {} : { idempotentHint: Boolean(annotationMembers.idempotentHint) },
40
- ...annotationMembers.openWorldHint === void 0 ? {} : { openWorldHint: Boolean(annotationMembers.openWorldHint) },
41
- untrustedContentHint: Boolean(annotationMembers.untrustedContentHint)
42
- } }
43
- };
44
- }
45
- function isJsonObjectRecord(value) {
46
- if (!isPlainObject(value)) return false;
47
- const prototype = Object.getPrototypeOf(value);
48
- return prototype === Object.prototype || prototype === null;
49
- }
50
- function isJsonValue(value, seen = /* @__PURE__ */ new WeakSet()) {
51
- if (value === null || typeof value === "string" || typeof value === "boolean") return true;
52
- if (typeof value === "number") return Number.isFinite(value);
53
- if (typeof value !== "object") return false;
54
- if (seen.has(value)) return false;
55
- seen.add(value);
56
- try {
57
- return (Array.isArray(value) ? value : isJsonObjectRecord(value) ? Object.values(value) : null)?.every((entry) => isJsonValue(entry, seen)) ?? false;
58
- } catch {
59
- return false;
60
- } finally {
61
- seen.delete(value);
62
- }
63
- }
64
- function toJsonValue(value) {
65
- return isJsonValue(value) ? value : void 0;
66
- }
67
- function hasCallToolResultShape(value) {
68
- return isPlainObject(value) && Array.isArray(value.content);
69
- }
70
- function serializeTextContent(value) {
71
- if (typeof value === "string") return value;
72
- try {
73
- return JSON.stringify(value) ?? String(value);
74
- } catch {
75
- return String(value);
76
- }
77
- }
78
- function normalizeToolResponse(value) {
79
- if (hasCallToolResultShape(value)) return value;
80
- const structuredContent = toJsonValue(value);
81
- return {
82
- content: [{
83
- type: "text",
84
- text: serializeTextContent(value)
85
- }],
86
- ...structuredContent === void 0 ? {} : { structuredContent },
87
- isError: false
88
- };
89
- }
90
- function createUnknownError(message) {
91
- return new DOMException(message, "UnknownError");
92
- }
93
- function createToolInvocationFailedError(error) {
94
- return createUnknownError(error instanceof Error ? `${TOOL_INVOCATION_FAILED_MESSAGE}: ${error.message}` : TOOL_INVOCATION_FAILED_MESSAGE);
95
- }
96
- function createInvalidStateError(message) {
97
- return new DOMException(message, "InvalidStateError");
98
- }
99
- function validateWebMcpToolDescriptor(tool) {
100
- if (tool.name === "") throw createInvalidStateError("Tool \"name\" must be a non-empty string");
101
- if (typeof tool.name !== "string" || !VALID_TOOL_NAME_RE.test(tool.name)) throw createInvalidStateError("Tool \"name\" must be 1–128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period");
102
- if (typeof tool.description !== "string" || tool.description.length === 0) throw createInvalidStateError("Tool \"description\" must be a non-empty string");
103
- if (typeof tool.execute !== "function") throw new TypeError("Tool \"execute\" must be a function");
104
- }
105
- function toWebMcpAnnotations(annotations) {
106
- return {
107
- readOnlyHint: annotations.readOnlyHint ?? false,
108
- untrustedContentHint: annotations.untrustedContentHint ?? false
109
- };
110
- }
111
- function parseChromeToolInput(input) {
112
- try {
113
- const value = JSON.parse(input);
114
- if (Array.isArray(value) || isPlainObject(value)) return value;
115
- } catch {}
116
- throw createUnknownError(FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE);
117
- }
118
- function serializeChromeToolResult(value) {
119
- if (typeof value === "object" && value !== null || typeof value === "function") try {
120
- const serialized = JSON.stringify(value);
121
- if (serialized) return serialized;
122
- } catch {}
123
- return String(value) || "Operation succeeded";
124
- }
125
- function withAbortSignal(operation, signal, getAbortReason = () => signal?.reason) {
126
- if (!signal) return operation;
127
- if (signal.aborted) return Promise.reject(getAbortReason());
128
- return new Promise((resolve, reject) => {
129
- const onAbort = () => {
130
- cleanup();
131
- reject(getAbortReason());
132
- };
133
- const cleanup = () => signal.removeEventListener("abort", onAbort);
134
- signal.addEventListener("abort", onAbort, { once: true });
135
- operation.then((value) => {
136
- cleanup();
137
- resolve(value);
138
- }, (error) => {
139
- cleanup();
140
- reject(error);
141
- });
142
- });
143
- }
144
- function isPotentiallyTrustworthyOrigin(url) {
145
- const originUrl = url.origin === "null" ? url : new URL(url.origin);
146
- const protocol = originUrl.protocol;
147
- if ([
148
- "https:",
149
- "wss:",
150
- "file:",
151
- "chrome-extension:",
152
- "moz-extension:"
153
- ].includes(protocol)) return true;
154
- const hostname = originUrl.hostname.toLowerCase();
155
- const ipv4 = hostname.split(".");
156
- const isLoopbackIpv4 = ipv4.length === 4 && ipv4.every((part) => /^\d{1,3}$/u.test(part) && Number(part) <= 255) && Number(ipv4[0]) === 127;
157
- return hostname === "::1" || hostname === "[::1]" || hostname === "localhost" || hostname === "localhost." || hostname.endsWith(".localhost") || hostname.endsWith(".localhost.") || isLoopbackIpv4;
158
- }
159
- function validatePotentiallyTrustworthyOrigins(origins) {
160
- for (const origin of origins ?? []) {
161
- let parsed;
162
- try {
163
- parsed = new URL(origin);
164
- } catch {
165
- throw new DOMException(`Invalid or untrustworthy origin: ${String(origin)}`, "SecurityError");
166
- }
167
- if (!isPotentiallyTrustworthyOrigin(parsed)) throw new DOMException(`Invalid or untrustworthy origin: ${origin}`, "SecurityError");
168
- }
169
- }
170
- function validateWebMcpAccess(ownerDocument) {
171
- validateOriginAgentCluster();
172
- if (!ownerDocument) return;
173
- const DOMExceptionConstructor = ownerDocument.defaultView?.DOMException ?? DOMException;
174
- let fullyActive = false;
175
- try {
176
- const ownerWindow = ownerDocument.defaultView;
177
- fullyActive = Boolean(ownerWindow && ownerWindow.document === ownerDocument);
178
- } catch {}
179
- if (!fullyActive) throw new DOMExceptionConstructor("The associated document is not fully active", "InvalidStateError");
180
- const policy = Reflect.get(ownerDocument, "permissionsPolicy") ?? Reflect.get(ownerDocument, "featurePolicy");
181
- if (policy && typeof policy === "object") {
182
- const features = Reflect.get(policy, "features");
183
- const allowsFeature = Reflect.get(policy, "allowsFeature");
184
- if (typeof features === "function" && typeof allowsFeature === "function") {
185
- const supported = Reflect.apply(features, policy, []);
186
- if (Array.isArray(supported) && supported.includes("tools")) {
187
- if (Reflect.apply(allowsFeature, policy, ["tools"]) === true) return;
188
- throw new DOMExceptionConstructor("WebMCP is disabled by Permissions Policy", "NotAllowedError");
189
- }
190
- }
191
- }
192
- const ownerWindow = ownerDocument.defaultView;
193
- if (!ownerWindow || ownerWindow.parent === ownerWindow) return;
194
- try {
195
- ownerWindow.parent.document;
196
- return;
197
- } catch {}
198
- throw new DOMExceptionConstructor("WebMCP in cross-origin frames requires native Permissions Policy support", "NotAllowedError");
199
- }
200
- function validateOriginAgentCluster() {
201
- if (globalThis.originAgentCluster === false && globalThis.location?.protocol !== "file:") throw new DOMException("", "SecurityError");
202
- }
203
- function validateExecutableOrigin(origin) {
204
- try {
205
- if (new URL(String(origin)).origin !== "null") return;
206
- } catch {}
207
- throw new DOMException(`Unsupported tool origin: ${String(origin)}`, "NotSupportedError");
208
- }
209
- function getStandardProps(value) {
210
- if (!isPlainObject(value)) return null;
211
- const standard = value["~standard"];
212
- if (!isPlainObject(standard)) return null;
213
- return standard;
214
- }
215
- function isStandardInputValidatorSchema(value) {
216
- const standard = getStandardProps(value);
217
- return Boolean(standard && standard.version === 1 && typeof standard.validate === "function");
218
- }
219
- function isStandardInputJsonSchema(value) {
220
- const standard = getStandardProps(value);
221
- if (!standard || standard.version !== 1 || !isPlainObject(standard.jsonSchema)) return false;
222
- return typeof standard.jsonSchema.input === "function";
223
- }
224
- function preserveStandardSchema(inputSchema, standardSchema) {
225
- const normalized = { ...inputSchema };
226
- Object.defineProperty(normalized, "~standard", { value: standardSchema["~standard"] });
227
- return normalized;
228
- }
229
- function convertStandardInputSchema(schema) {
230
- for (const target of STANDARD_JSON_SCHEMA_TARGETS) try {
231
- const serialized = serializeInputSchema(schema["~standard"].jsonSchema.input({ target }));
232
- const parsed = JSON.parse(serialized);
233
- if (!isPlainObject(parsed)) throw new TypeError("inputSchema must serialize to an object");
234
- return parsed;
235
- } catch {}
236
- throw new Error("Failed to convert Standard JSON Schema inputSchema to a JSON Schema object");
237
- }
238
- function normalizeInputSchema(inputSchema) {
239
- if (inputSchema === void 0) return { inputSchema: DEFAULT_INPUT_SCHEMA };
240
- if (isStandardInputJsonSchema(inputSchema)) {
241
- const converted = convertStandardInputSchema(inputSchema);
242
- const registeredInputSchema = serializeInputSchema(converted);
243
- return {
244
- inputSchema: isStandardInputValidatorSchema(inputSchema) ? preserveStandardSchema(converted, inputSchema) : converted,
245
- registeredInputSchema
246
- };
247
- }
248
- if (isStandardInputValidatorSchema(inputSchema)) throw new Error("Standard Schema inputSchema must provide ~standard.jsonSchema.input() for tool metadata");
249
- if (inputSchema === null || typeof inputSchema !== "object" && typeof inputSchema !== "function") throw new TypeError("inputSchema must be an object");
250
- const registeredInputSchema = serializeInputSchema(inputSchema);
251
- const serializedValue = JSON.parse(registeredInputSchema);
252
- const jsonSchema = isPlainObject(serializedValue) ? serializedValue : void 0;
253
- if (!jsonSchema || Object.keys(jsonSchema).length === 0) return {
254
- inputSchema: DEFAULT_INPUT_SCHEMA,
255
- registeredInputSchema
256
- };
257
- return {
258
- inputSchema: jsonSchema.type === void 0 ? {
259
- type: "object",
260
- ...jsonSchema
261
- } : jsonSchema,
262
- registeredInputSchema
263
- };
264
- }
265
- function serializeInputSchema(schema) {
266
- if (schema === null || typeof schema !== "object" && typeof schema !== "function") throw new TypeError("inputSchema must be an object");
267
- const serialized = JSON.stringify(schema);
268
- if (serialized === void 0) throw new TypeError("inputSchema must be JSON-serializable");
269
- return serialized;
270
- }
271
-
272
- //#endregion
273
- export { coerceWebMcpToolDescriptor, createInvalidStateError, createToolInvocationFailedError, createUnknownError, isPlainObject, normalizeInputSchema, normalizeToolResponse, parseChromeToolInput, serializeChromeToolResult, serializeInputSchema, toWebMcpAnnotations, validateExecutableOrigin, validateOriginAgentCluster, validatePotentiallyTrustworthyOrigins, validateWebMcpAccess, validateWebMcpToolDescriptor, withAbortSignal };
274
- //# sourceMappingURL=schema.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema.js","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import type {\n CallToolResult,\n InputSchema,\n JsonValue,\n ToolDescriptor,\n WebMcpToolInput,\n WebMcpToolAnnotations,\n} from '@mcp-b/webmcp-types';\nimport type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\n\ntype StandardInputValidatorSchema = StandardSchemaV1<WebMcpToolInput, WebMcpToolInput>;\ntype StandardInputJsonSchema = StandardJSONSchemaV1<WebMcpToolInput, WebMcpToolInput>;\n\nconst DEFAULT_INPUT_SCHEMA: InputSchema = { type: 'object', properties: {} };\nconst FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE = 'Failed to parse input arguments';\nconst TOOL_INVOCATION_FAILED_MESSAGE =\n 'Tool was executed but the invocation failed. For example, the script function threw an error';\nconst STANDARD_JSON_SCHEMA_TARGETS = ['draft-2020-12', 'draft-07'] as const;\nconst VALID_TOOL_NAME_RE = /^[A-Za-z0-9_.-]{1,128}$/u;\n\nexport type ToolInputSchema = InputSchema | StandardInputJsonSchema;\n\nexport interface NormalizedInputSchema {\n inputSchema: InputSchema;\n registeredInputSchema?: string;\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction toDomString(value: unknown): string {\n if (typeof value === 'symbol') {\n throw new TypeError('Symbol values cannot be converted to a DOMString');\n }\n return String(value);\n}\n\nexport function coerceWebMcpToolDescriptor<TArgs extends WebMcpToolInput>(\n tool: ToolDescriptor<TArgs>\n): ToolDescriptor<TArgs>;\nexport function coerceWebMcpToolDescriptor(\n tool: Record<string, unknown>\n): ToolDescriptor<WebMcpToolInput>;\nexport function coerceWebMcpToolDescriptor(tool: object): ToolDescriptor<WebMcpToolInput> {\n const name: unknown = Reflect.get(tool, 'name');\n const description: unknown = Reflect.get(tool, 'description');\n const title: unknown = Reflect.get(tool, 'title');\n if (name === undefined) {\n throw new TypeError('Tool \"name\" is required');\n }\n if (description === undefined) {\n throw new TypeError('Tool \"description\" is required');\n }\n\n const annotations: unknown = Reflect.get(tool, 'annotations');\n const annotationMembers = isPlainObject(annotations) ? annotations : {};\n const inputSchema: unknown = Reflect.get(tool, 'inputSchema');\n const outputSchema: unknown = Reflect.get(tool, 'outputSchema');\n const execute: unknown = Reflect.get(tool, 'execute');\n\n // Web IDL dictionaries read known members without retaining the caller's object.\n // The cast is load-bearing: `execute` stays unnarrowed until validateWebMcpToolDescriptor().\n return {\n name: toDomString(name),\n ...(title === undefined\n ? {}\n : {\n title: toDomString(title).toWellFormed(),\n }),\n description: toDomString(description),\n ...(inputSchema === undefined ? {} : { inputSchema }),\n ...(outputSchema === undefined ? {} : { outputSchema }),\n execute,\n ...(annotations === undefined\n ? {}\n : {\n annotations: {\n ...(annotationMembers.title === undefined\n ? {}\n : { title: toDomString(annotationMembers.title).toWellFormed() }),\n readOnlyHint: Boolean(annotationMembers.readOnlyHint),\n ...(annotationMembers.destructiveHint === undefined\n ? {}\n : { destructiveHint: Boolean(annotationMembers.destructiveHint) }),\n ...(annotationMembers.idempotentHint === undefined\n ? {}\n : { idempotentHint: Boolean(annotationMembers.idempotentHint) }),\n ...(annotationMembers.openWorldHint === undefined\n ? {}\n : { openWorldHint: Boolean(annotationMembers.openWorldHint) }),\n untrustedContentHint: Boolean(annotationMembers.untrustedContentHint),\n },\n }),\n } as ToolDescriptor<WebMcpToolInput>;\n}\n\nfunction isJsonObjectRecord(value: unknown): value is Record<string, unknown> {\n if (!isPlainObject(value)) {\n return false;\n }\n\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction isJsonValue(value: unknown, seen = new WeakSet<object>()): value is JsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') {\n return true;\n }\n\n if (typeof value === 'number') {\n return Number.isFinite(value);\n }\n\n if (typeof value !== 'object') {\n return false;\n }\n\n if (seen.has(value)) {\n return false;\n }\n\n seen.add(value);\n try {\n const entries = Array.isArray(value)\n ? value\n : isJsonObjectRecord(value)\n ? Object.values(value)\n : null;\n return entries?.every((entry) => isJsonValue(entry, seen)) ?? false;\n } catch {\n return false;\n } finally {\n seen.delete(value);\n }\n}\n\nfunction toJsonValue(value: unknown): JsonValue | undefined {\n return isJsonValue(value) ? value : undefined;\n}\n\nfunction hasCallToolResultShape(\n value: unknown\n): value is Record<string, unknown> & { content: unknown[] } {\n return isPlainObject(value) && Array.isArray(value.content);\n}\n\nfunction serializeTextContent(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\nexport function normalizeToolResponse(value: unknown): CallToolResult {\n // Preserve protocol-evolving content blocks at this compatibility boundary.\n if (hasCallToolResultShape(value)) return value as CallToolResult;\n const structuredContent = toJsonValue(value);\n return {\n content: [{ type: 'text', text: serializeTextContent(value) }],\n ...(structuredContent === undefined ? {} : { structuredContent }),\n isError: false,\n };\n}\n\nexport function createUnknownError(message: string): Error {\n return new DOMException(message, 'UnknownError');\n}\n\nexport function createToolInvocationFailedError(error: unknown): Error {\n return createUnknownError(\n error instanceof Error\n ? `${TOOL_INVOCATION_FAILED_MESSAGE}: ${error.message}`\n : TOOL_INVOCATION_FAILED_MESSAGE\n );\n}\n\nexport function createInvalidStateError(message: string): Error {\n return new DOMException(message, 'InvalidStateError');\n}\n\nexport function validateWebMcpToolDescriptor<TArgs extends WebMcpToolInput>(\n tool: ToolDescriptor<TArgs>\n): void {\n if (tool.name === '') {\n throw createInvalidStateError('Tool \"name\" must be a non-empty string');\n }\n if (typeof tool.name !== 'string' || !VALID_TOOL_NAME_RE.test(tool.name)) {\n throw createInvalidStateError(\n 'Tool \"name\" must be 1–128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period'\n );\n }\n if (typeof tool.description !== 'string' || tool.description.length === 0) {\n throw createInvalidStateError('Tool \"description\" must be a non-empty string');\n }\n if (typeof tool.execute !== 'function') {\n throw new TypeError('Tool \"execute\" must be a function');\n }\n}\n\nexport function toWebMcpAnnotations(annotations: WebMcpToolAnnotations): WebMcpToolAnnotations {\n return {\n readOnlyHint: annotations.readOnlyHint ?? false,\n untrustedContentHint: annotations.untrustedContentHint ?? false,\n };\n}\n\nexport function parseChromeToolInput(input: string): WebMcpToolInput {\n try {\n const value: unknown = JSON.parse(input);\n if (Array.isArray(value) || isPlainObject(value)) return value;\n } catch {\n // Chrome reports invalid JSON and non-object inputs as UnknownError.\n }\n throw createUnknownError(FAILED_TO_PARSE_INPUT_ARGUMENTS_MESSAGE);\n}\n\nexport function serializeChromeToolResult(value: unknown): string {\n if ((typeof value === 'object' && value !== null) || typeof value === 'function') {\n try {\n const serialized = JSON.stringify(value);\n if (serialized) return serialized;\n } catch {\n // Chromium falls back to string conversion when JSON serialization fails.\n }\n }\n return String(value) || 'Operation succeeded';\n}\n\nexport function withAbortSignal<T>(\n operation: Promise<T>,\n signal?: AbortSignal,\n getAbortReason: () => unknown = () => signal?.reason\n): Promise<T> {\n if (!signal) return operation;\n if (signal.aborted) return Promise.reject(getAbortReason());\n return new Promise<T>((resolve, reject) => {\n const onAbort = () => {\n cleanup();\n reject(getAbortReason());\n };\n const cleanup = () => signal.removeEventListener('abort', onAbort);\n\n signal.addEventListener('abort', onAbort, { once: true });\n operation.then(\n (value) => {\n cleanup();\n resolve(value);\n },\n (error: unknown) => {\n cleanup();\n reject(error);\n }\n );\n });\n}\n\nfunction isPotentiallyTrustworthyOrigin(url: URL): boolean {\n const originUrl = url.origin === 'null' ? url : new URL(url.origin);\n const protocol = originUrl.protocol;\n if (['https:', 'wss:', 'file:', 'chrome-extension:', 'moz-extension:'].includes(protocol)) {\n return true;\n }\n\n const hostname = originUrl.hostname.toLowerCase();\n const ipv4 = hostname.split('.');\n const isLoopbackIpv4 =\n ipv4.length === 4 &&\n ipv4.every((part) => /^\\d{1,3}$/u.test(part) && Number(part) <= 255) &&\n Number(ipv4[0]) === 127;\n return (\n hostname === '::1' ||\n hostname === '[::1]' ||\n hostname === 'localhost' ||\n hostname === 'localhost.' ||\n hostname.endsWith('.localhost') ||\n hostname.endsWith('.localhost.') ||\n isLoopbackIpv4\n );\n}\n\nexport function validatePotentiallyTrustworthyOrigins(\n origins: readonly string[] | undefined\n): void {\n for (const origin of origins ?? []) {\n let parsed: URL;\n try {\n parsed = new URL(origin);\n } catch {\n throw new DOMException(`Invalid or untrustworthy origin: ${String(origin)}`, 'SecurityError');\n }\n if (!isPotentiallyTrustworthyOrigin(parsed)) {\n throw new DOMException(`Invalid or untrustworthy origin: ${origin}`, 'SecurityError');\n }\n }\n}\n\nexport function validateWebMcpAccess(ownerDocument: Document | null): void {\n validateOriginAgentCluster();\n if (!ownerDocument) return;\n\n const DOMExceptionConstructor = ownerDocument.defaultView?.DOMException ?? DOMException;\n let fullyActive = false;\n try {\n const ownerWindow = ownerDocument.defaultView;\n fullyActive = Boolean(ownerWindow && ownerWindow.document === ownerDocument);\n } catch {\n // A navigated cross-origin WindowProxy is not the document's active window.\n }\n if (!fullyActive) {\n throw new DOMExceptionConstructor(\n 'The associated document is not fully active',\n 'InvalidStateError'\n );\n }\n\n const policy: unknown =\n Reflect.get(ownerDocument, 'permissionsPolicy') ?? Reflect.get(ownerDocument, 'featurePolicy');\n if (policy && typeof policy === 'object') {\n const features = Reflect.get(policy, 'features');\n const allowsFeature = Reflect.get(policy, 'allowsFeature');\n if (typeof features === 'function' && typeof allowsFeature === 'function') {\n const supported: unknown = Reflect.apply(features, policy, []);\n if (Array.isArray(supported) && supported.includes('tools')) {\n if (Reflect.apply(allowsFeature, policy, ['tools']) === true) return;\n throw new DOMExceptionConstructor(\n 'WebMCP is disabled by Permissions Policy',\n 'NotAllowedError'\n );\n }\n }\n }\n\n const ownerWindow = ownerDocument.defaultView;\n if (!ownerWindow || ownerWindow.parent === ownerWindow) return;\n try {\n void ownerWindow.parent.document;\n return;\n } catch {\n // Without native policy support, cross-origin frames fail closed.\n }\n throw new DOMExceptionConstructor(\n 'WebMCP in cross-origin frames requires native Permissions Policy support',\n 'NotAllowedError'\n );\n}\n\nexport function validateOriginAgentCluster(): void {\n if (globalThis.originAgentCluster === false && globalThis.location?.protocol !== 'file:') {\n throw new DOMException('', 'SecurityError');\n }\n}\n\nexport function validateExecutableOrigin(origin: unknown): void {\n try {\n if (new URL(String(origin)).origin !== 'null') return;\n } catch {\n // Invalid and opaque origins share the WebMCP NotSupportedError result.\n }\n throw new DOMException(`Unsupported tool origin: ${String(origin)}`, 'NotSupportedError');\n}\n\nfunction getStandardProps(value: unknown): Record<string, unknown> | null {\n if (!isPlainObject(value)) {\n return null;\n }\n\n const standard = value['~standard'];\n if (!isPlainObject(standard)) {\n return null;\n }\n\n return standard;\n}\n\nfunction isStandardInputValidatorSchema(value: unknown): value is StandardInputValidatorSchema {\n const standard = getStandardProps(value);\n return Boolean(standard && standard.version === 1 && typeof standard.validate === 'function');\n}\n\nfunction isStandardInputJsonSchema(value: unknown): value is StandardInputJsonSchema {\n const standard = getStandardProps(value);\n if (!standard || standard.version !== 1 || !isPlainObject(standard.jsonSchema)) {\n return false;\n }\n\n return typeof standard.jsonSchema.input === 'function';\n}\n\nfunction preserveStandardSchema(\n inputSchema: InputSchema,\n standardSchema: StandardInputValidatorSchema\n): InputSchema {\n const normalized = { ...inputSchema };\n Object.defineProperty(normalized, '~standard', {\n value: standardSchema['~standard'],\n });\n return normalized;\n}\n\nfunction convertStandardInputSchema(schema: StandardInputJsonSchema): InputSchema {\n for (const target of STANDARD_JSON_SCHEMA_TARGETS) {\n try {\n const converted = schema['~standard'].jsonSchema.input({ target });\n const serialized = serializeInputSchema(converted);\n const parsed: unknown = JSON.parse(serialized);\n if (!isPlainObject(parsed)) throw new TypeError('inputSchema must serialize to an object');\n return parsed;\n } catch {}\n }\n\n throw new Error('Failed to convert Standard JSON Schema inputSchema to a JSON Schema object');\n}\n\nexport function normalizeInputSchema(\n inputSchema: ToolInputSchema | undefined\n): NormalizedInputSchema {\n if (inputSchema === undefined) {\n return { inputSchema: DEFAULT_INPUT_SCHEMA };\n }\n\n if (isStandardInputJsonSchema(inputSchema)) {\n const converted = convertStandardInputSchema(inputSchema);\n const registeredInputSchema = serializeInputSchema(converted);\n return {\n inputSchema: isStandardInputValidatorSchema(inputSchema)\n ? preserveStandardSchema(converted, inputSchema)\n : converted,\n registeredInputSchema,\n };\n }\n\n if (isStandardInputValidatorSchema(inputSchema)) {\n throw new Error(\n 'Standard Schema inputSchema must provide ~standard.jsonSchema.input() for tool metadata'\n );\n }\n\n if (\n inputSchema === null ||\n (typeof inputSchema !== 'object' && typeof inputSchema !== 'function')\n ) {\n throw new TypeError('inputSchema must be an object');\n }\n const registeredInputSchema = serializeInputSchema(inputSchema);\n const serializedValue: unknown = JSON.parse(registeredInputSchema);\n const jsonSchema = isPlainObject(serializedValue) ? serializedValue : undefined;\n\n // Empty {} is valid JSON Schema but lacks type:\"object\" required by MCP.\n if (!jsonSchema || Object.keys(jsonSchema).length === 0) {\n return {\n inputSchema: DEFAULT_INPUT_SCHEMA,\n registeredInputSchema,\n };\n }\n\n const normalizedSchema: InputSchema =\n jsonSchema.type === undefined ? { type: 'object', ...jsonSchema } : jsonSchema;\n return {\n inputSchema: normalizedSchema,\n registeredInputSchema,\n };\n}\n\nexport function serializeInputSchema(schema: unknown): string {\n if (schema === null || (typeof schema !== 'object' && typeof schema !== 'function')) {\n throw new TypeError('inputSchema must be an object');\n }\n const serialized = JSON.stringify(schema);\n if (serialized === undefined) {\n throw new TypeError('inputSchema must be JSON-serializable');\n }\n return serialized;\n}\n"],"mappings":"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"}