@mcp-b/webmcp-polyfill 4.0.0 → 5.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/README.md +123 -193
- package/dist/index.d.ts +7 -23
- package/dist/index.iife.js +1 -2
- package/dist/index.js +940 -373
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +22 -12
- package/dist/schema.js +208 -101
- package/dist/schema.js.map +1 -1
- package/package.json +10 -13
- package/dist/index.d.ts.map +0 -1
- package/dist/schema.d.ts.map +0 -1
package/dist/schema.js
CHANGED
|
@@ -1,14 +1,47 @@
|
|
|
1
|
-
import { Validator } from "@cfworker/json-schema";
|
|
2
|
-
|
|
3
1
|
//#region src/schema.ts
|
|
4
2
|
const DEFAULT_INPUT_SCHEMA = {
|
|
5
3
|
type: "object",
|
|
6
4
|
properties: {}
|
|
7
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
8
|
const STANDARD_JSON_SCHEMA_TARGETS = ["draft-2020-12", "draft-07"];
|
|
9
|
+
const VALID_TOOL_NAME_RE = /^[A-Za-z0-9_.-]{1,128}$/u;
|
|
9
10
|
function isPlainObject(value) {
|
|
10
11
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11
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
|
+
}
|
|
12
45
|
function isJsonObjectRecord(value) {
|
|
13
46
|
if (!isPlainObject(value)) return false;
|
|
14
47
|
const prototype = Object.getPrototypeOf(value);
|
|
@@ -31,6 +64,148 @@ function isJsonValue(value, seen = /* @__PURE__ */ new WeakSet()) {
|
|
|
31
64
|
function toJsonValue(value) {
|
|
32
65
|
return isJsonValue(value) ? value : void 0;
|
|
33
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
|
+
}
|
|
34
209
|
function getStandardProps(value) {
|
|
35
210
|
if (!isPlainObject(value)) return null;
|
|
36
211
|
const standard = value["~standard"];
|
|
@@ -46,122 +221,54 @@ function isStandardInputJsonSchema(value) {
|
|
|
46
221
|
if (!standard || standard.version !== 1 || !isPlainObject(standard.jsonSchema)) return false;
|
|
47
222
|
return typeof standard.jsonSchema.input === "function";
|
|
48
223
|
}
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
validate(value) {
|
|
54
|
-
if (!isPlainObject(value)) return { issues: [{ message: "expected object arguments" }] };
|
|
55
|
-
const issue = validateValueWithSchema(value, schema);
|
|
56
|
-
if (issue) return { issues: [issue] };
|
|
57
|
-
return { value };
|
|
58
|
-
}
|
|
59
|
-
} };
|
|
224
|
+
function preserveStandardSchema(inputSchema, standardSchema) {
|
|
225
|
+
const normalized = { ...inputSchema };
|
|
226
|
+
Object.defineProperty(normalized, "~standard", { value: standardSchema["~standard"] });
|
|
227
|
+
return normalized;
|
|
60
228
|
}
|
|
61
229
|
function convertStandardInputSchema(schema) {
|
|
62
|
-
const failures = [];
|
|
63
230
|
for (const target of STANDARD_JSON_SCHEMA_TARGETS) try {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
target,
|
|
70
|
-
error
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
console.warn("[WebMCPPolyfill] Standard JSON Schema conversion failed:", failures);
|
|
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 {}
|
|
74
236
|
throw new Error("Failed to convert Standard JSON Schema inputSchema to a JSON Schema object");
|
|
75
237
|
}
|
|
76
238
|
function normalizeInputSchema(inputSchema) {
|
|
77
|
-
if (inputSchema === void 0) {
|
|
78
|
-
const normalized = DEFAULT_INPUT_SCHEMA;
|
|
79
|
-
return {
|
|
80
|
-
inputSchema: normalized,
|
|
81
|
-
standardValidator: createStandardValidatorFromJsonSchema(normalized)
|
|
82
|
-
};
|
|
83
|
-
}
|
|
239
|
+
if (inputSchema === void 0) return { inputSchema: DEFAULT_INPUT_SCHEMA };
|
|
84
240
|
if (isStandardInputJsonSchema(inputSchema)) {
|
|
85
241
|
const converted = convertStandardInputSchema(inputSchema);
|
|
242
|
+
const registeredInputSchema = serializeInputSchema(converted);
|
|
86
243
|
return {
|
|
87
|
-
inputSchema: converted,
|
|
88
|
-
|
|
244
|
+
inputSchema: isStandardInputValidatorSchema(inputSchema) ? preserveStandardSchema(converted, inputSchema) : converted,
|
|
245
|
+
registeredInputSchema
|
|
89
246
|
};
|
|
90
247
|
}
|
|
91
|
-
if (isStandardInputValidatorSchema(inputSchema))
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (Object.keys(
|
|
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 {
|
|
97
254
|
inputSchema: DEFAULT_INPUT_SCHEMA,
|
|
98
|
-
|
|
255
|
+
registeredInputSchema
|
|
99
256
|
};
|
|
100
|
-
const normalizedSchema = inputSchema.type === void 0 ? {
|
|
101
|
-
type: "object",
|
|
102
|
-
...inputSchema
|
|
103
|
-
} : inputSchema;
|
|
104
257
|
return {
|
|
105
|
-
inputSchema:
|
|
106
|
-
|
|
258
|
+
inputSchema: jsonSchema.type === void 0 ? {
|
|
259
|
+
type: "object",
|
|
260
|
+
...jsonSchema
|
|
261
|
+
} : jsonSchema,
|
|
262
|
+
registeredInputSchema
|
|
107
263
|
};
|
|
108
264
|
}
|
|
109
|
-
function
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const typeValue = node.type;
|
|
115
|
-
if (typeValue !== void 0 && typeof typeValue !== "string" && !(Array.isArray(typeValue) && typeValue.every((entry) => typeof entry === "string" && entry.length > 0))) throw new Error(`Invalid JSON Schema at ${path}: "type" must be a string or string[]`);
|
|
116
|
-
const requiredValue = node.required;
|
|
117
|
-
if (requiredValue !== void 0 && !(Array.isArray(requiredValue) && requiredValue.every((entry) => typeof entry === "string"))) throw new Error(`Invalid JSON Schema at ${path}: "required" must be an array of strings`);
|
|
118
|
-
const propertiesValue = node.properties;
|
|
119
|
-
if (propertiesValue !== void 0) {
|
|
120
|
-
if (!isPlainObject(propertiesValue)) throw new Error(`Invalid JSON Schema at ${path}: "properties" must be an object`);
|
|
121
|
-
for (const [key, value] of Object.entries(propertiesValue)) {
|
|
122
|
-
if (!isPlainObject(value)) throw new Error(`Invalid JSON Schema at ${path}.properties.${key}: expected object schema`);
|
|
123
|
-
validateJsonSchemaNode(value, `${path}.properties.${key}`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
const itemsValue = node.items;
|
|
127
|
-
if (itemsValue !== void 0) if (Array.isArray(itemsValue)) for (const [index, value] of itemsValue.entries()) {
|
|
128
|
-
if (!isPlainObject(value)) throw new Error(`Invalid JSON Schema at ${path}.items[${index}]: expected object schema`);
|
|
129
|
-
validateJsonSchemaNode(value, `${path}.items[${index}]`);
|
|
130
|
-
}
|
|
131
|
-
else if (isPlainObject(itemsValue)) validateJsonSchemaNode(itemsValue, `${path}.items`);
|
|
132
|
-
else throw new Error(`Invalid JSON Schema at ${path}: "items" must be an object or object[]`);
|
|
133
|
-
for (const keyword of [
|
|
134
|
-
"allOf",
|
|
135
|
-
"anyOf",
|
|
136
|
-
"oneOf"
|
|
137
|
-
]) {
|
|
138
|
-
const value = node[keyword];
|
|
139
|
-
if (value === void 0) continue;
|
|
140
|
-
if (!Array.isArray(value)) throw new Error(`Invalid JSON Schema at ${path}: "${keyword}" must be an array`);
|
|
141
|
-
for (const [index, entry] of value.entries()) {
|
|
142
|
-
if (!isPlainObject(entry)) throw new Error(`Invalid JSON Schema at ${path}.${keyword}[${index}]: expected object schema`);
|
|
143
|
-
validateJsonSchemaNode(entry, `${path}.${keyword}[${index}]`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
const notValue = node.not;
|
|
147
|
-
if (notValue !== void 0) {
|
|
148
|
-
if (!isPlainObject(notValue)) throw new Error(`Invalid JSON Schema at ${path}: "not" must be an object schema`);
|
|
149
|
-
validateJsonSchemaNode(notValue, `${path}.not`);
|
|
150
|
-
}
|
|
151
|
-
try {
|
|
152
|
-
JSON.stringify(node);
|
|
153
|
-
} catch {
|
|
154
|
-
throw new Error(`Invalid JSON Schema at ${path}: schema must be JSON-serializable`);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
function validateValueWithSchema(value, schema) {
|
|
158
|
-
const result = new Validator(schema, "2020-12", true).validate(value);
|
|
159
|
-
if (result.valid) return null;
|
|
160
|
-
const error = result.errors[result.errors.length - 1];
|
|
161
|
-
if (!error) return { message: "Input validation failed" };
|
|
162
|
-
return { message: error.error };
|
|
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;
|
|
163
270
|
}
|
|
164
271
|
|
|
165
272
|
//#endregion
|
|
166
|
-
export { isPlainObject, normalizeInputSchema,
|
|
273
|
+
export { coerceWebMcpToolDescriptor, createInvalidStateError, createToolInvocationFailedError, createUnknownError, isPlainObject, normalizeInputSchema, normalizeToolResponse, parseChromeToolInput, serializeChromeToolResult, serializeInputSchema, toWebMcpAnnotations, validateExecutableOrigin, validateOriginAgentCluster, validatePotentiallyTrustworthyOrigins, validateWebMcpAccess, validateWebMcpToolDescriptor, withAbortSignal };
|
|
167
274
|
//# sourceMappingURL=schema.js.map
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","names":[],"sources":["../src/schema.ts"],"sourcesContent":["import { type Schema, Validator } from '@cfworker/json-schema';\nimport type { InputSchema, JsonSchemaForInference, JsonValue } from '@mcp-b/webmcp-types';\nimport type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';\nexport type { StandardJSONSchemaV1 } from '@standard-schema/spec';\n\nconst DEFAULT_INPUT_SCHEMA: InputSchema = { type: 'object', properties: {} };\nconst STANDARD_JSON_SCHEMA_TARGETS = ['draft-2020-12', 'draft-07'] as const;\n\nexport type StandardInputValidatorSchema = StandardSchemaV1<\n Record<string, unknown>,\n Record<string, unknown>\n>;\nexport type StandardInputJsonSchema = StandardJSONSchemaV1<\n Record<string, unknown>,\n Record<string, unknown>\n>;\nexport type ToolInputSchema = InputSchema | StandardInputValidatorSchema | StandardInputJsonSchema;\nexport type ToolOutputSchema = InputSchema | StandardInputJsonSchema;\n\nexport type StandardValidationResult = Awaited<\n ReturnType<StandardInputValidatorSchema['~standard']['validate']>\n>;\nexport type StandardValidationIssue = NonNullable<StandardValidationResult['issues']>[number];\n\nexport interface NormalizedInputSchema {\n inputSchema: InputSchema;\n standardValidator: StandardInputValidatorSchema;\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 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\nexport function toJsonValue(value: unknown): JsonValue | undefined {\n return isJsonValue(value) ? value : undefined;\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 createStandardValidatorFromJsonSchema(schema: InputSchema): StandardInputValidatorSchema {\n return {\n '~standard': {\n version: 1,\n vendor: '@mcp-b/webmcp-polyfill-json-schema',\n validate(value: unknown): StandardValidationResult {\n if (!isPlainObject(value)) {\n return {\n issues: [{ message: 'expected object arguments' }],\n };\n }\n\n const issue = validateValueWithSchema(value, schema);\n if (issue) {\n return {\n issues: [issue],\n };\n }\n\n return {\n value,\n };\n },\n },\n };\n}\n\nfunction convertStandardInputSchema(schema: StandardInputJsonSchema): InputSchema {\n const failures: Array<{ error: unknown; target: (typeof STANDARD_JSON_SCHEMA_TARGETS)[number] }> =\n [];\n\n for (const target of STANDARD_JSON_SCHEMA_TARGETS) {\n try {\n const converted = schema['~standard'].jsonSchema.input({ target });\n validateInputSchema(converted);\n return converted;\n } catch (error) {\n failures.push({ target, error });\n }\n }\n\n console.warn('[WebMCPPolyfill] Standard JSON Schema conversion failed:', failures);\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 const normalized = DEFAULT_INPUT_SCHEMA;\n return {\n inputSchema: normalized,\n standardValidator: createStandardValidatorFromJsonSchema(normalized),\n };\n }\n\n if (isStandardInputJsonSchema(inputSchema)) {\n // Prefer JSON conversion for parity across JSON and Standard Schema inputs.\n const converted = convertStandardInputSchema(inputSchema);\n return {\n inputSchema: converted,\n standardValidator: createStandardValidatorFromJsonSchema(converted),\n };\n }\n\n if (isStandardInputValidatorSchema(inputSchema)) {\n return {\n inputSchema: DEFAULT_INPUT_SCHEMA,\n standardValidator: inputSchema,\n };\n }\n\n validateInputSchema(inputSchema);\n\n // Empty {} is valid JSON Schema but lacks type:\"object\" required by MCP.\n if (Object.keys(inputSchema as Record<string, unknown>).length === 0) {\n return {\n inputSchema: DEFAULT_INPUT_SCHEMA,\n standardValidator: createStandardValidatorFromJsonSchema(DEFAULT_INPUT_SCHEMA),\n };\n }\n\n const normalizedSchema =\n inputSchema.type === undefined\n ? ({ type: 'object', ...inputSchema } as InputSchema)\n : inputSchema;\n return {\n inputSchema: normalizedSchema,\n standardValidator: createStandardValidatorFromJsonSchema(normalizedSchema),\n };\n}\n\nfunction validateInputSchema(schema: unknown): asserts schema is InputSchema {\n if (!isPlainObject(schema)) {\n throw new Error('inputSchema must be a JSON Schema object');\n }\n\n validateJsonSchemaNode(schema, '$');\n}\n\nfunction validateJsonSchemaNode(node: Record<string, unknown>, path: string): void {\n const typeValue = node.type;\n if (\n typeValue !== undefined &&\n typeof typeValue !== 'string' &&\n !(\n Array.isArray(typeValue) &&\n typeValue.every((entry) => typeof entry === 'string' && entry.length > 0)\n )\n ) {\n throw new Error(`Invalid JSON Schema at ${path}: \"type\" must be a string or string[]`);\n }\n\n const requiredValue = node.required;\n if (\n requiredValue !== undefined &&\n !(Array.isArray(requiredValue) && requiredValue.every((entry) => typeof entry === 'string'))\n ) {\n throw new Error(`Invalid JSON Schema at ${path}: \"required\" must be an array of strings`);\n }\n\n const propertiesValue = node.properties;\n if (propertiesValue !== undefined) {\n if (!isPlainObject(propertiesValue)) {\n throw new Error(`Invalid JSON Schema at ${path}: \"properties\" must be an object`);\n }\n\n for (const [key, value] of Object.entries(propertiesValue)) {\n if (!isPlainObject(value)) {\n throw new Error(`Invalid JSON Schema at ${path}.properties.${key}: expected object schema`);\n }\n validateJsonSchemaNode(value, `${path}.properties.${key}`);\n }\n }\n\n const itemsValue = node.items;\n if (itemsValue !== undefined) {\n if (Array.isArray(itemsValue)) {\n for (const [index, value] of itemsValue.entries()) {\n if (!isPlainObject(value)) {\n throw new Error(`Invalid JSON Schema at ${path}.items[${index}]: expected object schema`);\n }\n validateJsonSchemaNode(value, `${path}.items[${index}]`);\n }\n } else if (isPlainObject(itemsValue)) {\n validateJsonSchemaNode(itemsValue, `${path}.items`);\n } else {\n throw new Error(`Invalid JSON Schema at ${path}: \"items\" must be an object or object[]`);\n }\n }\n\n for (const keyword of ['allOf', 'anyOf', 'oneOf'] as const) {\n const value = node[keyword];\n if (value === undefined) {\n continue;\n }\n\n if (!Array.isArray(value)) {\n throw new Error(`Invalid JSON Schema at ${path}: \"${keyword}\" must be an array`);\n }\n\n for (const [index, entry] of value.entries()) {\n if (!isPlainObject(entry)) {\n throw new Error(\n `Invalid JSON Schema at ${path}.${keyword}[${index}]: expected object schema`\n );\n }\n validateJsonSchemaNode(entry, `${path}.${keyword}[${index}]`);\n }\n }\n\n const notValue = node.not;\n if (notValue !== undefined) {\n if (!isPlainObject(notValue)) {\n throw new Error(`Invalid JSON Schema at ${path}: \"not\" must be an object schema`);\n }\n validateJsonSchemaNode(notValue, `${path}.not`);\n }\n\n try {\n JSON.stringify(node);\n } catch {\n throw new Error(`Invalid JSON Schema at ${path}: schema must be JSON-serializable`);\n }\n}\n\nexport function validateValueWithSchema(\n value: unknown,\n schema: InputSchema | JsonSchemaForInference\n): StandardValidationIssue | null {\n const validator = new Validator(schema as Schema, '2020-12', true);\n const result = validator.validate(value);\n\n if (result.valid) {\n return null;\n }\n\n // Use the deepest (last) error for the most specific message.\n const error = result.errors[result.errors.length - 1];\n if (!error) {\n return { message: 'Input validation failed' };\n }\n\n return { message: error.error };\n}\n"],"mappings":"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"}
|
|
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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-b/webmcp-polyfill",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Strict WebMCP core runtime polyfill for document.modelContext (with deprecated navigator.modelContext alias)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"browser",
|
|
@@ -24,10 +24,12 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"type": "module",
|
|
27
|
-
"sideEffects":
|
|
27
|
+
"sideEffects": [
|
|
28
|
+
"./dist/index.iife.js"
|
|
29
|
+
],
|
|
28
30
|
"main": "./dist/index.js",
|
|
29
31
|
"module": "./dist/index.js",
|
|
30
|
-
"browser": "./dist/index.
|
|
32
|
+
"browser": "./dist/index.js",
|
|
31
33
|
"types": "./dist/index.d.ts",
|
|
32
34
|
"exports": {
|
|
33
35
|
".": {
|
|
@@ -50,23 +52,20 @@
|
|
|
50
52
|
"registry": "https://registry.npmjs.org/"
|
|
51
53
|
},
|
|
52
54
|
"dependencies": {
|
|
53
|
-
"@cfworker/json-schema": "^4.1.1",
|
|
54
55
|
"@standard-schema/spec": "^1.1.0",
|
|
55
|
-
"@mcp-b/webmcp-types": "
|
|
56
|
+
"@mcp-b/webmcp-types": "5.0.0"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
58
|
-
"@vitest/coverage-v8": "^4.1.7",
|
|
59
|
-
"happy-dom": "^20.8.9",
|
|
60
59
|
"playwright": "^1.60.0",
|
|
61
60
|
"typescript": "^5.8.3",
|
|
62
61
|
"vite-plus": "^0.1.22",
|
|
63
62
|
"vitest": "npm:@voidzero-dev/vite-plus-test@latest"
|
|
64
63
|
},
|
|
65
64
|
"engines": {
|
|
66
|
-
"node": ">=
|
|
65
|
+
"node": ">=20"
|
|
67
66
|
},
|
|
68
67
|
"scripts": {
|
|
69
|
-
"build": "
|
|
68
|
+
"build": "vp pack",
|
|
70
69
|
"check": "vp check --fix",
|
|
71
70
|
"clean": "rm -rf dist",
|
|
72
71
|
"format": "vp fmt --write",
|
|
@@ -74,9 +73,7 @@
|
|
|
74
73
|
"publish:dry": "pnpm publish --access public --dry-run",
|
|
75
74
|
"publish:npm": "pnpm publish --access public",
|
|
76
75
|
"test": "vp test run",
|
|
77
|
-
"test:
|
|
78
|
-
"
|
|
79
|
-
"test:conformance": "vp test run --config vitest.conformance.config.ts --browser.headless",
|
|
80
|
-
"typecheck": "pnpm --filter @mcp-b/webmcp-types build && tsc --noEmit && vp test run --typecheck --silent"
|
|
76
|
+
"test:conformance": "vp test run conformance/polyfill-runtime.e2e.test.ts --browser.headless",
|
|
77
|
+
"typecheck": "tsc --noEmit && vp test run --typecheck --silent"
|
|
81
78
|
}
|
|
82
79
|
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;UAkFiB,yBAAA;EAAA;;;;;EAMf,cAAA;EAcA;;;AA0mBF;;;;EA/mBE,kBAAA;EAmsBc;;;EA9rBd,+BAAA;AAAA;AAAA,iBA0mBc,wBAAA,CAAyB,OAAA,GAAU,yBAAA;AAAA,iBAoFnC,qBAAA,CAAA;AAAA,QA+CR,MAAA;EAAA,UACI,MAAA;IACR,uBAAA,GAA0B,yBAAA;EAAA;AAAA"}
|
package/dist/schema.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","names":[],"sources":["../src/schema.ts"],"mappings":";;;;KAQY,4BAAA,GAA+B,gBAAA,CACzC,MAAA,mBACA,MAAA;AAAA,KAEU,uBAAA,GAA0B,sBAAA,CACpC,MAAA,mBACA,MAAA;AAAA,KAEU,eAAA,GAAkB,WAAA,GAAc,4BAAA,GAA+B,uBAAA;AAAA,KAC/D,gBAAA,GAAmB,WAAA,GAAc,uBAAA;AAAA,KAEjC,wBAAA,GAA2B,OAAA,CACrC,UAAA,CAAW,4BAAA;AAAA,KAED,uBAAA,GAA0B,WAAA,CAAY,wBAAA;AAAA,UAEjC,qBAAA;EACf,WAAA,EAAa,WAAA;EACb,iBAAA,EAAmB,4BAAA;AAAA;AAAA,iBAGL,aAAA,CAAc,KAAA,YAAiB,KAAA,IAAS,MAAA;AAAA,iBA6CxC,WAAA,CAAY,KAAA,YAAiB,SAAA;AAAA,iBA4E7B,oBAAA,CACd,WAAA,EAAa,eAAA,eACZ,qBAAA;AAAA,iBA2Ia,uBAAA,CACd,KAAA,WACA,MAAA,EAAQ,WAAA,GAAc,sBAAA,GACrB,uBAAA"}
|