@mcp-b/global 2.0.2 → 2.0.3-canary.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IframeChildTransport, TabServerTransport } from "@mcp-b/transports";
2
2
  import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, Server } from "@mcp-b/webmcp-ts-sdk";
3
- import { z } from "zod/v4";
3
+ import { z } from "zod";
4
4
 
5
5
  //#region src/logger.ts
6
6
  /**
@@ -94,18 +94,29 @@ const logger$2 = createLogger("WebModelContext");
94
94
  * Detect if a schema is a Zod schema object (Record<string, ZodType>)
95
95
  * or a JSON Schema object.
96
96
  *
97
- * Uses duck-typing to detect Zod 4 schemas by checking for the `_zod` property.
97
+ * Uses duck-typing to detect Zod schemas:
98
+ * - Zod 4 schemas have `_zod` property
99
+ * - Zod 3 schemas have `_def` property
100
+ *
101
+ * Both are supported as of Zod 3.25+ (which includes Zod 4 under the hood).
98
102
  */
99
103
  function isZodSchema(schema) {
100
104
  if (typeof schema !== "object" || schema === null) return false;
101
105
  if ("type" in schema && typeof schema.type === "string") return false;
102
106
  const values = Object.values(schema);
103
107
  if (values.length === 0) return false;
104
- return values.some((val) => val != null && typeof val === "object" && "_zod" in val);
108
+ for (const val of values) {
109
+ if (val == null || typeof val !== "object") continue;
110
+ const obj = val;
111
+ if ("_zod" in obj || "_def" in obj) return true;
112
+ }
113
+ return false;
105
114
  }
106
115
  /**
107
- * Convert JSON Schema to Zod validator
108
- * Uses Zod 4's native z.fromJSONSchema() for conversion
116
+ * Convert JSON Schema to Zod validator.
117
+ * Uses z.fromJSONSchema() which is available in Zod 4.2+.
118
+ *
119
+ * Works with both Zod 3.25+ and Zod 4.
109
120
  */
110
121
  function jsonSchemaToZod(jsonSchema) {
111
122
  try {
@@ -116,8 +127,11 @@ function jsonSchemaToZod(jsonSchema) {
116
127
  }
117
128
  }
118
129
  /**
119
- * Convert Zod schema object to JSON Schema
120
- * Uses Zod 4's native z.toJSONSchema() for conversion
130
+ * Convert Zod schema object to JSON Schema.
131
+ * Uses the toJSONSchema function from zod/v4.
132
+ *
133
+ * Works with schemas created from both `import { z } from 'zod'` (Zod 3.25+ compat)
134
+ * and `import { z } from 'zod/v4'` (native Zod 4).
121
135
  *
122
136
  * @param schema - Record of Zod type definitions (e.g., { name: z.string(), age: z.number() })
123
137
  * @returns JSON Schema object compatible with MCP InputSchema
@@ -128,8 +142,13 @@ function zodToJsonSchema(schema) {
128
142
  return rest;
129
143
  }
130
144
  /**
131
- * Normalize a schema to both JSON Schema and Zod formats
132
- * Detects which format is provided and converts to the other
145
+ * Normalize a schema to both JSON Schema and Zod formats.
146
+ * Detects which format is provided and converts to the other.
147
+ *
148
+ * Supports:
149
+ * - Zod schemas from `import { z } from 'zod'` (Zod 3.25+ compat layer)
150
+ * - Zod schemas from `import { z } from 'zod/v4'` (native Zod 4)
151
+ * - Plain JSON Schema objects
133
152
  */
134
153
  function normalizeSchema(schema) {
135
154
  if (isZodSchema(schema)) return {
@@ -181,6 +200,7 @@ const POLYFILL_MARKER_PROPERTY = "__isWebMCPPolyfill";
181
200
  * @returns Detection result with flags for native context and testing API availability
182
201
  */
183
202
  function detectNativeAPI() {
203
+ /* c8 ignore next 2 */
184
204
  if (typeof window === "undefined" || typeof navigator === "undefined") return {
185
205
  hasNativeContext: false,
186
206
  hasNativeTesting: false
@@ -188,8 +208,8 @@ function detectNativeAPI() {
188
208
  const modelContext = navigator.modelContext;
189
209
  const modelContextTesting = navigator.modelContextTesting;
190
210
  if (!modelContext || !modelContextTesting) return {
191
- hasNativeContext: false,
192
- hasNativeTesting: false
211
+ hasNativeContext: Boolean(modelContext),
212
+ hasNativeTesting: Boolean(modelContextTesting)
193
213
  };
194
214
  if (POLYFILL_MARKER_PROPERTY in modelContextTesting && modelContextTesting[POLYFILL_MARKER_PROPERTY] === true) return {
195
215
  hasNativeContext: false,
@@ -898,11 +918,11 @@ var WebModelContext = class {
898
918
  * @private
899
919
  */
900
920
  validateResource(resource) {
901
- const templateParamRegex = /\{([^}]+)\}/g;
921
+ const templateParamRegex = /\{([^}]{1,100})\}/g;
902
922
  const templateParams = [];
903
923
  for (const match of resource.uri.matchAll(templateParamRegex)) {
904
924
  const paramName = match[1];
905
- if (paramName) templateParams.push(paramName);
925
+ templateParams.push(paramName);
906
926
  }
907
927
  return {
908
928
  uri: resource.uri,
@@ -1318,7 +1338,13 @@ var WebModelContext = class {
1318
1338
  async readResource(uri) {
1319
1339
  const staticResource = this.bridge.resources.get(uri);
1320
1340
  if (staticResource && !staticResource.isTemplate) try {
1321
- const parsedUri = new URL(uri);
1341
+ let parsedUri;
1342
+ try {
1343
+ parsedUri = new URL(uri);
1344
+ } catch {
1345
+ parsedUri = new URL(`custom-scheme:///${encodeURIComponent(uri)}`);
1346
+ parsedUri.originalUri = uri;
1347
+ }
1322
1348
  return await staticResource.read(parsedUri);
1323
1349
  } catch (error) {
1324
1350
  logger$1.error(`Error reading resource ${uri}:`, error);
@@ -1328,7 +1354,13 @@ var WebModelContext = class {
1328
1354
  if (!resource.isTemplate) continue;
1329
1355
  const params = this.matchUriTemplate(resource.uri, uri);
1330
1356
  if (params) try {
1331
- const parsedUri = new URL(uri);
1357
+ let parsedUri;
1358
+ try {
1359
+ parsedUri = new URL(uri);
1360
+ } catch {
1361
+ parsedUri = new URL(`custom-scheme:///${encodeURIComponent(uri)}`);
1362
+ parsedUri.originalUri = uri;
1363
+ }
1332
1364
  return await resource.read(parsedUri, params);
1333
1365
  } catch (error) {
1334
1366
  logger$1.error(`Error reading resource ${uri}:`, error);
@@ -1361,8 +1393,7 @@ var WebModelContext = class {
1361
1393
  const params = {};
1362
1394
  for (let i = 0; i < paramNames.length; i++) {
1363
1395
  const paramName = paramNames[i];
1364
- const paramValue = match[i + 1];
1365
- if (paramName !== void 0 && paramValue !== void 0) params[paramName] = paramValue;
1396
+ params[paramName] = match[i + 1];
1366
1397
  }
1367
1398
  return params;
1368
1399
  }
@@ -1640,6 +1671,7 @@ function initializeMCPBridge(options) {
1640
1671
  * ```
1641
1672
  */
1642
1673
  function initializeWebModelContext(options) {
1674
+ /* c8 ignore next 4 */
1643
1675
  if (typeof window === "undefined") {
1644
1676
  logger$1.warn("Not in browser environment, skipping initialization");
1645
1677
  return;
@@ -1733,6 +1765,7 @@ function initializeWebModelContext(options) {
1733
1765
  * ```
1734
1766
  */
1735
1767
  function cleanupWebModelContext() {
1768
+ /* c8 ignore next */
1736
1769
  if (typeof window === "undefined") return;
1737
1770
  if (window.__mcpBridge) try {
1738
1771
  window.__mcpBridge.tabServer.close();