@mcp-b/global 0.0.0-beta-20260109203913

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1061 @@
1
+ import { IframeChildTransportOptions, TabServerTransportOptions } from "@mcp-b/transports";
2
+ import { CallToolResult, CreateMessageRequest, CreateMessageResult, ElicitRequest, ElicitResult, Prompt, PromptMessage, Resource, ResourceContents, ResourceTemplate, Server, ToolAnnotations, Transport } from "@mcp-b/webmcp-ts-sdk";
3
+ import { z } from "zod";
4
+
5
+ //#region src/types.d.ts
6
+
7
+ /**
8
+ * JSON Schema definition for tool/prompt input parameters.
9
+ *
10
+ * This interface represents a JSON Schema object as defined by the JSON Schema
11
+ * specification. It's used for defining tool input schemas and prompt argument
12
+ * schemas when not using Zod.
13
+ *
14
+ * @see {@link https://json-schema.org/}
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const schema: InputSchema = {
19
+ * type: 'object',
20
+ * properties: {
21
+ * query: { type: 'string', description: 'Search query' },
22
+ * limit: { type: 'number', description: 'Max results' }
23
+ * },
24
+ * required: ['query']
25
+ * };
26
+ * ```
27
+ */
28
+ interface InputSchema {
29
+ /** The JSON Schema type (typically "object" for tool inputs) */
30
+ type: string;
31
+ /** Property definitions for object schemas */
32
+ properties?: Record<string, {
33
+ /** The property type */
34
+ type: string;
35
+ /** Human-readable description of the property */
36
+ description?: string;
37
+ /** Additional JSON Schema keywords */
38
+ [key: string]: unknown;
39
+ }>;
40
+ /** Array of required property names */
41
+ required?: string[];
42
+ /** Additional JSON Schema keywords */
43
+ [key: string]: unknown;
44
+ }
45
+ /**
46
+ * Zod schema object type for type-safe tool and prompt definitions.
47
+ *
48
+ * When using Zod schemas instead of JSON Schema, define your schema as an object
49
+ * where keys are parameter names and values are Zod type definitions.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * import { z } from 'zod';
54
+ *
55
+ * const mySchema: ZodSchemaObject = {
56
+ * query: z.string().describe('Search query'),
57
+ * limit: z.number().optional().describe('Max results')
58
+ * };
59
+ * ```
60
+ */
61
+ type ZodSchemaObject = Record<string, z.ZodTypeAny>;
62
+ /**
63
+ * Tool response format for the Web Model Context API.
64
+ * This is an alias for MCP SDK's CallToolResult for API consistency.
65
+ * @see {@link CallToolResult}
66
+ */
67
+ type ToolResponse = CallToolResult;
68
+ /**
69
+ * Metadata for tools that trigger page navigation.
70
+ *
71
+ * When a tool needs to navigate the page (e.g., to a different URL), it must include
72
+ * this metadata in its response to signal the navigation intent to the client. This
73
+ * allows the client to distinguish between successful navigation and interrupted execution.
74
+ *
75
+ * **CRITICAL PATTERN**: Tools MUST return their response BEFORE triggering navigation.
76
+ * Use `setTimeout()` with a minimum 100ms delay to ensure the response is transmitted
77
+ * via `postMessage` and received by the client before the page unloads.
78
+ *
79
+ * **Why the pattern is necessary**: During page navigation, the JavaScript context
80
+ * is destroyed. If navigation occurs before the response is sent, the client will
81
+ * never receive the tool's result and cannot distinguish success from failure.
82
+ *
83
+ * @example Correct pattern - Response before navigation
84
+ * ```typescript
85
+ * navigator.modelContext.registerTool({
86
+ * name: 'navigate_to_docs',
87
+ * description: 'Navigate to documentation page',
88
+ * inputSchema: { section: z.string() },
89
+ * async execute(args) {
90
+ * const url = `https://docs.example.com/${args.section}`;
91
+ *
92
+ * // 1. Prepare response with navigation metadata
93
+ * const response = {
94
+ * content: [{ type: 'text', text: `Navigating to ${url}` }],
95
+ * metadata: {
96
+ * willNavigate: true,
97
+ * navigationUrl: url,
98
+ * navigationTiming: 'immediate',
99
+ * },
100
+ * };
101
+ *
102
+ * // 2. Schedule navigation AFTER response is returned (100ms minimum)
103
+ * setTimeout(() => {
104
+ * window.location.href = url;
105
+ * }, 100);
106
+ *
107
+ * // 3. Return response BEFORE navigation occurs
108
+ * return response;
109
+ * },
110
+ * });
111
+ * ```
112
+ *
113
+ * @example Anti-pattern - Navigation before response (DO NOT DO THIS)
114
+ * ```typescript
115
+ * // ❌ WRONG - Response will be lost during navigation
116
+ * async execute(args) {
117
+ * window.location.href = computeUrl(args); // Navigation happens first
118
+ * return { content: [...] }; // This response is never received!
119
+ * }
120
+ * ```
121
+ *
122
+ * @see {@link InterruptionMetadata} for metadata added when navigation interrupts execution
123
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage} for postMessage timing
124
+ */
125
+ interface NavigationMetadata {
126
+ /**
127
+ * Indicates this tool will trigger page navigation.
128
+ * This flag signals to the client that the tool succeeded and navigation is expected.
129
+ */
130
+ willNavigate: true;
131
+ /**
132
+ * The URL the page will navigate to (if known).
133
+ * Helps clients track navigation targets.
134
+ */
135
+ navigationUrl?: string;
136
+ /**
137
+ * When navigation will occur relative to the response.
138
+ * - 'immediate': Navigation scheduled immediately after return (within ~100ms)
139
+ * - 'delayed': Navigation will occur after some delay (see navigationDelayMs)
140
+ * @default 'immediate'
141
+ */
142
+ navigationTiming?: 'immediate' | 'delayed';
143
+ /**
144
+ * Expected delay in milliseconds before navigation (if timing='delayed').
145
+ * Only meaningful when navigationTiming is 'delayed'.
146
+ */
147
+ navigationDelayMs?: number;
148
+ }
149
+ /**
150
+ * Metadata indicating a tool call was interrupted by page navigation.
151
+ *
152
+ * This metadata is automatically added by the transport layer (`TabServerTransport`)
153
+ * when a page navigation occurs while a tool is executing. The transport layer's
154
+ * `beforeunload` event handler detects the navigation and sends an interrupted
155
+ * response for any pending tool calls.
156
+ *
157
+ * **When this occurs**:
158
+ * - User clicks browser back/forward buttons during tool execution
159
+ * - User manually navigates to a different URL
160
+ * - Tool triggers immediate navigation without following the response-first pattern
161
+ * - Page is reloaded or closed during tool execution
162
+ *
163
+ * **How to distinguish from successful navigation**:
164
+ * - Tool succeeded and navigated: Response includes `NavigationMetadata` with `willNavigate: true`
165
+ * - Tool was interrupted: Response includes `InterruptionMetadata` with `navigationInterrupted: true`
166
+ *
167
+ * **Client handling**:
168
+ * ```typescript
169
+ * const response = await client.callTool('my_tool', args);
170
+ *
171
+ * if (response.metadata?.willNavigate) {
172
+ * // Tool succeeded and will navigate - expected behavior
173
+ * console.log('Tool navigated successfully');
174
+ * } else if (response.metadata?.navigationInterrupted) {
175
+ * // Tool was interrupted - may not have completed
176
+ * console.warn('Tool execution interrupted by navigation');
177
+ * } else {
178
+ * // Normal tool response - no navigation
179
+ * console.log('Tool completed normally');
180
+ * }
181
+ * ```
182
+ *
183
+ * @see {@link NavigationMetadata} for metadata indicating intentional navigation
184
+ * @see {@link TabServerTransport._handleBeforeUnload} for the implementation
185
+ * @internal This metadata is added automatically by the transport layer
186
+ */
187
+ interface InterruptionMetadata {
188
+ /**
189
+ * Indicates the tool execution was interrupted by page navigation.
190
+ * When `true`, the tool may not have completed its operation successfully.
191
+ */
192
+ navigationInterrupted: true;
193
+ /**
194
+ * The original JSON-RPC method that was interrupted.
195
+ * Typically `'tools/call'` for tool invocations, but could be other MCP methods.
196
+ *
197
+ * @example 'tools/call' | 'resources/read' | 'prompts/get'
198
+ */
199
+ originalMethod: string;
200
+ /**
201
+ * Unix timestamp (milliseconds since epoch) when the interruption was detected.
202
+ * Useful for logging, debugging, and understanding the timeline of events.
203
+ *
204
+ * @example 1704067200000 (January 1, 2024, 00:00:00 UTC)
205
+ */
206
+ timestamp: number;
207
+ }
208
+ /**
209
+ * Transport configuration for initializing the Web Model Context polyfill.
210
+ *
211
+ * The polyfill supports multiple transport modes:
212
+ * - **Custom transport**: Provide your own MCP transport implementation
213
+ * - **Tab server**: Same-window communication via postMessage
214
+ * - **Iframe server**: Parent-child iframe communication
215
+ *
216
+ * @example Custom transport
217
+ * ```typescript
218
+ * const config: TransportConfiguration = {
219
+ * create: () => new MyCustomTransport()
220
+ * };
221
+ * ```
222
+ *
223
+ * @example Configure allowed origins
224
+ * ```typescript
225
+ * const config: TransportConfiguration = {
226
+ * tabServer: { allowedOrigins: ['https://example.com'] },
227
+ * iframeServer: false // disable iframe server
228
+ * };
229
+ * ```
230
+ */
231
+ interface TransportConfiguration {
232
+ /**
233
+ * Provide a custom transport factory.
234
+ * When set, tabServer and iframeServer options are ignored.
235
+ */
236
+ create?: () => Transport;
237
+ /**
238
+ * Options passed to the built-in TabServerTransport when no custom factory is provided.
239
+ * Set to `false` to disable the tab server.
240
+ * @default { allowedOrigins: ['*'] }
241
+ */
242
+ tabServer?: Partial<TabServerTransportOptions> | false;
243
+ /**
244
+ * Options passed to the built-in IframeChildTransport when no custom factory is provided.
245
+ * Set to `false` to disable the iframe server.
246
+ * @default Auto-enabled when `window.parent !== window`
247
+ */
248
+ iframeServer?: Partial<IframeChildTransportOptions> | false;
249
+ }
250
+ /**
251
+ * Initialization options for the Web Model Context polyfill.
252
+ *
253
+ * @example
254
+ * ```typescript
255
+ * initializeWebModelContext({
256
+ * autoInitialize: true,
257
+ * transport: {
258
+ * tabServer: { allowedOrigins: ['https://trusted.com'] }
259
+ * }
260
+ * });
261
+ * ```
262
+ */
263
+ interface WebModelContextInitOptions {
264
+ /**
265
+ * Configure the transport used to expose the MCP server in the browser.
266
+ */
267
+ transport?: TransportConfiguration;
268
+ /**
269
+ * When set to `false`, automatic initialization on module load is skipped.
270
+ * Useful when you need to configure options before initialization.
271
+ * @default true
272
+ */
273
+ autoInitialize?: boolean;
274
+ }
275
+ /**
276
+ * Tool descriptor for the Web Model Context API.
277
+ *
278
+ * Tools are functions that AI models can call to perform actions or retrieve
279
+ * information. This interface supports both JSON Schema (Web standard) and
280
+ * Zod schemas (type-safe) for input/output validation.
281
+ *
282
+ * @template TInputSchema - Zod schema object type for input type inference
283
+ * @template TOutputSchema - Zod schema object type for output type inference
284
+ *
285
+ * @see {@link https://spec.modelcontextprotocol.io/specification/server/tools/}
286
+ *
287
+ * @example JSON Schema
288
+ * ```typescript
289
+ * const tool: ToolDescriptor = {
290
+ * name: 'search',
291
+ * description: 'Search the web',
292
+ * inputSchema: {
293
+ * type: 'object',
294
+ * properties: { query: { type: 'string' } },
295
+ * required: ['query']
296
+ * },
297
+ * execute: async ({ query }) => ({
298
+ * content: [{ type: 'text', text: `Results for: ${query}` }]
299
+ * })
300
+ * };
301
+ * ```
302
+ *
303
+ * @example Zod Schema (type-safe)
304
+ * ```typescript
305
+ * const tool: ToolDescriptor<{ query: z.ZodString }> = {
306
+ * name: 'search',
307
+ * description: 'Search the web',
308
+ * inputSchema: { query: z.string() },
309
+ * execute: async ({ query }) => ({ // query is typed as string
310
+ * content: [{ type: 'text', text: `Results for: ${query}` }]
311
+ * })
312
+ * };
313
+ * ```
314
+ */
315
+ interface ToolDescriptor<TInputSchema extends ZodSchemaObject = Record<string, never>, TOutputSchema extends ZodSchemaObject = Record<string, never>> {
316
+ /**
317
+ * Unique identifier for the tool
318
+ */
319
+ name: string;
320
+ /**
321
+ * Natural language description of what the tool does
322
+ */
323
+ description: string;
324
+ /**
325
+ * Input schema - accepts EITHER:
326
+ * - JSON Schema object (Web standard): { type: "object", properties: {...}, required: [...] }
327
+ * - Zod schema object (type-safe): { text: z.string(), priority: z.enum(...) }
328
+ *
329
+ * When using Zod, TypeScript will infer the execute parameter types automatically
330
+ */
331
+ inputSchema: InputSchema | TInputSchema;
332
+ /**
333
+ * Optional output schema - accepts EITHER:
334
+ * - JSON Schema object (Web standard): { type: "object", properties: {...} }
335
+ * - Zod schema object (type-safe): { result: z.string(), success: z.boolean() }
336
+ */
337
+ outputSchema?: InputSchema | TOutputSchema;
338
+ /**
339
+ * Optional annotations providing hints about tool behavior
340
+ */
341
+ annotations?: ToolAnnotations;
342
+ /**
343
+ * Function that executes the tool logic
344
+ *
345
+ * When using Zod schemas, the args parameter type is automatically inferred from TInputSchema
346
+ * When using JSON Schema, args is Record<string, unknown>
347
+ */
348
+ execute: (args: TInputSchema extends Record<string, never> ? Record<string, unknown> : z.infer<z.ZodObject<TInputSchema>>) => Promise<ToolResponse>;
349
+ }
350
+ /**
351
+ * Internal validated tool descriptor (used internally by the bridge).
352
+ * Always stores JSON Schema format for MCP protocol compatibility,
353
+ * plus Zod validators for runtime validation.
354
+ * @internal
355
+ */
356
+ interface ValidatedToolDescriptor {
357
+ name: string;
358
+ description: string;
359
+ inputSchema: InputSchema;
360
+ outputSchema?: InputSchema;
361
+ annotations?: ToolAnnotations;
362
+ execute: (args: Record<string, unknown>) => Promise<ToolResponse>;
363
+ /** Zod validator for input arguments (not exposed via MCP) */
364
+ inputValidator: z.ZodType;
365
+ /** Zod validator for output (not exposed via MCP) */
366
+ outputValidator?: z.ZodType;
367
+ }
368
+ /**
369
+ * Resource descriptor for Web Model Context API
370
+ * Defines a resource that can be read by AI models
371
+ *
372
+ * Resources can be:
373
+ * - Static: Fixed URI like "config://app-settings"
374
+ * - Dynamic: URI template like "file://{path}" where {path} is a parameter
375
+ *
376
+ * @example Static resource
377
+ * ```typescript
378
+ * const configResource: ResourceDescriptor = {
379
+ * uri: 'config://app-settings',
380
+ * name: 'App Settings',
381
+ * description: 'Application configuration',
382
+ * mimeType: 'application/json',
383
+ * read: async (uri) => ({
384
+ * contents: [{ uri: uri.href, text: JSON.stringify(config) }]
385
+ * })
386
+ * };
387
+ * ```
388
+ *
389
+ * @example Dynamic resource with URI template
390
+ * ```typescript
391
+ * const fileResource: ResourceDescriptor = {
392
+ * uri: 'file://{path}',
393
+ * name: 'File Reader',
394
+ * description: 'Read files from the virtual filesystem',
395
+ * read: async (uri, params) => ({
396
+ * contents: [{ uri: uri.href, text: await readFile(params?.path ?? '') }]
397
+ * })
398
+ * };
399
+ * ```
400
+ */
401
+ interface ResourceDescriptor {
402
+ /**
403
+ * The resource URI or URI template
404
+ * - Static: "config://app-settings"
405
+ * - Template: "file://{path}" where {path} becomes a parameter
406
+ */
407
+ uri: string;
408
+ /**
409
+ * Human-readable name for the resource
410
+ */
411
+ name: string;
412
+ /**
413
+ * Optional description of what the resource provides
414
+ */
415
+ description?: string;
416
+ /**
417
+ * Optional MIME type of the resource content
418
+ */
419
+ mimeType?: string;
420
+ /**
421
+ * Function that reads and returns the resource content
422
+ *
423
+ * @param uri - The resolved URI being requested
424
+ * @param params - Parameters extracted from URI template (if applicable)
425
+ * @returns Resource contents with the data
426
+ */
427
+ read: (uri: URL, params?: Record<string, string>) => Promise<{
428
+ contents: ResourceContents[];
429
+ }>;
430
+ }
431
+ /**
432
+ * Internal validated resource descriptor (used internally by the bridge).
433
+ * @internal
434
+ */
435
+ interface ValidatedResourceDescriptor {
436
+ uri: string;
437
+ name: string;
438
+ description: string | undefined;
439
+ mimeType: string | undefined;
440
+ read: (uri: URL, params?: Record<string, string>) => Promise<{
441
+ contents: ResourceContents[];
442
+ }>;
443
+ /** Whether this is a URI template (contains {param} placeholders) */
444
+ isTemplate: boolean;
445
+ /** Parameter names extracted from URI template (e.g., ['path'] for 'file://{path}') */
446
+ templateParams: string[];
447
+ }
448
+ /**
449
+ * Prompt descriptor for Web Model Context API
450
+ * Defines a reusable prompt template for AI interactions
451
+ *
452
+ * Prompts help users interact with AI models by providing
453
+ * pre-defined message templates. They can accept arguments
454
+ * to customize the prompt dynamically.
455
+ *
456
+ * @template TArgsSchema - If using Zod, the schema object type for argument inference
457
+ *
458
+ * @example Simple prompt without arguments
459
+ * ```typescript
460
+ * const helpPrompt: PromptDescriptor = {
461
+ * name: 'help',
462
+ * description: 'Get help with using the application',
463
+ * get: async () => ({
464
+ * messages: [{
465
+ * role: 'user',
466
+ * content: { type: 'text', text: 'How do I use this application?' }
467
+ * }]
468
+ * })
469
+ * };
470
+ * ```
471
+ *
472
+ * @example Prompt with typed arguments
473
+ * ```typescript
474
+ * const reviewPrompt: PromptDescriptor<{ code: z.ZodString }> = {
475
+ * name: 'review-code',
476
+ * description: 'Review code for best practices',
477
+ * argsSchema: { code: z.string() },
478
+ * get: async ({ code }) => ({
479
+ * messages: [{
480
+ * role: 'user',
481
+ * content: { type: 'text', text: `Please review this code:\n\n${code}` }
482
+ * }]
483
+ * })
484
+ * };
485
+ * ```
486
+ */
487
+ interface PromptDescriptor<TArgsSchema extends ZodSchemaObject = Record<string, never>> {
488
+ /**
489
+ * Unique identifier for the prompt
490
+ */
491
+ name: string;
492
+ /**
493
+ * Optional description of what the prompt does
494
+ */
495
+ description?: string;
496
+ /**
497
+ * Optional schema for prompt arguments
498
+ * Accepts EITHER:
499
+ * - JSON Schema object: { type: "object", properties: {...} }
500
+ * - Zod schema object: { code: z.string(), language: z.enum([...]) }
501
+ */
502
+ argsSchema?: InputSchema | TArgsSchema;
503
+ /**
504
+ * Function that generates prompt messages
505
+ *
506
+ * @param args - Arguments matching the argsSchema (if defined)
507
+ * @returns Object containing the prompt messages
508
+ */
509
+ get: (args: TArgsSchema extends Record<string, never> ? Record<string, unknown> : z.infer<z.ZodObject<TArgsSchema>>) => Promise<{
510
+ messages: PromptMessage[];
511
+ }>;
512
+ }
513
+ /**
514
+ * Internal validated prompt descriptor (used internally by the bridge).
515
+ * @internal
516
+ */
517
+ interface ValidatedPromptDescriptor {
518
+ name: string;
519
+ description: string | undefined;
520
+ argsSchema: InputSchema | undefined;
521
+ get: (args: Record<string, unknown>) => Promise<{
522
+ messages: PromptMessage[];
523
+ }>;
524
+ /** Zod validator for arguments (not exposed via MCP) */
525
+ argsValidator: z.ZodType | undefined;
526
+ }
527
+ /**
528
+ * Tool information returned by listTools().
529
+ * Provides metadata about a registered tool without exposing the execute function.
530
+ */
531
+ interface ToolListItem {
532
+ /** Unique identifier for the tool */
533
+ name: string;
534
+ /** Natural language description of what the tool does */
535
+ description: string;
536
+ /** JSON Schema for tool input parameters */
537
+ inputSchema: InputSchema;
538
+ /** Optional JSON Schema for tool output */
539
+ outputSchema?: InputSchema;
540
+ /** Optional annotations providing hints about tool behavior */
541
+ annotations?: ToolAnnotations;
542
+ }
543
+ /**
544
+ * Resource template information returned by listResourceTemplates().
545
+ * Describes a dynamic resource with URI template parameters.
546
+ */
547
+ interface ResourceTemplateInfo {
548
+ /** The URI template (e.g., 'file://{path}') */
549
+ uriTemplate: string;
550
+ /** Human-readable name for the resource */
551
+ name: string;
552
+ /** Optional description of what the resource provides */
553
+ description?: string;
554
+ /** Optional MIME type of the resource content */
555
+ mimeType?: string;
556
+ }
557
+ /**
558
+ * Registration handle returned by registerTool, registerResource, registerPrompt.
559
+ * Provides a method to unregister the item.
560
+ */
561
+ interface RegistrationHandle {
562
+ /** Unregister the item, removing it from the context */
563
+ unregister: () => void;
564
+ }
565
+ /**
566
+ * Parameters for a sampling request from the server.
567
+ * Extracted from CreateMessageRequest for handler convenience.
568
+ */
569
+ interface SamplingRequestParams {
570
+ /** Messages to send to the LLM */
571
+ messages: Array<{
572
+ role: 'user' | 'assistant';
573
+ content: {
574
+ type: 'text';
575
+ text: string;
576
+ } | {
577
+ type: 'image';
578
+ data: string;
579
+ mimeType: string;
580
+ } | Array<{
581
+ type: 'text';
582
+ text: string;
583
+ } | {
584
+ type: 'image';
585
+ data: string;
586
+ mimeType: string;
587
+ }>;
588
+ }>;
589
+ /** Optional system prompt */
590
+ systemPrompt?: string | undefined;
591
+ /** Maximum tokens to generate */
592
+ maxTokens: number;
593
+ /** Optional temperature for sampling */
594
+ temperature?: number | undefined;
595
+ /** Optional stop sequences */
596
+ stopSequences?: string[] | undefined;
597
+ /** Optional model preferences */
598
+ modelPreferences?: {
599
+ hints?: Array<{
600
+ name?: string;
601
+ }>;
602
+ costPriority?: number;
603
+ speedPriority?: number;
604
+ intelligencePriority?: number;
605
+ } | undefined;
606
+ /** Optional context inclusion setting */
607
+ includeContext?: 'none' | 'thisServer' | 'allServers' | undefined;
608
+ /** Optional metadata */
609
+ metadata?: Record<string, unknown> | undefined;
610
+ }
611
+ /**
612
+ * Result of a sampling request.
613
+ * Returned by the sampling handler.
614
+ */
615
+ interface SamplingResult {
616
+ /** The model that generated the response */
617
+ model: string;
618
+ /** The generated content */
619
+ content: {
620
+ type: 'text';
621
+ text: string;
622
+ } | {
623
+ type: 'image';
624
+ data: string;
625
+ mimeType: string;
626
+ };
627
+ /** Role of the responder */
628
+ role: 'user' | 'assistant';
629
+ /** Reason for stopping generation */
630
+ stopReason?: 'endTurn' | 'stopSequence' | 'maxTokens' | string;
631
+ }
632
+ /**
633
+ * Parameters for a form elicitation request.
634
+ */
635
+ interface ElicitationFormParams {
636
+ /** Mode of elicitation */
637
+ mode?: 'form';
638
+ /** Message to show to the user */
639
+ message: string;
640
+ /** Schema for the form fields */
641
+ requestedSchema: {
642
+ type: 'object';
643
+ properties: Record<string, {
644
+ type: 'string' | 'number' | 'integer' | 'boolean';
645
+ title?: string;
646
+ description?: string;
647
+ default?: string | number | boolean;
648
+ minLength?: number;
649
+ maxLength?: number;
650
+ minimum?: number;
651
+ maximum?: number;
652
+ enum?: Array<string | number>;
653
+ enumNames?: string[];
654
+ format?: string;
655
+ }>;
656
+ required?: string[];
657
+ };
658
+ }
659
+ /**
660
+ * Parameters for a URL elicitation request.
661
+ */
662
+ interface ElicitationUrlParams {
663
+ /** Mode of elicitation */
664
+ mode: 'url';
665
+ /** Message explaining why the URL needs to be opened */
666
+ message: string;
667
+ /** Unique identifier for this elicitation */
668
+ elicitationId: string;
669
+ /** URL to open */
670
+ url: string;
671
+ }
672
+ /**
673
+ * Parameters for an elicitation request.
674
+ * Can be either form-based or URL-based.
675
+ */
676
+ type ElicitationParams = ElicitationFormParams | ElicitationUrlParams;
677
+ /**
678
+ * Result of an elicitation request.
679
+ */
680
+ interface ElicitationResult {
681
+ /** User action */
682
+ action: 'accept' | 'decline' | 'cancel';
683
+ /** Content returned when action is 'accept' */
684
+ content?: Record<string, string | number | boolean | string[]>;
685
+ }
686
+ /**
687
+ * Context provided to models via provideContext().
688
+ * Contains the base set of tools, resources, and prompts (Bucket A).
689
+ */
690
+ interface ModelContextInput {
691
+ /**
692
+ * Array of tool descriptors
693
+ * Supports both JSON Schema and Zod schema formats
694
+ */
695
+ tools?: ToolDescriptor[];
696
+ /**
697
+ * Array of resource descriptors
698
+ * Resources expose data that AI models can read
699
+ */
700
+ resources?: ResourceDescriptor[];
701
+ /**
702
+ * Array of prompt descriptors
703
+ * Prompts provide reusable message templates
704
+ */
705
+ prompts?: PromptDescriptor[];
706
+ }
707
+ /**
708
+ * Tool call event
709
+ */
710
+ interface ToolCallEvent extends Event {
711
+ /**
712
+ * Name of the tool being called
713
+ */
714
+ name: string;
715
+ /**
716
+ * Arguments passed to the tool
717
+ */
718
+ arguments: Record<string, unknown>;
719
+ /**
720
+ * Respond with a result
721
+ */
722
+ respondWith: (response: ToolResponse) => void;
723
+ }
724
+ /**
725
+ * ModelContext interface on window.navigator
726
+ * Implements the W3C Web Model Context API proposal
727
+ */
728
+ interface ModelContext {
729
+ /**
730
+ * Provide context (tools, resources, prompts) to AI models
731
+ * Clears base items (Bucket A) and replaces with the provided arrays.
732
+ * Dynamic items (Bucket B) registered via register* methods persist.
733
+ */
734
+ provideContext(context: ModelContextInput): void;
735
+ /**
736
+ * Register a single tool dynamically.
737
+ * Returns a handle to unregister the tool.
738
+ * Supports both JSON Schema and Zod schema formats.
739
+ */
740
+ registerTool<TInputSchema extends ZodSchemaObject = Record<string, never>, TOutputSchema extends ZodSchemaObject = Record<string, never>>(tool: ToolDescriptor<TInputSchema, TOutputSchema>): RegistrationHandle;
741
+ /**
742
+ * Unregister a tool by name
743
+ * Available in Chromium's native implementation
744
+ */
745
+ unregisterTool(name: string): void;
746
+ /**
747
+ * Get the list of all registered tools.
748
+ * Returns tools from both buckets (provideContext and registerTool).
749
+ */
750
+ listTools(): ToolListItem[];
751
+ /**
752
+ * Register a single resource dynamically.
753
+ * Returns a handle to unregister the resource.
754
+ */
755
+ registerResource(resource: ResourceDescriptor): RegistrationHandle;
756
+ /**
757
+ * Unregister a resource by URI
758
+ */
759
+ unregisterResource(uri: string): void;
760
+ /**
761
+ * Get the list of all registered resources
762
+ * Returns resources from both buckets (provideContext and registerResource)
763
+ */
764
+ listResources(): Resource[];
765
+ /**
766
+ * Get the list of all resource templates.
767
+ * Returns only resources with URI templates (dynamic resources).
768
+ */
769
+ listResourceTemplates(): ResourceTemplateInfo[];
770
+ /**
771
+ * Register a single prompt dynamically.
772
+ * Returns a handle to unregister the prompt.
773
+ * Supports both JSON Schema and Zod schema formats for argsSchema.
774
+ */
775
+ registerPrompt<TArgsSchema extends ZodSchemaObject = Record<string, never>>(prompt: PromptDescriptor<TArgsSchema>): RegistrationHandle;
776
+ /**
777
+ * Unregister a prompt by name
778
+ */
779
+ unregisterPrompt(name: string): void;
780
+ /**
781
+ * Get the list of all registered prompts
782
+ * Returns prompts from both buckets (provideContext and registerPrompt)
783
+ */
784
+ listPrompts(): Prompt[];
785
+ /**
786
+ * Clear all registered context (tools, resources, prompts from both buckets)
787
+ * Available in Chromium's native implementation
788
+ */
789
+ clearContext(): void;
790
+ /**
791
+ * Request an LLM completion from the connected client.
792
+ * This allows the server (webpage) to request sampling from the client (AI agent).
793
+ *
794
+ * @param params - Parameters for the sampling request
795
+ * @returns Promise resolving to the LLM completion result
796
+ *
797
+ * @example
798
+ * ```typescript
799
+ * const result = await navigator.modelContext.createMessage({
800
+ * messages: [
801
+ * { role: 'user', content: { type: 'text', text: 'What is 2+2?' } }
802
+ * ],
803
+ * maxTokens: 100,
804
+ * });
805
+ * console.log(result.content); // { type: 'text', text: '4' }
806
+ * ```
807
+ */
808
+ createMessage(params: SamplingRequestParams): Promise<SamplingResult>;
809
+ /**
810
+ * Request user input from the connected client.
811
+ * This allows the server (webpage) to request form data or URL navigation from the client.
812
+ *
813
+ * @param params - Parameters for the elicitation request
814
+ * @returns Promise resolving to the user's response
815
+ *
816
+ * @example Form elicitation:
817
+ * ```typescript
818
+ * const result = await navigator.modelContext.elicitInput({
819
+ * message: 'Please provide your API key',
820
+ * requestedSchema: {
821
+ * type: 'object',
822
+ * properties: {
823
+ * apiKey: { type: 'string', title: 'API Key', description: 'Your API key' }
824
+ * },
825
+ * required: ['apiKey']
826
+ * }
827
+ * });
828
+ * if (result.action === 'accept') {
829
+ * console.log(result.content?.apiKey);
830
+ * }
831
+ * ```
832
+ */
833
+ elicitInput(params: ElicitationParams): Promise<ElicitationResult>;
834
+ /**
835
+ * Add event listener for tool calls
836
+ */
837
+ addEventListener(type: 'toolcall', listener: (event: ToolCallEvent) => void | Promise<void>, options?: boolean | AddEventListenerOptions): void;
838
+ /**
839
+ * Remove event listener
840
+ */
841
+ removeEventListener(type: 'toolcall', listener: (event: ToolCallEvent) => void | Promise<void>, options?: boolean | EventListenerOptions): void;
842
+ /**
843
+ * Dispatch an event
844
+ */
845
+ dispatchEvent(event: Event): boolean;
846
+ }
847
+ /**
848
+ * Internal ModelContext interface with additional methods for MCP bridge.
849
+ * Not exposed as part of the public Web Model Context API.
850
+ * @internal
851
+ */
852
+ interface InternalModelContext extends ModelContext {
853
+ /**
854
+ * Execute a tool (internal use only by MCP bridge)
855
+ * @internal
856
+ */
857
+ executeTool(toolName: string, args: Record<string, unknown>): Promise<ToolResponse>;
858
+ /**
859
+ * Read a resource by URI (internal use only by MCP bridge)
860
+ * @internal
861
+ */
862
+ readResource(uri: string): Promise<{
863
+ contents: ResourceContents[];
864
+ }>;
865
+ /**
866
+ * Get a prompt with arguments (internal use only by MCP bridge)
867
+ * @internal
868
+ */
869
+ getPrompt(name: string, args?: Record<string, unknown>): Promise<{
870
+ messages: PromptMessage[];
871
+ }>;
872
+ }
873
+ /**
874
+ * Internal MCP Bridge state.
875
+ * Contains the MCP servers and registered context items.
876
+ * @internal
877
+ */
878
+ interface MCPBridge {
879
+ /** The main tab server transport */
880
+ tabServer: Server;
881
+ /** Optional iframe server transport */
882
+ iframeServer?: Server;
883
+ /** Map of tool name -> validated tool descriptor */
884
+ tools: Map<string, ValidatedToolDescriptor>;
885
+ /** Map of resource URI -> validated resource descriptor */
886
+ resources: Map<string, ValidatedResourceDescriptor>;
887
+ /** Map of prompt name -> validated prompt descriptor */
888
+ prompts: Map<string, ValidatedPromptDescriptor>;
889
+ /** The internal model context instance */
890
+ modelContext: InternalModelContext;
891
+ /** Optional testing API instance */
892
+ modelContextTesting?: ModelContextTesting;
893
+ /** Whether the bridge has been initialized */
894
+ isInitialized: boolean;
895
+ }
896
+ /**
897
+ * Tool info returned by listTools() in the testing API.
898
+ * Note: inputSchema is a JSON string, not an object (matches Chromium implementation).
899
+ */
900
+ interface ToolInfo {
901
+ name: string;
902
+ description: string;
903
+ inputSchema: string;
904
+ }
905
+ /**
906
+ * Testing API for Model Context
907
+ *
908
+ * **Native Support**: This API is available natively in Chromium-based browsers
909
+ * when the experimental "Model Context Testing" feature flag is enabled.
910
+ *
911
+ * **How to enable in Chromium**:
912
+ * - Navigate to `chrome://flags`
913
+ * - Search for "experimental web platform features" or "model context"
914
+ * - Enable the feature and restart the browser
915
+ * - Or launch with: `--enable-experimental-web-platform-features`
916
+ *
917
+ * **Polyfill**: If the native API is not available, this polyfill provides
918
+ * a compatible implementation for testing purposes.
919
+ */
920
+ interface ModelContextTesting {
921
+ /**
922
+ * Execute a tool directly with JSON string input (Chromium native API)
923
+ * @param toolName - Name of the tool to execute
924
+ * @param inputArgsJson - JSON string of input arguments
925
+ * @returns Promise resolving to the tool's result
926
+ */
927
+ executeTool(toolName: string, inputArgsJson: string): Promise<unknown>;
928
+ /**
929
+ * List all registered tools (Chromium native API)
930
+ * Returns tools with inputSchema as JSON string
931
+ */
932
+ listTools(): ToolInfo[];
933
+ /**
934
+ * Register a callback that fires when the tools list changes (Chromium native API)
935
+ * Callback will fire on: registerTool, unregisterTool, provideContext, clearContext
936
+ */
937
+ registerToolsChangedCallback(callback: () => void): void;
938
+ /**
939
+ * Get all tool calls that have been made (for testing/debugging)
940
+ * Polyfill-specific extension
941
+ */
942
+ getToolCalls(): Array<{
943
+ toolName: string;
944
+ arguments: Record<string, unknown>;
945
+ timestamp: number;
946
+ }>;
947
+ /**
948
+ * Clear the history of tool calls
949
+ * Polyfill-specific extension
950
+ */
951
+ clearToolCalls(): void;
952
+ /**
953
+ * Set a mock response for a specific tool (for testing)
954
+ * When set, the tool's execute function will be bypassed and the mock response returned
955
+ * Polyfill-specific extension
956
+ */
957
+ setMockToolResponse(toolName: string, response: ToolResponse): void;
958
+ /**
959
+ * Clear mock response for a specific tool
960
+ * Polyfill-specific extension
961
+ */
962
+ clearMockToolResponse(toolName: string): void;
963
+ /**
964
+ * Clear all mock tool responses
965
+ * Polyfill-specific extension
966
+ */
967
+ clearAllMockToolResponses(): void;
968
+ /**
969
+ * Get the current tools registered in the system
970
+ * (same as modelContext.listTools but explicitly for testing)
971
+ * Polyfill-specific extension
972
+ */
973
+ getRegisteredTools(): ReturnType<ModelContext['listTools']>;
974
+ /**
975
+ * Reset the entire testing state (clears tool calls and mock responses)
976
+ * Polyfill-specific extension
977
+ */
978
+ reset(): void;
979
+ }
980
+ declare global {
981
+ interface Navigator {
982
+ /**
983
+ * Web Model Context API
984
+ * Provides tools and context to AI agents
985
+ */
986
+ modelContext: ModelContext;
987
+ /**
988
+ * Model Context Testing API
989
+ *
990
+ * **IMPORTANT**: This API is only available in Chromium-based browsers
991
+ * with the experimental feature flag enabled:
992
+ * - `chrome://flags` → "Experimental Web Platform Features"
993
+ * - Or launch with: `--enable-experimental-web-platform-features`
994
+ *
995
+ * If not available natively, the @mcp-b/global polyfill provides
996
+ * a compatible implementation.
997
+ */
998
+ modelContextTesting?: ModelContextTesting;
999
+ }
1000
+ interface Window {
1001
+ /**
1002
+ * Internal MCP server instance (for debugging/advanced use)
1003
+ */
1004
+ __mcpBridge?: MCPBridge;
1005
+ }
1006
+ }
1007
+ //# sourceMappingURL=types.d.ts.map
1008
+ //#endregion
1009
+ //#region src/global.d.ts
1010
+ declare global {
1011
+ interface Window {
1012
+ __webModelContextOptions?: WebModelContextInitOptions;
1013
+ }
1014
+ }
1015
+ /**
1016
+ * Initializes the Web Model Context API on window.navigator.
1017
+ * Creates and exposes navigator.modelContext and navigator.modelContextTesting.
1018
+ * Automatically detects and uses native Chromium implementation if available.
1019
+ *
1020
+ * @param {WebModelContextInitOptions} [options] - Configuration options
1021
+ * @throws {Error} If initialization fails
1022
+ * @example
1023
+ * ```typescript
1024
+ * import { initializeWebModelContext } from '@mcp-b/global';
1025
+ *
1026
+ * initializeWebModelContext({
1027
+ * transport: {
1028
+ * tabServer: {
1029
+ * allowedOrigins: ['https://example.com']
1030
+ * }
1031
+ * }
1032
+ * });
1033
+ * ```
1034
+ */
1035
+ declare function initializeWebModelContext(options?: WebModelContextInitOptions): void;
1036
+ /**
1037
+ * Cleans up the Web Model Context API.
1038
+ * Closes all MCP servers and removes API from window.navigator.
1039
+ * Useful for testing and hot module replacement.
1040
+ *
1041
+ * @example
1042
+ * ```typescript
1043
+ * import { cleanupWebModelContext } from '@mcp-b/global';
1044
+ *
1045
+ * cleanupWebModelContext();
1046
+ * ```
1047
+ */
1048
+ declare function cleanupWebModelContext(): void;
1049
+ //#endregion
1050
+ //#region src/validation.d.ts
1051
+ /**
1052
+ * Convert Zod schema object to JSON Schema
1053
+ * Uses zod-to-json-schema package for comprehensive conversion
1054
+ *
1055
+ * @param schema - Record of Zod type definitions (e.g., { name: z.string(), age: z.number() })
1056
+ * @returns JSON Schema object compatible with MCP InputSchema
1057
+ */
1058
+ declare function zodToJsonSchema(schema: Record<string, z.ZodTypeAny>): InputSchema;
1059
+ //#endregion
1060
+ export { type CallToolResult, type CreateMessageRequest, type CreateMessageResult, type ElicitRequest, type ElicitResult, ElicitationFormParams, ElicitationParams, ElicitationResult, ElicitationUrlParams, InputSchema, InternalModelContext, InterruptionMetadata, MCPBridge, ModelContext, ModelContextInput, ModelContextTesting, NavigationMetadata, type Prompt, PromptDescriptor, type PromptMessage, RegistrationHandle, type Resource, type ResourceContents, ResourceDescriptor, type ResourceTemplate, ResourceTemplateInfo, SamplingRequestParams, SamplingResult, type ToolAnnotations, ToolCallEvent, ToolDescriptor, ToolInfo, ToolListItem, ToolResponse, TransportConfiguration, ValidatedPromptDescriptor, ValidatedResourceDescriptor, ValidatedToolDescriptor, WebModelContextInitOptions, ZodSchemaObject, cleanupWebModelContext, initializeWebModelContext, zodToJsonSchema };
1061
+ //# sourceMappingURL=index.d.ts.map