@mcp-b/global 1.2.1 → 2.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/index.js CHANGED
@@ -1,45 +1,130 @@
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 { jsonSchemaToZod } from "@composio/json-schema-to-zod";
4
- import { z } from "zod";
5
- import { zodToJsonSchema as zodToJsonSchema$1 } from "zod-to-json-schema";
3
+ import { z } from "zod/v4";
6
4
 
5
+ //#region src/logger.ts
6
+ /**
7
+ * @license
8
+ * Copyright 2025 Google LLC
9
+ * SPDX-License-Identifier: Apache-2.0
10
+ */
11
+ /**
12
+ * Lightweight logging system for @mcp-b/global
13
+ *
14
+ * Design Decision: This implements a custom logger instead of using the 'debug'
15
+ * package to reduce bundle size and eliminate external dependencies in the
16
+ * browser build. The API is intentionally simpler, focusing on the specific
17
+ * needs of browser-based MCP implementations.
18
+ *
19
+ * Configuration via localStorage:
20
+ * - localStorage.setItem('WEBMCP_DEBUG', '*') - enable all debug logging
21
+ * - localStorage.setItem('WEBMCP_DEBUG', 'WebModelContext') - enable specific namespace
22
+ * - localStorage.setItem('WEBMCP_DEBUG', 'WebModelContext,NativeAdapter') - multiple namespaces
23
+ * - localStorage.setItem('WEBMCP_DEBUG', 'WebModelContext:') - enable namespace and sub-namespaces
24
+ * - localStorage.removeItem('WEBMCP_DEBUG') - disable debug logging (default)
25
+ *
26
+ * Environment Support:
27
+ * - Automatically detects localStorage availability
28
+ * - Gracefully degrades to "disabled" state when localStorage is inaccessible
29
+ * - Never throws errors from configuration checks (safe for private browsing mode)
30
+ */
31
+ /** localStorage key for debug configuration */
32
+ const DEBUG_CONFIG_KEY = "WEBMCP_DEBUG";
33
+ /**
34
+ * Check if debug logging is enabled for a namespace
35
+ *
36
+ * Supports namespace hierarchy via colons. Setting 'WebModelContext' will match
37
+ * both 'WebModelContext' and 'WebModelContext:init', but NOT 'WebModelContextTesting'.
38
+ */
39
+ function isDebugEnabled(namespace) {
40
+ if (typeof window === "undefined" || !window.localStorage) return false;
41
+ try {
42
+ const debugConfig = localStorage.getItem(DEBUG_CONFIG_KEY);
43
+ if (!debugConfig) return false;
44
+ if (debugConfig === "*") return true;
45
+ return debugConfig.split(",").map((p) => p.trim()).some((pattern) => namespace === pattern || namespace.startsWith(`${pattern}:`));
46
+ } catch (err) {
47
+ if (typeof console !== "undefined" && console.warn) {
48
+ const message = err instanceof Error ? err.message : String(err);
49
+ console.warn(`[WebMCP] localStorage access failed, debug logging disabled: ${message}`);
50
+ }
51
+ return false;
52
+ }
53
+ }
54
+ /**
55
+ * No-op function for disabled log levels
56
+ */
57
+ const noop = () => {};
58
+ /**
59
+ * Create a namespaced logger
60
+ *
61
+ * Uses .bind() to prepend namespace prefixes to console methods without manual
62
+ * string concatenation. Debug enablement is determined at logger creation time
63
+ * for performance - changes to localStorage after creation won't affect existing
64
+ * loggers. Refresh the page to apply new WEBMCP_DEBUG settings.
65
+ *
66
+ * @param namespace - Namespace for the logger (e.g., 'WebModelContext', 'NativeAdapter')
67
+ * @returns Logger instance with debug, info, warn, error methods
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const logger = createLogger('WebModelContext');
72
+ * logger.debug('Tool registered:', toolName); // Only shown if WEBMCP_DEBUG includes 'WebModelContext'
73
+ * logger.error('Execution failed:', error); // Always enabled
74
+ * ```
75
+ */
76
+ function createLogger(namespace) {
77
+ const prefix = `[${namespace}]`;
78
+ const isDebug = isDebugEnabled(namespace);
79
+ const boundWarn = console.warn.bind(console, prefix);
80
+ const boundError = console.error.bind(console, prefix);
81
+ const boundLog = console.log.bind(console, prefix);
82
+ return {
83
+ warn: boundWarn,
84
+ error: boundError,
85
+ debug: isDebug ? boundLog : noop,
86
+ info: isDebug ? boundLog : noop
87
+ };
88
+ }
89
+
90
+ //#endregion
7
91
  //#region src/validation.ts
92
+ const logger$2 = createLogger("WebModelContext");
8
93
  /**
9
94
  * Detect if a schema is a Zod schema object (Record<string, ZodType>)
10
- * or a JSON Schema object
95
+ * or a JSON Schema object.
96
+ *
97
+ * Uses duck-typing to detect Zod 4 schemas by checking for the `_zod` property.
11
98
  */
12
99
  function isZodSchema(schema) {
13
100
  if (typeof schema !== "object" || schema === null) return false;
14
101
  if ("type" in schema && typeof schema.type === "string") return false;
15
102
  const values = Object.values(schema);
16
103
  if (values.length === 0) return false;
17
- return values.some((val) => val instanceof z.ZodType);
104
+ return values.some((val) => val != null && typeof val === "object" && "_zod" in val);
18
105
  }
19
106
  /**
20
107
  * Convert JSON Schema to Zod validator
21
- * Uses @composio/json-schema-to-zod for conversion
108
+ * Uses Zod 4's native z.fromJSONSchema() for conversion
22
109
  */
23
- function jsonSchemaToZod$1(jsonSchema) {
110
+ function jsonSchemaToZod(jsonSchema) {
24
111
  try {
25
- return jsonSchemaToZod(jsonSchema);
112
+ return z.fromJSONSchema(jsonSchema);
26
113
  } catch (error) {
27
- console.warn("[Web Model Context] Failed to convert JSON Schema to Zod:", error);
114
+ logger$2.warn("Failed to convert JSON Schema to Zod:", error);
28
115
  return z.object({}).passthrough();
29
116
  }
30
117
  }
31
118
  /**
32
119
  * Convert Zod schema object to JSON Schema
33
- * Uses zod-to-json-schema package for comprehensive conversion
120
+ * Uses Zod 4's native z.toJSONSchema() for conversion
34
121
  *
35
122
  * @param schema - Record of Zod type definitions (e.g., { name: z.string(), age: z.number() })
36
123
  * @returns JSON Schema object compatible with MCP InputSchema
37
124
  */
38
125
  function zodToJsonSchema(schema) {
39
- const { $schema: _,...rest } = zodToJsonSchema$1(z.object(schema), {
40
- $refStrategy: "none",
41
- target: "jsonSchema7"
42
- });
126
+ const zodObject = z.object(schema);
127
+ const { $schema: _,...rest } = z.toJSONSchema(zodObject);
43
128
  return rest;
44
129
  }
45
130
  /**
@@ -54,7 +139,7 @@ function normalizeSchema(schema) {
54
139
  const jsonSchema = schema;
55
140
  return {
56
141
  jsonSchema,
57
- zodValidator: jsonSchemaToZod$1(jsonSchema)
142
+ zodValidator: jsonSchemaToZod(jsonSchema)
58
143
  };
59
144
  }
60
145
  /**
@@ -64,7 +149,7 @@ function validateWithZod(data, validator) {
64
149
  const result = validator.safeParse(data);
65
150
  if (!result.success) return {
66
151
  success: false,
67
- error: `Validation failed:\n${result.error.errors.map((err) => ` - ${err.path.join(".") || "root"}: ${err.message}`).join("\n")}`
152
+ error: `Validation failed:\n${result.error.issues.map((err) => ` - ${err.path.join(".") || "root"}: ${err.message}`).join("\n")}`
68
153
  };
69
154
  return {
70
155
  success: true,
@@ -74,11 +159,24 @@ function validateWithZod(data, validator) {
74
159
 
75
160
  //#endregion
76
161
  //#region src/global.ts
162
+ const logger$1 = createLogger("WebModelContext");
163
+ const nativeLogger = createLogger("NativeAdapter");
164
+ const bridgeLogger = createLogger("MCPBridge");
165
+ const testingLogger = createLogger("ModelContextTesting");
166
+ /**
167
+ * Marker property name used to identify polyfill implementations.
168
+ * This constant ensures single source of truth for the marker used in
169
+ * both detection (detectNativeAPI) and definition (WebModelContextTesting).
170
+ */
171
+ const POLYFILL_MARKER_PROPERTY = "__isWebMCPPolyfill";
77
172
  /**
78
173
  * Detect if the native Chromium Web Model Context API is available.
79
174
  * Checks for both navigator.modelContext and navigator.modelContextTesting,
80
- * and verifies they are native implementations (not polyfills) by examining
81
- * the constructor name.
175
+ * and verifies they are native implementations (not polyfills).
176
+ *
177
+ * Detection uses a marker property (`__isWebMCPPolyfill`) on the testing API
178
+ * to reliably distinguish polyfills from native implementations. This approach
179
+ * works correctly even when class names are minified in production builds.
82
180
  *
83
181
  * @returns Detection result with flags for native context and testing API availability
84
182
  */
@@ -93,7 +191,7 @@ function detectNativeAPI() {
93
191
  hasNativeContext: false,
94
192
  hasNativeTesting: false
95
193
  };
96
- if ((modelContextTesting.constructor?.name || "").includes("WebModelContext")) return {
194
+ if (POLYFILL_MARKER_PROPERTY in modelContextTesting && modelContextTesting[POLYFILL_MARKER_PROPERTY] === true) return {
97
195
  hasNativeContext: false,
98
196
  hasNativeTesting: false
99
197
  };
@@ -133,7 +231,6 @@ var NativeModelContextAdapter = class {
133
231
  this.nativeContext = nativeContext;
134
232
  this.nativeTesting = nativeTesting;
135
233
  this.nativeTesting.registerToolsChangedCallback(() => {
136
- console.log("[Native Adapter] Tool change detected from native API");
137
234
  this.syncToolsFromNative();
138
235
  });
139
236
  this.syncToolsFromNative();
@@ -150,7 +247,6 @@ var NativeModelContextAdapter = class {
150
247
  this.syncInProgress = true;
151
248
  try {
152
249
  const nativeTools = this.nativeTesting.listTools();
153
- console.log(`[Native Adapter] Syncing ${nativeTools.length} tools from native API`);
154
250
  this.bridge.tools.clear();
155
251
  for (const toolInfo of nativeTools) try {
156
252
  const inputSchema = JSON.parse(toolInfo.inputSchema);
@@ -162,11 +258,11 @@ var NativeModelContextAdapter = class {
162
258
  const result = await this.nativeTesting.executeTool(toolInfo.name, JSON.stringify(args));
163
259
  return this.convertToToolResponse(result);
164
260
  },
165
- inputValidator: jsonSchemaToZod$1(inputSchema)
261
+ inputValidator: jsonSchemaToZod(inputSchema)
166
262
  };
167
263
  this.bridge.tools.set(toolInfo.name, validatedTool);
168
264
  } catch (error) {
169
- console.error(`[Native Adapter] Failed to sync tool "${toolInfo.name}":`, error);
265
+ nativeLogger.error(`Failed to sync tool "${toolInfo.name}":`, error);
170
266
  }
171
267
  this.notifyMCPServers();
172
268
  } finally {
@@ -226,7 +322,6 @@ var NativeModelContextAdapter = class {
226
322
  * @param {ModelContextInput} context - Context containing tools to register
227
323
  */
228
324
  provideContext(context) {
229
- console.log("[Native Adapter] Delegating provideContext to native API");
230
325
  this.nativeContext.provideContext(context);
231
326
  }
232
327
  /**
@@ -238,7 +333,6 @@ var NativeModelContextAdapter = class {
238
333
  * @returns {{unregister: () => void}} Object with unregister function
239
334
  */
240
335
  registerTool(tool) {
241
- console.log(`[Native Adapter] Delegating registerTool("${tool.name}") to native API`);
242
336
  return this.nativeContext.registerTool(tool);
243
337
  }
244
338
  /**
@@ -248,7 +342,6 @@ var NativeModelContextAdapter = class {
248
342
  * @param {string} name - Name of the tool to unregister
249
343
  */
250
344
  unregisterTool(name) {
251
- console.log(`[Native Adapter] Delegating unregisterTool("${name}") to native API`);
252
345
  this.nativeContext.unregisterTool(name);
253
346
  }
254
347
  /**
@@ -256,7 +349,6 @@ var NativeModelContextAdapter = class {
256
349
  * Delegates to navigator.modelContext.clearContext().
257
350
  */
258
351
  clearContext() {
259
- console.log("[Native Adapter] Delegating clearContext to native API");
260
352
  this.nativeContext.clearContext();
261
353
  }
262
354
  /**
@@ -269,12 +361,11 @@ var NativeModelContextAdapter = class {
269
361
  * @internal
270
362
  */
271
363
  async executeTool(toolName, args) {
272
- console.log(`[Native Adapter] Executing tool "${toolName}" via native API`);
273
364
  try {
274
365
  const result = await this.nativeTesting.executeTool(toolName, JSON.stringify(args));
275
366
  return this.convertToToolResponse(result);
276
367
  } catch (error) {
277
- console.error(`[Native Adapter] Error executing tool "${toolName}":`, error);
368
+ nativeLogger.error(`Error executing tool "${toolName}":`, error);
278
369
  return {
279
370
  content: [{
280
371
  type: "text",
@@ -305,7 +396,7 @@ var NativeModelContextAdapter = class {
305
396
  * This is a polyfill-only feature.
306
397
  */
307
398
  registerResource(_resource) {
308
- console.warn("[Native Adapter] registerResource is not supported by native API");
399
+ nativeLogger.warn("registerResource is not supported by native API");
309
400
  return { unregister: () => {} };
310
401
  }
311
402
  /**
@@ -313,7 +404,7 @@ var NativeModelContextAdapter = class {
313
404
  * Note: Native Chromium API does not yet support resources.
314
405
  */
315
406
  unregisterResource(_uri) {
316
- console.warn("[Native Adapter] unregisterResource is not supported by native API");
407
+ nativeLogger.warn("unregisterResource is not supported by native API");
317
408
  }
318
409
  /**
319
410
  * Lists all registered resources.
@@ -343,7 +434,7 @@ var NativeModelContextAdapter = class {
343
434
  * This is a polyfill-only feature.
344
435
  */
345
436
  registerPrompt(_prompt) {
346
- console.warn("[Native Adapter] registerPrompt is not supported by native API");
437
+ nativeLogger.warn("registerPrompt is not supported by native API");
347
438
  return { unregister: () => {} };
348
439
  }
349
440
  /**
@@ -351,7 +442,7 @@ var NativeModelContextAdapter = class {
351
442
  * Note: Native Chromium API does not yet support prompts.
352
443
  */
353
444
  unregisterPrompt(_name) {
354
- console.warn("[Native Adapter] unregisterPrompt is not supported by native API");
445
+ nativeLogger.warn("unregisterPrompt is not supported by native API");
355
446
  }
356
447
  /**
357
448
  * Lists all registered prompts.
@@ -406,7 +497,6 @@ var NativeModelContextAdapter = class {
406
497
  * This is handled by the polyfill.
407
498
  */
408
499
  async createMessage(params) {
409
- console.log("[Native Adapter] Requesting sampling from client");
410
500
  const underlyingServer = this.bridge.tabServer.server;
411
501
  if (!underlyingServer?.createMessage) throw new Error("Sampling is not supported: no connected client with sampling capability");
412
502
  return underlyingServer.createMessage(params);
@@ -417,7 +507,6 @@ var NativeModelContextAdapter = class {
417
507
  * This is handled by the polyfill.
418
508
  */
419
509
  async elicitInput(params) {
420
- console.log("[Native Adapter] Requesting elicitation from client");
421
510
  const underlyingServer = this.bridge.tabServer.server;
422
511
  if (!underlyingServer?.elicitInput) throw new Error("Elicitation is not supported: no connected client with elicitation capability");
423
512
  return underlyingServer.elicitInput(params);
@@ -490,6 +579,15 @@ const RAPID_DUPLICATE_WINDOW_MS = 50;
490
579
  * @implements {ModelContextTesting}
491
580
  */
492
581
  var WebModelContextTesting = class {
582
+ /**
583
+ * Marker property to identify this as a polyfill implementation.
584
+ * Used by detectNativeAPI() to distinguish polyfill from native Chromium API.
585
+ * This approach works reliably even when class names are minified in production builds.
586
+ *
587
+ * @see POLYFILL_MARKER_PROPERTY - The constant defining this property name
588
+ * @see MayHavePolyfillMarker - The interface for type-safe detection
589
+ */
590
+ [POLYFILL_MARKER_PROPERTY] = true;
493
591
  toolCallHistory = [];
494
592
  mockResponses = /* @__PURE__ */ new Map();
495
593
  toolsChangedCallbacks = /* @__PURE__ */ new Set();
@@ -547,7 +645,7 @@ var WebModelContextTesting = class {
547
645
  for (const callback of this.toolsChangedCallbacks) try {
548
646
  callback();
549
647
  } catch (error) {
550
- console.error("[Model Context Testing] Error in tools changed callback:", error);
648
+ testingLogger.error("Error in tools changed callback:", error);
551
649
  }
552
650
  }
553
651
  /**
@@ -561,7 +659,6 @@ var WebModelContextTesting = class {
561
659
  * @throws {Error} If the tool does not exist
562
660
  */
563
661
  async executeTool(toolName, inputArgsJson) {
564
- console.log(`[Model Context Testing] Executing tool: ${toolName}`);
565
662
  let args;
566
663
  try {
567
664
  args = JSON.parse(inputArgsJson);
@@ -598,7 +695,6 @@ var WebModelContextTesting = class {
598
695
  */
599
696
  registerToolsChangedCallback(callback) {
600
697
  this.toolsChangedCallbacks.add(callback);
601
- console.log("[Model Context Testing] Tools changed callback registered");
602
698
  }
603
699
  /**
604
700
  * Gets all tool calls that have been recorded (polyfill extension).
@@ -613,7 +709,6 @@ var WebModelContextTesting = class {
613
709
  */
614
710
  clearToolCalls() {
615
711
  this.toolCallHistory = [];
616
- console.log("[Model Context Testing] Tool call history cleared");
617
712
  }
618
713
  /**
619
714
  * Sets a mock response for a specific tool (polyfill extension).
@@ -624,7 +719,6 @@ var WebModelContextTesting = class {
624
719
  */
625
720
  setMockToolResponse(toolName, response) {
626
721
  this.mockResponses.set(toolName, response);
627
- console.log(`[Model Context Testing] Mock response set for tool: ${toolName}`);
628
722
  }
629
723
  /**
630
724
  * Clears the mock response for a specific tool (polyfill extension).
@@ -633,14 +727,12 @@ var WebModelContextTesting = class {
633
727
  */
634
728
  clearMockToolResponse(toolName) {
635
729
  this.mockResponses.delete(toolName);
636
- console.log(`[Model Context Testing] Mock response cleared for tool: ${toolName}`);
637
730
  }
638
731
  /**
639
732
  * Clears all mock tool responses (polyfill extension).
640
733
  */
641
734
  clearAllMockToolResponses() {
642
735
  this.mockResponses.clear();
643
- console.log("[Model Context Testing] All mock responses cleared");
644
736
  }
645
737
  /**
646
738
  * Gets the current tools registered in the system (polyfill extension).
@@ -657,7 +749,6 @@ var WebModelContextTesting = class {
657
749
  reset() {
658
750
  this.clearToolCalls();
659
751
  this.clearAllMockToolResponses();
660
- console.log("[Model Context Testing] Testing state reset");
661
752
  }
662
753
  };
663
754
  /**
@@ -763,14 +854,13 @@ var WebModelContext = class {
763
854
  * @throws {Error} If a name/uri collides with existing dynamic items
764
855
  */
765
856
  provideContext(context) {
766
- const toolCount = context.tools?.length ?? 0;
767
- const resourceCount = context.resources?.length ?? 0;
768
- const promptCount = context.prompts?.length ?? 0;
769
- console.log(`[Web Model Context] provideContext: ${toolCount} tools, ${resourceCount} resources, ${promptCount} prompts`);
770
857
  this.provideContextTools.clear();
771
858
  this.provideContextResources.clear();
772
859
  this.provideContextPrompts.clear();
773
860
  for (const tool of context.tools ?? []) {
861
+ if (tool.name.startsWith("_")) logger$1.warn(`⚠️ Warning: Tool name "${tool.name}" starts with underscore. This may cause compatibility issues with some MCP clients. Consider using a letter as the first character.`);
862
+ if (/^[0-9]/.test(tool.name)) logger$1.warn(`⚠️ Warning: Tool name "${tool.name}" starts with a number. This may cause compatibility issues. Consider using a letter as the first character.`);
863
+ if (tool.name.startsWith("-")) logger$1.warn(`⚠️ Warning: Tool name "${tool.name}" starts with hyphen. This may cause compatibility issues. Consider using a letter as the first character.`);
774
864
  if (this.dynamicTools.has(tool.name)) throw new Error(`[Web Model Context] Tool name collision: "${tool.name}" is already registered via registerTool(). Please use a different name or unregister the dynamic tool first.`);
775
865
  const { jsonSchema: inputJson, zodValidator: inputZod } = normalizeSchema(tool.inputSchema);
776
866
  const normalizedOutput = tool.outputSchema ? normalizeSchema(tool.outputSchema) : null;
@@ -853,11 +943,13 @@ var WebModelContext = class {
853
943
  * @throws {Error} If tool name collides with existing tools
854
944
  */
855
945
  registerTool(tool) {
856
- console.log(`[Web Model Context] Registering tool dynamically: ${tool.name}`);
946
+ if (tool.name.startsWith("_")) logger$1.warn(`⚠️ Warning: Tool name "${tool.name}" starts with underscore. This may cause compatibility issues with some MCP clients. Consider using a letter as the first character.`);
947
+ if (/^[0-9]/.test(tool.name)) logger$1.warn(`⚠️ Warning: Tool name "${tool.name}" starts with a number. This may cause compatibility issues. Consider using a letter as the first character.`);
948
+ if (tool.name.startsWith("-")) logger$1.warn(`⚠️ Warning: Tool name "${tool.name}" starts with hyphen. This may cause compatibility issues. Consider using a letter as the first character.`);
857
949
  const now = Date.now();
858
950
  const lastRegistration = this.toolRegistrationTimestamps.get(tool.name);
859
951
  if (lastRegistration && now - lastRegistration < RAPID_DUPLICATE_WINDOW_MS) {
860
- console.warn(`[Web Model Context] Tool "${tool.name}" registered multiple times within ${RAPID_DUPLICATE_WINDOW_MS}ms. This is likely due to React Strict Mode double-mounting. Ignoring duplicate registration.`);
952
+ logger$1.warn(`Tool "${tool.name}" registered multiple times within ${RAPID_DUPLICATE_WINDOW_MS}ms. This is likely due to React Strict Mode double-mounting. Ignoring duplicate registration.`);
861
953
  const existingUnregister = this.toolUnregisterFunctions.get(tool.name);
862
954
  if (existingUnregister) return { unregister: existingUnregister };
863
955
  }
@@ -880,10 +972,9 @@ var WebModelContext = class {
880
972
  this.updateBridgeTools();
881
973
  this.scheduleListChanged("tools");
882
974
  const unregisterFn = () => {
883
- console.log(`[Web Model Context] Unregistering tool: ${tool.name}`);
884
975
  if (this.provideContextTools.has(tool.name)) throw new Error(`[Web Model Context] Cannot unregister tool "${tool.name}": This tool was registered via provideContext(). Use provideContext() to update the base tool set.`);
885
976
  if (!this.dynamicTools.has(tool.name)) {
886
- console.warn(`[Web Model Context] Tool "${tool.name}" is not registered, ignoring unregister call`);
977
+ logger$1.warn(`Tool "${tool.name}" is not registered, ignoring unregister call`);
887
978
  return;
888
979
  }
889
980
  this.dynamicTools.delete(tool.name);
@@ -904,11 +995,10 @@ var WebModelContext = class {
904
995
  * @throws {Error} If resource URI collides with existing resources
905
996
  */
906
997
  registerResource(resource) {
907
- console.log(`[Web Model Context] Registering resource dynamically: ${resource.uri}`);
908
998
  const now = Date.now();
909
999
  const lastRegistration = this.resourceRegistrationTimestamps.get(resource.uri);
910
1000
  if (lastRegistration && now - lastRegistration < RAPID_DUPLICATE_WINDOW_MS) {
911
- console.warn(`[Web Model Context] Resource "${resource.uri}" registered multiple times within ${RAPID_DUPLICATE_WINDOW_MS}ms. This is likely due to React Strict Mode double-mounting. Ignoring duplicate registration.`);
1001
+ logger$1.warn(`Resource "${resource.uri}" registered multiple times within ${RAPID_DUPLICATE_WINDOW_MS}ms. This is likely due to React Strict Mode double-mounting. Ignoring duplicate registration.`);
912
1002
  const existingUnregister = this.resourceUnregisterFunctions.get(resource.uri);
913
1003
  if (existingUnregister) return { unregister: existingUnregister };
914
1004
  }
@@ -920,10 +1010,9 @@ var WebModelContext = class {
920
1010
  this.updateBridgeResources();
921
1011
  this.scheduleListChanged("resources");
922
1012
  const unregisterFn = () => {
923
- console.log(`[Web Model Context] Unregistering resource: ${resource.uri}`);
924
1013
  if (this.provideContextResources.has(resource.uri)) throw new Error(`[Web Model Context] Cannot unregister resource "${resource.uri}": This resource was registered via provideContext(). Use provideContext() to update the base resource set.`);
925
1014
  if (!this.dynamicResources.has(resource.uri)) {
926
- console.warn(`[Web Model Context] Resource "${resource.uri}" is not registered, ignoring unregister call`);
1015
+ logger$1.warn(`Resource "${resource.uri}" is not registered, ignoring unregister call`);
927
1016
  return;
928
1017
  }
929
1018
  this.dynamicResources.delete(resource.uri);
@@ -942,11 +1031,10 @@ var WebModelContext = class {
942
1031
  * @param {string} uri - URI of the resource to unregister
943
1032
  */
944
1033
  unregisterResource(uri) {
945
- console.log(`[Web Model Context] Unregistering resource: ${uri}`);
946
1034
  const inProvideContext = this.provideContextResources.has(uri);
947
1035
  const inDynamic = this.dynamicResources.has(uri);
948
1036
  if (!inProvideContext && !inDynamic) {
949
- console.warn(`[Web Model Context] Resource "${uri}" is not registered, ignoring unregister call`);
1037
+ logger$1.warn(`Resource "${uri}" is not registered, ignoring unregister call`);
950
1038
  return;
951
1039
  }
952
1040
  if (inProvideContext) this.provideContextResources.delete(uri);
@@ -995,11 +1083,10 @@ var WebModelContext = class {
995
1083
  * @throws {Error} If prompt name collides with existing prompts
996
1084
  */
997
1085
  registerPrompt(prompt) {
998
- console.log(`[Web Model Context] Registering prompt dynamically: ${prompt.name}`);
999
1086
  const now = Date.now();
1000
1087
  const lastRegistration = this.promptRegistrationTimestamps.get(prompt.name);
1001
1088
  if (lastRegistration && now - lastRegistration < RAPID_DUPLICATE_WINDOW_MS) {
1002
- console.warn(`[Web Model Context] Prompt "${prompt.name}" registered multiple times within ${RAPID_DUPLICATE_WINDOW_MS}ms. This is likely due to React Strict Mode double-mounting. Ignoring duplicate registration.`);
1089
+ logger$1.warn(`Prompt "${prompt.name}" registered multiple times within ${RAPID_DUPLICATE_WINDOW_MS}ms. This is likely due to React Strict Mode double-mounting. Ignoring duplicate registration.`);
1003
1090
  const existingUnregister = this.promptUnregisterFunctions.get(prompt.name);
1004
1091
  if (existingUnregister) return { unregister: existingUnregister };
1005
1092
  }
@@ -1011,10 +1098,9 @@ var WebModelContext = class {
1011
1098
  this.updateBridgePrompts();
1012
1099
  this.scheduleListChanged("prompts");
1013
1100
  const unregisterFn = () => {
1014
- console.log(`[Web Model Context] Unregistering prompt: ${prompt.name}`);
1015
1101
  if (this.provideContextPrompts.has(prompt.name)) throw new Error(`[Web Model Context] Cannot unregister prompt "${prompt.name}": This prompt was registered via provideContext(). Use provideContext() to update the base prompt set.`);
1016
1102
  if (!this.dynamicPrompts.has(prompt.name)) {
1017
- console.warn(`[Web Model Context] Prompt "${prompt.name}" is not registered, ignoring unregister call`);
1103
+ logger$1.warn(`Prompt "${prompt.name}" is not registered, ignoring unregister call`);
1018
1104
  return;
1019
1105
  }
1020
1106
  this.dynamicPrompts.delete(prompt.name);
@@ -1033,11 +1119,10 @@ var WebModelContext = class {
1033
1119
  * @param {string} name - Name of the prompt to unregister
1034
1120
  */
1035
1121
  unregisterPrompt(name) {
1036
- console.log(`[Web Model Context] Unregistering prompt: ${name}`);
1037
1122
  const inProvideContext = this.provideContextPrompts.has(name);
1038
1123
  const inDynamic = this.dynamicPrompts.has(name);
1039
1124
  if (!inProvideContext && !inDynamic) {
1040
- console.warn(`[Web Model Context] Prompt "${name}" is not registered, ignoring unregister call`);
1125
+ logger$1.warn(`Prompt "${name}" is not registered, ignoring unregister call`);
1041
1126
  return;
1042
1127
  }
1043
1128
  if (inProvideContext) this.provideContextPrompts.delete(name);
@@ -1073,11 +1158,10 @@ var WebModelContext = class {
1073
1158
  * @param {string} name - Name of the tool to unregister
1074
1159
  */
1075
1160
  unregisterTool(name) {
1076
- console.log(`[Web Model Context] Unregistering tool: ${name}`);
1077
1161
  const inProvideContext = this.provideContextTools.has(name);
1078
1162
  const inDynamic = this.dynamicTools.has(name);
1079
1163
  if (!inProvideContext && !inDynamic) {
1080
- console.warn(`[Web Model Context] Tool "${name}" is not registered, ignoring unregister call`);
1164
+ logger$1.warn(`Tool "${name}" is not registered, ignoring unregister call`);
1081
1165
  return;
1082
1166
  }
1083
1167
  if (inProvideContext) this.provideContextTools.delete(name);
@@ -1094,7 +1178,6 @@ var WebModelContext = class {
1094
1178
  * Removes all tools, resources, and prompts registered via provideContext() and register* methods.
1095
1179
  */
1096
1180
  clearContext() {
1097
- console.log("[Web Model Context] Clearing all context (tools, resources, prompts)");
1098
1181
  this.provideContextTools.clear();
1099
1182
  this.dynamicTools.clear();
1100
1183
  this.toolRegistrationTimestamps.clear();
@@ -1124,7 +1207,6 @@ var WebModelContext = class {
1124
1207
  this.bridge.tools.clear();
1125
1208
  for (const [name, tool] of this.provideContextTools) this.bridge.tools.set(name, tool);
1126
1209
  for (const [name, tool] of this.dynamicTools) this.bridge.tools.set(name, tool);
1127
- console.log(`[Web Model Context] Updated bridge with ${this.provideContextTools.size} base tools + ${this.dynamicTools.size} dynamic tools = ${this.bridge.tools.size} total`);
1128
1210
  }
1129
1211
  /**
1130
1212
  * Notifies all servers and testing callbacks that the tools list has changed.
@@ -1152,7 +1234,6 @@ var WebModelContext = class {
1152
1234
  this.bridge.resources.clear();
1153
1235
  for (const [uri, resource] of this.provideContextResources) this.bridge.resources.set(uri, resource);
1154
1236
  for (const [uri, resource] of this.dynamicResources) this.bridge.resources.set(uri, resource);
1155
- console.log(`[Web Model Context] Updated bridge with ${this.provideContextResources.size} base resources + ${this.dynamicResources.size} dynamic resources = ${this.bridge.resources.size} total`);
1156
1237
  }
1157
1238
  /**
1158
1239
  * Notifies all servers that the resources list has changed.
@@ -1178,7 +1259,6 @@ var WebModelContext = class {
1178
1259
  this.bridge.prompts.clear();
1179
1260
  for (const [name, prompt] of this.provideContextPrompts) this.bridge.prompts.set(name, prompt);
1180
1261
  for (const [name, prompt] of this.dynamicPrompts) this.bridge.prompts.set(name, prompt);
1181
- console.log(`[Web Model Context] Updated bridge with ${this.provideContextPrompts.size} base prompts + ${this.dynamicPrompts.size} dynamic prompts = ${this.bridge.prompts.size} total`);
1182
1262
  }
1183
1263
  /**
1184
1264
  * Notifies all servers that the prompts list has changed.
@@ -1221,7 +1301,7 @@ var WebModelContext = class {
1221
1301
  break;
1222
1302
  default: {
1223
1303
  const _exhaustive = listType;
1224
- console.error(`[Web Model Context] Unknown list type: ${_exhaustive}`);
1304
+ logger$1.error(`Unknown list type: ${_exhaustive}`);
1225
1305
  }
1226
1306
  }
1227
1307
  });
@@ -1236,13 +1316,12 @@ var WebModelContext = class {
1236
1316
  * @internal
1237
1317
  */
1238
1318
  async readResource(uri) {
1239
- console.log(`[Web Model Context] Reading resource: ${uri}`);
1240
1319
  const staticResource = this.bridge.resources.get(uri);
1241
1320
  if (staticResource && !staticResource.isTemplate) try {
1242
1321
  const parsedUri = new URL(uri);
1243
1322
  return await staticResource.read(parsedUri);
1244
1323
  } catch (error) {
1245
- console.error(`[Web Model Context] Error reading resource ${uri}:`, error);
1324
+ logger$1.error(`Error reading resource ${uri}:`, error);
1246
1325
  throw error;
1247
1326
  }
1248
1327
  for (const resource of this.bridge.resources.values()) {
@@ -1252,7 +1331,7 @@ var WebModelContext = class {
1252
1331
  const parsedUri = new URL(uri);
1253
1332
  return await resource.read(parsedUri, params);
1254
1333
  } catch (error) {
1255
- console.error(`[Web Model Context] Error reading resource ${uri}:`, error);
1334
+ logger$1.error(`Error reading resource ${uri}:`, error);
1256
1335
  throw error;
1257
1336
  }
1258
1337
  }
@@ -1297,20 +1376,19 @@ var WebModelContext = class {
1297
1376
  * @internal
1298
1377
  */
1299
1378
  async getPrompt(name, args) {
1300
- console.log(`[Web Model Context] Getting prompt: ${name}`);
1301
1379
  const prompt = this.bridge.prompts.get(name);
1302
1380
  if (!prompt) throw new Error(`Prompt not found: ${name}`);
1303
1381
  if (prompt.argsValidator && args) {
1304
1382
  const validation = validateWithZod(args, prompt.argsValidator);
1305
1383
  if (!validation.success) {
1306
- console.error(`[Web Model Context] Argument validation failed for prompt ${name}:`, validation.error);
1384
+ logger$1.error(`Argument validation failed for prompt ${name}:`, validation.error);
1307
1385
  throw new Error(`Argument validation error for prompt "${name}":\n${validation.error}`);
1308
1386
  }
1309
1387
  }
1310
1388
  try {
1311
1389
  return await prompt.get(args ?? {});
1312
1390
  } catch (error) {
1313
- console.error(`[Web Model Context] Error getting prompt ${name}:`, error);
1391
+ logger$1.error(`Error getting prompt ${name}:`, error);
1314
1392
  throw error;
1315
1393
  }
1316
1394
  }
@@ -1333,10 +1411,9 @@ var WebModelContext = class {
1333
1411
  async executeTool(toolName, args) {
1334
1412
  const tool = this.bridge.tools.get(toolName);
1335
1413
  if (!tool) throw new Error(`Tool not found: ${toolName}`);
1336
- console.log(`[Web Model Context] Validating input for tool: ${toolName}`);
1337
1414
  const validation = validateWithZod(args, tool.inputValidator);
1338
1415
  if (!validation.success) {
1339
- console.error(`[Web Model Context] Input validation failed for ${toolName}:`, validation.error);
1416
+ logger$1.error(`Input validation failed for ${toolName}:`, validation.error);
1340
1417
  return {
1341
1418
  content: [{
1342
1419
  type: "text",
@@ -1349,30 +1426,24 @@ var WebModelContext = class {
1349
1426
  if (this.testingAPI) this.testingAPI.recordToolCall(toolName, validatedArgs);
1350
1427
  if (this.testingAPI?.hasMockResponse(toolName)) {
1351
1428
  const mockResponse = this.testingAPI.getMockResponse(toolName);
1352
- if (mockResponse) {
1353
- console.log(`[Web Model Context] Returning mock response for tool: ${toolName}`);
1354
- return mockResponse;
1355
- }
1429
+ if (mockResponse) return mockResponse;
1356
1430
  }
1357
1431
  const event = new WebToolCallEvent(toolName, validatedArgs);
1358
1432
  this.dispatchEvent(event);
1359
1433
  if (event.defaultPrevented && event.hasResponse()) {
1360
1434
  const response = event.getResponse();
1361
- if (response) {
1362
- console.log(`[Web Model Context] Tool ${toolName} handled by event listener`);
1363
- return response;
1364
- }
1435
+ if (response) return response;
1365
1436
  }
1366
- console.log(`[Web Model Context] Executing tool: ${toolName}`);
1367
1437
  try {
1368
1438
  const response = await tool.execute(validatedArgs);
1369
1439
  if (tool.outputValidator && response.structuredContent) {
1370
1440
  const outputValidation = validateWithZod(response.structuredContent, tool.outputValidator);
1371
- if (!outputValidation.success) console.warn(`[Web Model Context] Output validation failed for ${toolName}:`, outputValidation.error);
1441
+ if (!outputValidation.success) logger$1.warn(`Output validation failed for ${toolName}:`, outputValidation.error);
1372
1442
  }
1443
+ if (response.metadata && typeof response.metadata === "object" && "willNavigate" in response.metadata) logger$1.info(`Tool "${toolName}" will trigger navigation`, response.metadata);
1373
1444
  return response;
1374
1445
  } catch (error) {
1375
- console.error(`[Web Model Context] Error executing tool ${toolName}:`, error);
1446
+ logger$1.error(`Error executing tool ${toolName}:`, error);
1376
1447
  return {
1377
1448
  content: [{
1378
1449
  type: "text",
@@ -1406,7 +1477,6 @@ var WebModelContext = class {
1406
1477
  * @returns {Promise<SamplingResult>} The LLM completion result
1407
1478
  */
1408
1479
  async createMessage(params) {
1409
- console.log("[Web Model Context] Requesting sampling from client");
1410
1480
  const underlyingServer = this.bridge.tabServer.server;
1411
1481
  if (!underlyingServer?.createMessage) throw new Error("Sampling is not supported: no connected client with sampling capability");
1412
1482
  return underlyingServer.createMessage(params);
@@ -1419,7 +1489,6 @@ var WebModelContext = class {
1419
1489
  * @returns {Promise<ElicitationResult>} The user's response
1420
1490
  */
1421
1491
  async elicitInput(params) {
1422
- console.log("[Web Model Context] Requesting elicitation from client");
1423
1492
  const underlyingServer = this.bridge.tabServer.server;
1424
1493
  if (!underlyingServer?.elicitInput) throw new Error("Elicitation is not supported: no connected client with elicitation capability");
1425
1494
  return underlyingServer.elicitInput(params);
@@ -1434,16 +1503,13 @@ var WebModelContext = class {
1434
1503
  * @returns {MCPBridge} The initialized MCP bridge
1435
1504
  */
1436
1505
  function initializeMCPBridge(options) {
1437
- console.log("[Web Model Context] Initializing MCP bridge");
1438
1506
  const hostname = window.location.hostname || "localhost";
1439
1507
  const transportOptions = options?.transport;
1440
1508
  const setupServerHandlers = (server, bridge$1) => {
1441
1509
  server.setRequestHandler(ListToolsRequestSchema, async () => {
1442
- console.log("[MCP Bridge] Handling list_tools request");
1443
1510
  return { tools: bridge$1.modelContext.listTools() };
1444
1511
  });
1445
1512
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
1446
- console.log(`[MCP Bridge] Handling call_tool request: ${request.params.name}`);
1447
1513
  const toolName = request.params.name;
1448
1514
  const args = request.params.arguments || {};
1449
1515
  try {
@@ -1454,40 +1520,35 @@ function initializeMCPBridge(options) {
1454
1520
  ...response.structuredContent && { structuredContent: response.structuredContent }
1455
1521
  };
1456
1522
  } catch (error) {
1457
- console.error(`[MCP Bridge] Error calling tool ${toolName}:`, error);
1523
+ bridgeLogger.error(`Error calling tool ${toolName}:`, error);
1458
1524
  throw error;
1459
1525
  }
1460
1526
  });
1461
1527
  server.setRequestHandler(ListResourcesRequestSchema, async () => {
1462
- console.log("[MCP Bridge] Handling list_resources request");
1463
1528
  return { resources: bridge$1.modelContext.listResources() };
1464
1529
  });
1465
1530
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
1466
- console.log(`[MCP Bridge] Handling read_resource request: ${request.params.uri}`);
1467
1531
  try {
1468
1532
  return await bridge$1.modelContext.readResource(request.params.uri);
1469
1533
  } catch (error) {
1470
- console.error(`[MCP Bridge] Error reading resource ${request.params.uri}:`, error);
1534
+ bridgeLogger.error(`Error reading resource ${request.params.uri}:`, error);
1471
1535
  throw error;
1472
1536
  }
1473
1537
  });
1474
1538
  server.setRequestHandler(ListPromptsRequestSchema, async () => {
1475
- console.log("[MCP Bridge] Handling list_prompts request");
1476
1539
  return { prompts: bridge$1.modelContext.listPrompts() };
1477
1540
  });
1478
1541
  server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1479
- console.log(`[MCP Bridge] Handling get_prompt request: ${request.params.name}`);
1480
1542
  try {
1481
1543
  return await bridge$1.modelContext.getPrompt(request.params.name, request.params.arguments);
1482
1544
  } catch (error) {
1483
- console.error(`[MCP Bridge] Error getting prompt ${request.params.name}:`, error);
1545
+ bridgeLogger.error(`Error getting prompt ${request.params.name}:`, error);
1484
1546
  throw error;
1485
1547
  }
1486
1548
  });
1487
1549
  };
1488
1550
  const customTransport = transportOptions?.create?.();
1489
1551
  if (customTransport) {
1490
- console.log("[Web Model Context] Using custom transport");
1491
1552
  const server = new Server({
1492
1553
  name: hostname,
1493
1554
  version: "1.0.0"
@@ -1507,10 +1568,8 @@ function initializeMCPBridge(options) {
1507
1568
  bridge$1.modelContext = new WebModelContext(bridge$1);
1508
1569
  setupServerHandlers(server, bridge$1);
1509
1570
  server.connect(customTransport);
1510
- console.log("[Web Model Context] MCP server connected with custom transport");
1511
1571
  return bridge$1;
1512
1572
  }
1513
- console.log("[Web Model Context] Using dual-server mode");
1514
1573
  const tabServerEnabled = transportOptions?.tabServer !== false;
1515
1574
  const tabServer = new Server({
1516
1575
  name: `${hostname}-tab`,
@@ -1537,12 +1596,10 @@ function initializeMCPBridge(options) {
1537
1596
  ...restTabServerOptions
1538
1597
  });
1539
1598
  tabServer.connect(tabTransport);
1540
- console.log("[Web Model Context] Tab server connected");
1541
1599
  }
1542
1600
  const isInIframe = typeof window !== "undefined" && window.parent !== window;
1543
1601
  const iframeServerConfig = transportOptions?.iframeServer;
1544
1602
  if (iframeServerConfig !== false && (iframeServerConfig !== void 0 || isInIframe)) {
1545
- console.log("[Web Model Context] Enabling iframe server");
1546
1603
  const iframeServer = new Server({
1547
1604
  name: `${hostname}-iframe`,
1548
1605
  version: "1.0.0"
@@ -1559,7 +1616,6 @@ function initializeMCPBridge(options) {
1559
1616
  });
1560
1617
  iframeServer.connect(iframeTransport);
1561
1618
  bridge.iframeServer = iframeServer;
1562
- console.log("[Web Model Context] Iframe server connected");
1563
1619
  }
1564
1620
  return bridge;
1565
1621
  }
@@ -1585,7 +1641,7 @@ function initializeMCPBridge(options) {
1585
1641
  */
1586
1642
  function initializeWebModelContext(options) {
1587
1643
  if (typeof window === "undefined") {
1588
- console.warn("[Web Model Context] Not in browser environment, skipping initialization");
1644
+ logger$1.warn("Not in browser environment, skipping initialization");
1589
1645
  return;
1590
1646
  }
1591
1647
  const effectiveOptions = options ?? window.__webModelContextOptions;
@@ -1594,12 +1650,12 @@ function initializeWebModelContext(options) {
1594
1650
  const nativeContext = window.navigator.modelContext;
1595
1651
  const nativeTesting = window.navigator.modelContextTesting;
1596
1652
  if (!nativeContext || !nativeTesting) {
1597
- console.error("[Web Model Context] Native API detection mismatch");
1653
+ logger$1.error("Native API detection mismatch");
1598
1654
  return;
1599
1655
  }
1600
- console.log("✅ [Web Model Context] Native Chromium API detected");
1601
- console.log(" Using native implementation with MCP bridge synchronization");
1602
- console.log(" Native API will automatically collect tools from embedded iframes");
1656
+ logger$1.info("✅ Native Chromium API detected");
1657
+ logger$1.info(" Using native implementation with MCP bridge synchronization");
1658
+ logger$1.info(" Native API will automatically collect tools from embedded iframes");
1603
1659
  try {
1604
1660
  const bridge = initializeMCPBridge(effectiveOptions);
1605
1661
  bridge.modelContext = new NativeModelContextAdapter(bridge, nativeContext, nativeTesting);
@@ -1609,29 +1665,29 @@ function initializeWebModelContext(options) {
1609
1665
  writable: false,
1610
1666
  configurable: true
1611
1667
  });
1612
- console.log("✅ [Web Model Context] MCP bridge synced with native API");
1613
- console.log(" MCP clients will receive automatic tool updates from native registry");
1668
+ logger$1.info("✅ MCP bridge synced with native API");
1669
+ logger$1.info(" MCP clients will receive automatic tool updates from native registry");
1614
1670
  } catch (error) {
1615
- console.error("[Web Model Context] Failed to initialize native adapter:", error);
1671
+ logger$1.error("Failed to initialize native adapter:", error);
1616
1672
  throw error;
1617
1673
  }
1618
1674
  return;
1619
1675
  }
1620
1676
  if (native.hasNativeContext && !native.hasNativeTesting) {
1621
- console.warn("[Web Model Context] Partial native API detected");
1622
- console.warn(" navigator.modelContext exists but navigator.modelContextTesting is missing");
1623
- console.warn(" Cannot sync with native API. Please enable experimental features:");
1624
- console.warn(" - Navigate to chrome://flags");
1625
- console.warn(" - Enable \"Experimental Web Platform Features\"");
1626
- console.warn(" - Or launch with: --enable-experimental-web-platform-features");
1627
- console.warn(" Skipping initialization to avoid conflicts");
1677
+ logger$1.warn("Partial native API detected");
1678
+ logger$1.warn(" navigator.modelContext exists but navigator.modelContextTesting is missing");
1679
+ logger$1.warn(" Cannot sync with native API. Please enable experimental features:");
1680
+ logger$1.warn(" - Navigate to chrome://flags");
1681
+ logger$1.warn(" - Enable \"Experimental Web Platform Features\"");
1682
+ logger$1.warn(" - Or launch with: --enable-experimental-web-platform-features");
1683
+ logger$1.warn(" Skipping initialization to avoid conflicts");
1628
1684
  return;
1629
1685
  }
1630
1686
  if (window.navigator.modelContext) {
1631
- console.warn("[Web Model Context] window.navigator.modelContext already exists, skipping initialization");
1687
+ logger$1.warn("window.navigator.modelContext already exists, skipping initialization");
1632
1688
  return;
1633
1689
  }
1634
- console.log("[Web Model Context] Native API not detected, installing polyfill");
1690
+ logger$1.info("Native API not detected, installing polyfill");
1635
1691
  try {
1636
1692
  const bridge = initializeMCPBridge(effectiveOptions);
1637
1693
  Object.defineProperty(window.navigator, "modelContext", {
@@ -1644,12 +1700,12 @@ function initializeWebModelContext(options) {
1644
1700
  writable: false,
1645
1701
  configurable: true
1646
1702
  });
1647
- console.log("✅ [Web Model Context] window.navigator.modelContext initialized successfully");
1648
- console.log("[Model Context Testing] Installing polyfill");
1649
- console.log(" 💡 To use the native implementation in Chromium:");
1650
- console.log(" - Navigate to chrome://flags");
1651
- console.log(" - Enable \"Experimental Web Platform Features\"");
1652
- console.log(" - Or launch with: --enable-experimental-web-platform-features");
1703
+ logger$1.info("✅ window.navigator.modelContext initialized successfully");
1704
+ testingLogger.info("Installing polyfill");
1705
+ testingLogger.info(" 💡 To use the native implementation in Chromium:");
1706
+ testingLogger.info(" - Navigate to chrome://flags");
1707
+ testingLogger.info(" - Enable \"Experimental Web Platform Features\"");
1708
+ testingLogger.info(" - Or launch with: --enable-experimental-web-platform-features");
1653
1709
  const testingAPI = new WebModelContextTesting(bridge);
1654
1710
  bridge.modelContextTesting = testingAPI;
1655
1711
  bridge.modelContext.setTestingAPI(testingAPI);
@@ -1658,9 +1714,9 @@ function initializeWebModelContext(options) {
1658
1714
  writable: false,
1659
1715
  configurable: true
1660
1716
  });
1661
- console.log("✅ [Model Context Testing] Polyfill installed at window.navigator.modelContextTesting");
1717
+ testingLogger.info("✅ Polyfill installed at window.navigator.modelContextTesting");
1662
1718
  } catch (error) {
1663
- console.error("[Web Model Context] Failed to initialize:", error);
1719
+ logger$1.error("Failed to initialize:", error);
1664
1720
  throw error;
1665
1721
  }
1666
1722
  }
@@ -1682,16 +1738,17 @@ function cleanupWebModelContext() {
1682
1738
  window.__mcpBridge.tabServer.close();
1683
1739
  if (window.__mcpBridge.iframeServer) window.__mcpBridge.iframeServer.close();
1684
1740
  } catch (error) {
1685
- console.warn("[Web Model Context] Error closing MCP servers:", error);
1741
+ logger$1.warn("Error closing MCP servers:", error);
1686
1742
  }
1687
1743
  delete window.navigator.modelContext;
1688
1744
  delete window.navigator.modelContextTesting;
1689
1745
  delete window.__mcpBridge;
1690
- console.log("[Web Model Context] Cleaned up");
1746
+ logger$1.info("Cleaned up");
1691
1747
  }
1692
1748
 
1693
1749
  //#endregion
1694
1750
  //#region src/index.ts
1751
+ const logger = createLogger("WebModelContext");
1695
1752
  function mergeTransportOptions(base, override) {
1696
1753
  if (!base) return override;
1697
1754
  if (!override) return base;
@@ -1719,7 +1776,7 @@ function parseScriptTagOptions(script) {
1719
1776
  if (dataset.webmcpOptions) try {
1720
1777
  return JSON.parse(dataset.webmcpOptions);
1721
1778
  } catch (error) {
1722
- console.error("[Web Model Context] Invalid JSON in data-webmcp-options:", error);
1779
+ logger.error("Invalid JSON in data-webmcp-options:", error);
1723
1780
  return;
1724
1781
  }
1725
1782
  const options = {};
@@ -1762,10 +1819,10 @@ if (typeof window !== "undefined" && typeof document !== "undefined") {
1762
1819
  try {
1763
1820
  if (shouldAutoInitialize) initializeWebModelContext(mergedOptions);
1764
1821
  } catch (error) {
1765
- console.error("[Web Model Context] Auto-initialization failed:", error);
1822
+ logger.error("Auto-initialization failed:", error);
1766
1823
  }
1767
1824
  }
1768
1825
 
1769
1826
  //#endregion
1770
- export { cleanupWebModelContext, initializeWebModelContext, zodToJsonSchema };
1827
+ export { cleanupWebModelContext, createLogger, initializeWebModelContext, zodToJsonSchema };
1771
1828
  //# sourceMappingURL=index.js.map