@mcp-b/global 1.0.15 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +486 -0
- package/dist/index.d.ts +189 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.iife.js +4 -4
- package/dist/index.js +848 -79
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -103,6 +103,263 @@ window.navigator.modelContext.provideContext({
|
|
|
103
103
|
});
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
+
## ⚙️ Configuration
|
|
107
|
+
|
|
108
|
+
The polyfill exposes `initializeWebModelContext(options?: WebModelContextInitOptions)` to let you control transport behaviour. When you import `@mcp-b/global` as a module it auto-initializes by default, but you can customise or defer initialization:
|
|
109
|
+
|
|
110
|
+
- **Disable auto init**: Set `window.__webModelContextOptions = { autoInitialize: false }` before importing, then call `initializeWebModelContext()` manually.
|
|
111
|
+
- **Configure via script tag**: When using the IIFE build, pass options through data attributes:
|
|
112
|
+
```html
|
|
113
|
+
<script
|
|
114
|
+
src="https://unpkg.com/@mcp-b/global@latest/dist/index.iife.js"
|
|
115
|
+
data-webmcp-auto-initialize="false"
|
|
116
|
+
data-webmcp-allowed-origins="https://example.com,https://docs.example.com"
|
|
117
|
+
></script>
|
|
118
|
+
<!-- Later in the page -->
|
|
119
|
+
<script>
|
|
120
|
+
window.navigator.modelContext.provideContext({ tools: [] });
|
|
121
|
+
</script>
|
|
122
|
+
```
|
|
123
|
+
Use `data-webmcp-options='{"transport":{"tabServer":{"allowedOrigins":["https://example.com"]}}}'` for advanced JSON configuration.
|
|
124
|
+
- **Supported data attributes**
|
|
125
|
+
- `data-webmcp-auto-initialize="false"`: Skip automatic setup.
|
|
126
|
+
- `data-webmcp-allowed-origins="https://a.com,https://b.com"`: Override `tabServer.allowedOrigins`.
|
|
127
|
+
- `data-webmcp-channel-id="custom-channel"`: Set the Tab transport channel.
|
|
128
|
+
|
|
129
|
+
### Dual-Server Mode (Tab + Iframe)
|
|
130
|
+
|
|
131
|
+
By default, the global package runs **two MCP servers** that share the same tool registry:
|
|
132
|
+
|
|
133
|
+
1. **Tab Server** (`TabServerTransport`) - For same-window communication
|
|
134
|
+
2. **Iframe Server** (`IframeChildTransport`) - Auto-enabled when running in an iframe (when `window.parent !== window`)
|
|
135
|
+
|
|
136
|
+
Both servers expose the same tools (Bucket A + Bucket B), allowing your tools to be accessed from:
|
|
137
|
+
- Same-window clients (e.g., browser extension content scripts)
|
|
138
|
+
- Parent page (when running in an iframe)
|
|
139
|
+
|
|
140
|
+
**Example: Running in an Iframe**
|
|
141
|
+
|
|
142
|
+
When your app runs in an iframe, both servers are automatically enabled:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
// In iframe: Auto-initializes with both servers
|
|
146
|
+
import '@mcp-b/global';
|
|
147
|
+
|
|
148
|
+
// Register tools - they're automatically available to:
|
|
149
|
+
// 1. Same-window clients (via TabServerTransport)
|
|
150
|
+
// 2. Parent page (via IframeChildTransport)
|
|
151
|
+
window.navigator.modelContext.provideContext({
|
|
152
|
+
tools: [
|
|
153
|
+
{
|
|
154
|
+
name: "iframe-action",
|
|
155
|
+
description: "Action from iframe",
|
|
156
|
+
inputSchema: { type: "object", properties: {} },
|
|
157
|
+
async execute() {
|
|
158
|
+
return {
|
|
159
|
+
content: [{ type: "text", text: "Hello from iframe!" }]
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
});
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Configure Iframe Server**
|
|
168
|
+
|
|
169
|
+
You can customize or disable the iframe server:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { initializeWebModelContext } from '@mcp-b/global';
|
|
173
|
+
|
|
174
|
+
// Customize iframe server
|
|
175
|
+
initializeWebModelContext({
|
|
176
|
+
transport: {
|
|
177
|
+
iframeServer: {
|
|
178
|
+
allowedOrigins: ['https://parent-app.com'], // Only allow specific parent
|
|
179
|
+
channelId: 'custom-iframe-channel',
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Disable iframe server (only Tab server runs)
|
|
185
|
+
initializeWebModelContext({
|
|
186
|
+
transport: {
|
|
187
|
+
iframeServer: false, // Disable iframe server
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Disable tab server (only Iframe server runs)
|
|
192
|
+
initializeWebModelContext({
|
|
193
|
+
transport: {
|
|
194
|
+
tabServer: false, // Disable tab server
|
|
195
|
+
iframeServer: {
|
|
196
|
+
allowedOrigins: ['https://parent-app.com'],
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Custom Transport Factory**
|
|
203
|
+
|
|
204
|
+
Provide `transport.create` to supply any MCP `Transport` implementation instead of the built-in dual-server mode:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
import { initializeWebModelContext } from '@mcp-b/global';
|
|
208
|
+
import { CustomTransport } from './my-transport';
|
|
209
|
+
|
|
210
|
+
initializeWebModelContext({
|
|
211
|
+
transport: {
|
|
212
|
+
create: () => new CustomTransport(),
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
## 🔄 Native Chromium API Support
|
|
218
|
+
|
|
219
|
+
This package **automatically detects and integrates** with Chromium's native Web Model Context API when available. No configuration needed - it just works!
|
|
220
|
+
|
|
221
|
+
### Automatic Detection & Integration
|
|
222
|
+
|
|
223
|
+
When you call `initializeWebModelContext()` (or when auto-initialization runs):
|
|
224
|
+
|
|
225
|
+
1. **Native API detected** (both `navigator.modelContext` and `navigator.modelContextTesting` present):
|
|
226
|
+
- Uses native Chromium implementation
|
|
227
|
+
- Creates MCP bridge and syncs tools automatically
|
|
228
|
+
- Registers callback to listen for native tool changes
|
|
229
|
+
- MCP clients stay synchronized with native tool registry
|
|
230
|
+
|
|
231
|
+
2. **No native API detected**:
|
|
232
|
+
- Installs full polyfill implementation
|
|
233
|
+
- Provides identical API surface
|
|
234
|
+
|
|
235
|
+
**Zero configuration required** - the package automatically adapts to your environment!
|
|
236
|
+
|
|
237
|
+
### Native API Features
|
|
238
|
+
|
|
239
|
+
When the native Chromium API is available, you get:
|
|
240
|
+
|
|
241
|
+
- ✅ **Automatic tool synchronization** - Tools registered in native API are synced to MCP bridge via `registerToolsChangedCallback()`
|
|
242
|
+
- ✅ **Iframe tool collection** - Native API automatically collects tools from embedded iframes (no manual transport setup needed)
|
|
243
|
+
- ✅ **MCP compatibility** - Your MCP clients (extensions, apps) continue to work seamlessly
|
|
244
|
+
- ✅ **Tool change notifications** - MCP servers receive `tools/list_changed` notifications automatically
|
|
245
|
+
- ✅ **Consistent API** - Same code works with both native and polyfill implementations
|
|
246
|
+
|
|
247
|
+
### How Tool Synchronization Works
|
|
248
|
+
|
|
249
|
+
The polyfill automatically registers a callback with the native API:
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
// Happens automatically when native API is detected
|
|
253
|
+
navigator.modelContextTesting.registerToolsChangedCallback(() => {
|
|
254
|
+
// Syncs native tools → MCP bridge
|
|
255
|
+
// MCP clients receive tools/list_changed notification
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
This callback fires when:
|
|
260
|
+
- `navigator.modelContext.registerTool()` is called
|
|
261
|
+
- `navigator.modelContext.unregisterTool()` is called
|
|
262
|
+
- `navigator.modelContext.provideContext()` is called
|
|
263
|
+
- `navigator.modelContext.clearContext()` is called
|
|
264
|
+
- Tools are added from embedded iframes (native feature)
|
|
265
|
+
|
|
266
|
+
### Enabling Native API in Chromium
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# Method 1: Launch with flag
|
|
270
|
+
chromium --enable-experimental-web-platform-features
|
|
271
|
+
|
|
272
|
+
# Method 2: Enable in chrome://flags
|
|
273
|
+
# Search for: "Experimental Web Platform Features"
|
|
274
|
+
# Set to: Enabled
|
|
275
|
+
# Restart browser
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Example: Using Native API
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import '@mcp-b/global';
|
|
282
|
+
|
|
283
|
+
// If native API is present, this delegates to navigator.modelContext:
|
|
284
|
+
window.navigator.modelContext.registerTool({
|
|
285
|
+
name: 'myTool',
|
|
286
|
+
description: 'My tool',
|
|
287
|
+
inputSchema: { type: 'object', properties: {} },
|
|
288
|
+
async execute() {
|
|
289
|
+
return { content: [{ type: 'text', text: 'Hello!' }] };
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
// Behind the scenes:
|
|
294
|
+
// 1. Tool registered in native Chromium registry
|
|
295
|
+
// 2. Callback fires (registerToolsChangedCallback)
|
|
296
|
+
// 3. Tool synced to MCP bridge
|
|
297
|
+
// 4. MCP clients notified (tools/list_changed)
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Iframe Tool Collection (Native Only)
|
|
301
|
+
|
|
302
|
+
When the native API is active, tools from embedded iframes are **automatically collected**:
|
|
303
|
+
|
|
304
|
+
```html
|
|
305
|
+
<!-- parent.html -->
|
|
306
|
+
<script type="module">
|
|
307
|
+
import '@mcp-b/global';
|
|
308
|
+
|
|
309
|
+
// Native API will collect tools from this page AND all iframes
|
|
310
|
+
navigator.modelContext.registerTool({
|
|
311
|
+
name: 'parent-tool',
|
|
312
|
+
description: 'Tool from parent page',
|
|
313
|
+
inputSchema: { type: 'object', properties: {} },
|
|
314
|
+
async execute() {
|
|
315
|
+
return { content: [{ type: 'text', text: 'Parent tool' }] };
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
</script>
|
|
319
|
+
|
|
320
|
+
<iframe src="child.html"></iframe>
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
```html
|
|
324
|
+
<!-- child.html -->
|
|
325
|
+
<script type="module">
|
|
326
|
+
import '@mcp-b/global';
|
|
327
|
+
|
|
328
|
+
// This tool is automatically visible in parent's registry (native feature)
|
|
329
|
+
navigator.modelContext.registerTool({
|
|
330
|
+
name: 'child-tool',
|
|
331
|
+
description: 'Tool from iframe',
|
|
332
|
+
inputSchema: { type: 'object', properties: {} },
|
|
333
|
+
async execute() {
|
|
334
|
+
return { content: [{ type: 'text', text: 'Child tool' }] };
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
</script>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
With native API, `navigator.modelContextTesting.listTools()` in the parent will show **both** tools! The MCP bridge stays in sync automatically.
|
|
341
|
+
|
|
342
|
+
### Detection in Console
|
|
343
|
+
|
|
344
|
+
When you initialize the package, check the console logs:
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
✅ [Web Model Context] Native Chromium API detected
|
|
348
|
+
Using native implementation with MCP bridge synchronization
|
|
349
|
+
Native API will automatically collect tools from embedded iframes
|
|
350
|
+
✅ [Web Model Context] MCP bridge synced with native API
|
|
351
|
+
MCP clients will receive automatic tool updates from native registry
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Or if polyfill is used:
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
[Web Model Context] Native API not detected, installing polyfill
|
|
358
|
+
✅ [Web Model Context] window.navigator.modelContext initialized successfully
|
|
359
|
+
[Model Context Testing] Installing polyfill
|
|
360
|
+
✅ [Model Context Testing] Polyfill installed at window.navigator.modelContextTesting
|
|
361
|
+
```
|
|
362
|
+
|
|
106
363
|
## 📖 API Reference
|
|
107
364
|
|
|
108
365
|
### Two-Bucket Tool Management System
|
|
@@ -577,9 +834,238 @@ if (window.__mcpBridge) {
|
|
|
577
834
|
}
|
|
578
835
|
```
|
|
579
836
|
|
|
837
|
+
## 🧪 Testing API (`navigator.modelContextTesting`)
|
|
838
|
+
|
|
839
|
+
This package provides a **Model Context Testing API** at `window.navigator.modelContextTesting` for debugging and testing your tools during development.
|
|
840
|
+
|
|
841
|
+
### Native Support in Chromium
|
|
842
|
+
|
|
843
|
+
**IMPORTANT**: The `modelContextTesting` API is available natively in Chromium-based browsers when the experimental feature flag is enabled. This polyfill will detect and use the native implementation when available.
|
|
844
|
+
|
|
845
|
+
#### How to Enable Native API in Chromium:
|
|
846
|
+
|
|
847
|
+
**Option 1: Chrome Flags**
|
|
848
|
+
1. Navigate to `chrome://flags`
|
|
849
|
+
2. Search for "Experimental Web Platform Features"
|
|
850
|
+
3. Enable the flag
|
|
851
|
+
4. Restart your browser
|
|
852
|
+
|
|
853
|
+
**Option 2: Command Line**
|
|
854
|
+
```bash
|
|
855
|
+
# Launch Chrome/Edge with experimental features
|
|
856
|
+
chrome --enable-experimental-web-platform-features
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
**Detection**: When the native API is detected, you'll see this console message:
|
|
860
|
+
```
|
|
861
|
+
✅ [Model Context Testing] Native implementation detected (Chromium experimental feature)
|
|
862
|
+
Using native window.navigator.modelContextTesting from browser
|
|
863
|
+
```
|
|
864
|
+
|
|
865
|
+
### Polyfill Fallback
|
|
866
|
+
|
|
867
|
+
If the native API is not available, this package automatically provides a polyfill implementation with the same interface:
|
|
868
|
+
|
|
869
|
+
```
|
|
870
|
+
[Model Context Testing] Native implementation not found, installing polyfill
|
|
871
|
+
💡 To use the native implementation in Chromium:
|
|
872
|
+
- Navigate to chrome://flags
|
|
873
|
+
- Enable "Experimental Web Platform Features"
|
|
874
|
+
- Or launch with: --enable-experimental-web-platform-features
|
|
875
|
+
✅ [Model Context Testing] Polyfill installed at window.navigator.modelContextTesting
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
### API Reference
|
|
879
|
+
|
|
880
|
+
#### `getToolCalls(): Array<ToolCall>`
|
|
881
|
+
|
|
882
|
+
Get a history of all tool calls made during the session.
|
|
883
|
+
|
|
884
|
+
```javascript
|
|
885
|
+
// Register and call some tools
|
|
886
|
+
window.navigator.modelContext.provideContext({
|
|
887
|
+
tools: [{
|
|
888
|
+
name: "greet",
|
|
889
|
+
description: "Greet a user",
|
|
890
|
+
inputSchema: {
|
|
891
|
+
type: "object",
|
|
892
|
+
properties: { name: { type: "string" } },
|
|
893
|
+
required: ["name"]
|
|
894
|
+
},
|
|
895
|
+
async execute({ name }) {
|
|
896
|
+
return { content: [{ type: "text", text: `Hello, ${name}!` }] };
|
|
897
|
+
}
|
|
898
|
+
}]
|
|
899
|
+
});
|
|
900
|
+
|
|
901
|
+
// Simulate a tool call
|
|
902
|
+
// (In practice, this would come from an AI agent)
|
|
903
|
+
|
|
904
|
+
// Later, inspect the tool call history
|
|
905
|
+
const calls = window.navigator.modelContextTesting.getToolCalls();
|
|
906
|
+
console.log(calls);
|
|
907
|
+
// [
|
|
908
|
+
// {
|
|
909
|
+
// toolName: "greet",
|
|
910
|
+
// arguments: { name: "Alice" },
|
|
911
|
+
// timestamp: 1699123456789
|
|
912
|
+
// }
|
|
913
|
+
// ]
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
#### `clearToolCalls(): void`
|
|
917
|
+
|
|
918
|
+
Clear the tool call history.
|
|
919
|
+
|
|
920
|
+
```javascript
|
|
921
|
+
window.navigator.modelContextTesting.clearToolCalls();
|
|
922
|
+
console.log(window.navigator.modelContextTesting.getToolCalls()); // []
|
|
923
|
+
```
|
|
924
|
+
|
|
925
|
+
#### `setMockToolResponse(toolName: string, response: ToolResponse): void`
|
|
926
|
+
|
|
927
|
+
Set a mock response for a specific tool. When set, the tool's `execute()` function will be bypassed and the mock response will be returned instead.
|
|
928
|
+
|
|
929
|
+
```javascript
|
|
930
|
+
// Mock the "greet" tool to always return a specific response
|
|
931
|
+
window.navigator.modelContextTesting.setMockToolResponse("greet", {
|
|
932
|
+
content: [{
|
|
933
|
+
type: "text",
|
|
934
|
+
text: "Mocked greeting!"
|
|
935
|
+
}]
|
|
936
|
+
});
|
|
937
|
+
|
|
938
|
+
// Now when the tool is called, it returns the mock response
|
|
939
|
+
// (The execute function is never called)
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
#### `clearMockToolResponse(toolName: string): void`
|
|
943
|
+
|
|
944
|
+
Remove the mock response for a specific tool.
|
|
945
|
+
|
|
946
|
+
```javascript
|
|
947
|
+
window.navigator.modelContextTesting.clearMockToolResponse("greet");
|
|
948
|
+
// Tool will now use its actual execute function
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
#### `clearAllMockToolResponses(): void`
|
|
952
|
+
|
|
953
|
+
Remove all mock tool responses.
|
|
954
|
+
|
|
955
|
+
```javascript
|
|
956
|
+
window.navigator.modelContextTesting.clearAllMockToolResponses();
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
#### `getRegisteredTools(): Array<ToolDescriptor>`
|
|
960
|
+
|
|
961
|
+
Get the list of all currently registered tools (same as `modelContext.listTools()`).
|
|
962
|
+
|
|
963
|
+
```javascript
|
|
964
|
+
const tools = window.navigator.modelContextTesting.getRegisteredTools();
|
|
965
|
+
console.log(tools.map(t => t.name)); // ["greet", "add-todo", ...]
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
#### `reset(): void`
|
|
969
|
+
|
|
970
|
+
Reset the entire testing state (clears tool call history and all mock responses).
|
|
971
|
+
|
|
972
|
+
```javascript
|
|
973
|
+
window.navigator.modelContextTesting.reset();
|
|
974
|
+
```
|
|
975
|
+
|
|
976
|
+
### Testing Workflow Example
|
|
977
|
+
|
|
978
|
+
Here's a complete example of using the testing API:
|
|
979
|
+
|
|
980
|
+
```javascript
|
|
981
|
+
// 1. Register your tools
|
|
982
|
+
window.navigator.modelContext.provideContext({
|
|
983
|
+
tools: [
|
|
984
|
+
{
|
|
985
|
+
name: "add-todo",
|
|
986
|
+
description: "Add a todo item",
|
|
987
|
+
inputSchema: {
|
|
988
|
+
type: "object",
|
|
989
|
+
properties: { text: { type: "string" } },
|
|
990
|
+
required: ["text"]
|
|
991
|
+
},
|
|
992
|
+
async execute({ text }) {
|
|
993
|
+
// This would normally add to your app state
|
|
994
|
+
return { content: [{ type: "text", text: `Added: ${text}` }] };
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
]
|
|
998
|
+
});
|
|
999
|
+
|
|
1000
|
+
// 2. Set up mocks for testing
|
|
1001
|
+
window.navigator.modelContextTesting.setMockToolResponse("add-todo", {
|
|
1002
|
+
content: [{ type: "text", text: "Mock: Todo added successfully" }]
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
// 3. Simulate tool calls (or let AI agent call them)
|
|
1006
|
+
// The tool will return the mock response instead of executing
|
|
1007
|
+
|
|
1008
|
+
// 4. Inspect tool call history
|
|
1009
|
+
const calls = window.navigator.modelContextTesting.getToolCalls();
|
|
1010
|
+
console.log(`${calls.length} tool calls made`);
|
|
1011
|
+
calls.forEach(call => {
|
|
1012
|
+
console.log(`- ${call.toolName}`, call.arguments);
|
|
1013
|
+
});
|
|
1014
|
+
|
|
1015
|
+
// 5. Clean up after testing
|
|
1016
|
+
window.navigator.modelContextTesting.reset();
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
### Integration Testing Example
|
|
1020
|
+
|
|
1021
|
+
Perfect for automated testing with frameworks like Jest, Vitest, or Playwright:
|
|
1022
|
+
|
|
1023
|
+
```javascript
|
|
1024
|
+
// test/model-context.test.js
|
|
1025
|
+
import { test, expect } from 'vitest';
|
|
1026
|
+
|
|
1027
|
+
test('todo tool creates correct response', async () => {
|
|
1028
|
+
// Arrange
|
|
1029
|
+
const mockResponse = {
|
|
1030
|
+
content: [{ type: "text", text: "Test todo added" }]
|
|
1031
|
+
};
|
|
1032
|
+
|
|
1033
|
+
window.navigator.modelContextTesting.setMockToolResponse(
|
|
1034
|
+
"add-todo",
|
|
1035
|
+
mockResponse
|
|
1036
|
+
);
|
|
1037
|
+
|
|
1038
|
+
// Act
|
|
1039
|
+
// Trigger your AI agent or directly call the tool via MCP
|
|
1040
|
+
// ...
|
|
1041
|
+
|
|
1042
|
+
// Assert
|
|
1043
|
+
const calls = window.navigator.modelContextTesting.getToolCalls();
|
|
1044
|
+
expect(calls).toHaveLength(1);
|
|
1045
|
+
expect(calls[0].toolName).toBe("add-todo");
|
|
1046
|
+
expect(calls[0].arguments).toEqual({ text: "Test item" });
|
|
1047
|
+
|
|
1048
|
+
// Cleanup
|
|
1049
|
+
window.navigator.modelContextTesting.reset();
|
|
1050
|
+
});
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
### Browser Compatibility
|
|
1054
|
+
|
|
1055
|
+
| Browser | Native Support | Polyfill |
|
|
1056
|
+
|---------|---------------|----------|
|
|
1057
|
+
| Chrome/Edge (with flag) | ✅ Yes | N/A |
|
|
1058
|
+
| Chrome/Edge (default) | ❌ No | ✅ Yes |
|
|
1059
|
+
| Firefox | ❌ No | ✅ Yes |
|
|
1060
|
+
| Safari | ❌ No | ✅ Yes |
|
|
1061
|
+
| Other browsers | ❌ No | ✅ Yes |
|
|
1062
|
+
|
|
1063
|
+
The polyfill automatically detects and defers to the native implementation when available, ensuring forward compatibility as browsers adopt this standard.
|
|
1064
|
+
|
|
580
1065
|
## 📦 What's Included
|
|
581
1066
|
|
|
582
1067
|
- **Web Model Context API** - Standard `window.navigator.modelContext` interface
|
|
1068
|
+
- **Model Context Testing API** - `window.navigator.modelContextTesting` for debugging and testing (with native Chromium support detection)
|
|
583
1069
|
- **Dynamic Tool Registration** - `registerTool()` with `unregister()` function
|
|
584
1070
|
- **MCP Bridge** - Automatic bridging to Model Context Protocol
|
|
585
1071
|
- **Tab Transport** - Communication layer for browser contexts
|