@mcp-fe/mcp-worker 0.1.10 → 0.2.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/docs/index.md +1 -0
- package/docs/native-webmcp.md +232 -0
- package/index.js +539 -153
- package/mcp-service-worker.js +10 -0
- package/mcp-shared-worker.js +10 -0
- package/package.json +1 -1
- package/src/client/index.d.ts +2 -0
- package/src/client/index.d.ts.map +1 -1
- package/src/client/tool-registry.d.ts +117 -0
- package/src/client/tool-registry.d.ts.map +1 -0
- package/src/client/web-mcp-adapter.d.ts +97 -0
- package/src/client/web-mcp-adapter.d.ts.map +1 -0
- package/src/client/web-mcp-types.d.ts +122 -0
- package/src/client/web-mcp-types.d.ts.map +1 -0
- package/src/client/worker-client.d.ts +41 -37
- package/src/client/worker-client.d.ts.map +1 -1
- package/src/worker/mcp-controller.d.ts.map +1 -1
- package/src/worker/mcp-server.d.ts +5 -0
- package/src/worker/mcp-server.d.ts.map +1 -1
package/docs/index.md
CHANGED
|
@@ -11,6 +11,7 @@ Complete guide to all documentation and examples in the MCP Worker library.
|
|
|
11
11
|
| **Learn step-by-step** | [Guide](./guide.md) |
|
|
12
12
|
| **Complete API reference** | [API Reference](./api.md) |
|
|
13
13
|
| **Multi-tab applications** | [Multi-Tab Guide](./multi-tab.md) |
|
|
14
|
+
| **WebMCP integration** | [WebMCP](./native-webmcp.md) |
|
|
14
15
|
| **Worker implementation** | [Worker Details](./worker-details.md) |
|
|
15
16
|
| **Understand codebase structure** | [Project Structure](./project-structure.md) |
|
|
16
17
|
| **Use with React** | [React Hooks Guide](../../react-event-tracker/REACT_MCP_TOOLS.md) |
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# WebMCP Integration
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The MCP Worker library includes a built-in adapter for the **WebMCP API** (`navigator.modelContext`), a browser-native mechanism for registering MCP tools directly with the user-agent. When the browser supports this API, tools registered via `WorkerClient` are **automatically** advertised through the native channel as well, enabling browser-level tool discovery by AI agents, browser's agents, and assistive technologies.
|
|
6
|
+
|
|
7
|
+
**Enabled by default** — if the browser supports `navigator.modelContext`, it just works. No configuration needed. You can explicitly disable it if needed.
|
|
8
|
+
|
|
9
|
+
Based on the [WebMCP specification](https://webmachinelearning.github.io/webmcp/) published by the W3C Web Machine Learning Community Group.
|
|
10
|
+
|
|
11
|
+
## How It Works
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
┌──────────────────────────────────────────────────────────┐
|
|
15
|
+
│ WorkerClient │
|
|
16
|
+
│ │
|
|
17
|
+
│ registerTool('my-tool', ...) │
|
|
18
|
+
│ │ │
|
|
19
|
+
│ ├──→ ToolRegistry (local, immediate) │
|
|
20
|
+
│ │ │
|
|
21
|
+
│ ├──→ SharedWorker / ServiceWorker (transport) │
|
|
22
|
+
│ │ └──→ WebSocket → Backend MCP Server │
|
|
23
|
+
│ │ │
|
|
24
|
+
│ └──→ WebMcpAdapter (auto-enabled if supported) │
|
|
25
|
+
│ └──→ navigator.modelContext.registerTool() │
|
|
26
|
+
│ (browser-native registration) │
|
|
27
|
+
└──────────────────────────────────────────────────────────┘
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Key principle**: The worker transport remains the **primary** channel. WebMCP registration is a **secondary, additive** channel for browser-level discovery. Both systems coexist.
|
|
31
|
+
|
|
32
|
+
## WebMCP Spec API Surface
|
|
33
|
+
|
|
34
|
+
The adapter maps to the following browser API (per spec §5):
|
|
35
|
+
|
|
36
|
+
```webidl
|
|
37
|
+
// §5.1 Navigator extension
|
|
38
|
+
partial interface Navigator {
|
|
39
|
+
[SecureContext, SameObject] readonly attribute ModelContext modelContext;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// §5.2 ModelContext interface
|
|
43
|
+
interface ModelContext {
|
|
44
|
+
undefined provideContext(optional ModelContextOptions options = {});
|
|
45
|
+
undefined clearContext();
|
|
46
|
+
undefined registerTool(ModelContextTool tool);
|
|
47
|
+
undefined unregisterTool(DOMString name);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// §5.2.2 ModelContextTool dictionary
|
|
51
|
+
dictionary ModelContextTool {
|
|
52
|
+
required DOMString name;
|
|
53
|
+
required DOMString description;
|
|
54
|
+
object inputSchema;
|
|
55
|
+
required ToolExecuteCallback execute;
|
|
56
|
+
ToolAnnotations annotations;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
dictionary ToolAnnotations {
|
|
60
|
+
boolean readOnlyHint;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
callback ToolExecuteCallback = Promise<any> (object input, ModelContextClient client);
|
|
64
|
+
|
|
65
|
+
// §5.2.3 ModelContextClient
|
|
66
|
+
interface ModelContextClient {
|
|
67
|
+
Promise<any> requestUserInteraction(UserInteractionCallback callback);
|
|
68
|
+
};
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Feature Detection
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { WorkerClient, WebMcpAdapter } from '@anthropic/mcp-worker';
|
|
75
|
+
|
|
76
|
+
// Static check: does the browser support navigator.modelContext?
|
|
77
|
+
if (WorkerClient.isWebMcpSupported()) {
|
|
78
|
+
console.log('Browser supports WebMCP!');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Or use the adapter directly:
|
|
82
|
+
if (WebMcpAdapter.isSupported()) {
|
|
83
|
+
console.log('navigator.modelContext is available');
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Configuration
|
|
88
|
+
|
|
89
|
+
### Default behavior (auto-enabled)
|
|
90
|
+
|
|
91
|
+
No configuration needed. If `navigator.modelContext` is available, tools are automatically registered via WebMCP:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
import { workerClient } from '@anthropic/mcp-worker';
|
|
95
|
+
|
|
96
|
+
await workerClient.init({
|
|
97
|
+
sharedWorkerUrl: '/mcp-shared-worker.js',
|
|
98
|
+
backendWsUrl: 'ws://localhost:3001',
|
|
99
|
+
// enableWebMcp defaults to true — auto-detects browser support
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Explicitly disable
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
await workerClient.init({
|
|
107
|
+
sharedWorkerUrl: '/mcp-shared-worker.js',
|
|
108
|
+
backendWsUrl: 'ws://localhost:3001',
|
|
109
|
+
enableWebMcp: false, // ← disable WebMCP registration
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Toggle at runtime
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// Disable — calls navigator.modelContext.clearContext()
|
|
117
|
+
workerClient.setWebMcpEnabled(false);
|
|
118
|
+
|
|
119
|
+
// Re-enable — syncs all existing tools to navigator.modelContext
|
|
120
|
+
workerClient.setWebMcpEnabled(true);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Registering Tools
|
|
124
|
+
|
|
125
|
+
No changes to tool registration are needed. When WebMCP is available, `registerTool()` automatically registers in both systems:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
await workerClient.registerTool(
|
|
129
|
+
'get-user-profile',
|
|
130
|
+
'Fetch the current user profile',
|
|
131
|
+
{
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
userId: { type: 'string', description: 'User ID' },
|
|
135
|
+
},
|
|
136
|
+
required: ['userId'],
|
|
137
|
+
},
|
|
138
|
+
async (args: unknown) => {
|
|
139
|
+
const { userId } = args as { userId: string };
|
|
140
|
+
const profile = await fetchProfile(userId);
|
|
141
|
+
return {
|
|
142
|
+
content: [{ type: 'text', text: JSON.stringify(profile) }],
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
{ annotations: { readOnlyHint: true } },
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Check where the tool is registered:
|
|
149
|
+
workerClient.isToolRegistered('get-user-profile'); // true (local + worker)
|
|
150
|
+
workerClient.isToolRegisteredViaWebMcp('get-user-profile'); // true (navigator.modelContext)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Querying WebMCP Registrations
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// Check if a specific tool is registered via WebMCP
|
|
157
|
+
workerClient.isToolRegisteredViaWebMcp('my-tool'); // boolean
|
|
158
|
+
|
|
159
|
+
// Get all WebMCP-registered tool names
|
|
160
|
+
workerClient.getWebMcpRegisteredTools(); // string[]
|
|
161
|
+
|
|
162
|
+
// Check if WebMCP is currently enabled AND supported
|
|
163
|
+
workerClient.isWebMcpAvailable(); // boolean
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Cleanup
|
|
167
|
+
|
|
168
|
+
WebMCP registrations are cleaned up automatically:
|
|
169
|
+
|
|
170
|
+
- **On `unregisterTool()`** — calls `navigator.modelContext.unregisterTool(name)`
|
|
171
|
+
- **On page unload** (`beforeunload` / `pagehide`) — calls `navigator.modelContext.clearContext()`
|
|
172
|
+
- **On `setWebMcpEnabled(false)`** — calls `navigator.modelContext.clearContext()`
|
|
173
|
+
|
|
174
|
+
## Architecture
|
|
175
|
+
|
|
176
|
+
### Files
|
|
177
|
+
|
|
178
|
+
| File | Purpose |
|
|
179
|
+
|------|---------|
|
|
180
|
+
| `web-mcp-types.ts` | TypeScript types matching the WebMCP spec (`ModelContext`, `ModelContextTool`, `ModelContextClient`, etc.) |
|
|
181
|
+
| `web-mcp-adapter.ts` | Adapter that bridges ToolRegistry ↔ `navigator.modelContext` |
|
|
182
|
+
| `worker-client.ts` | Integration point (uses adapter internally) |
|
|
183
|
+
|
|
184
|
+
### Type Augmentation
|
|
185
|
+
|
|
186
|
+
The `web-mcp-types.ts` file extends the global `Navigator` interface:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
declare global {
|
|
190
|
+
interface Navigator {
|
|
191
|
+
readonly modelContext?: ModelContext;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### WebMcpAdapter
|
|
197
|
+
|
|
198
|
+
The adapter is a standalone class, enabled by default:
|
|
199
|
+
|
|
200
|
+
- **`isSupported()`** — static, checks `navigator.modelContext` existence
|
|
201
|
+
- **`isAvailable()`** — instance, respects enabled flag + browser support
|
|
202
|
+
- **`registerTool()`** — builds `ModelContextTool` dict and calls `navigator.modelContext.registerTool(tool)` (synchronous)
|
|
203
|
+
- **`unregisterTool()`** — calls `navigator.modelContext.unregisterTool(name)` (synchronous)
|
|
204
|
+
- **`clearAll()`** — calls `navigator.modelContext.clearContext()` (per spec §5.2)
|
|
205
|
+
- **`toModelContextTool()`** — static utility to convert internal `ToolDefinition` + handler
|
|
206
|
+
|
|
207
|
+
### Handler Mapping
|
|
208
|
+
|
|
209
|
+
The spec defines `ToolExecuteCallback` as:
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
callback ToolExecuteCallback = Promise<any> (object input, ModelContextClient client);
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
The adapter wraps the internal `ToolHandler` (which takes `args: unknown` and returns `{ content: [...] }`) into this format. The `ModelContextClient` parameter gives access to `requestUserInteraction()` for user consent flows.
|
|
216
|
+
|
|
217
|
+
## Error Handling
|
|
218
|
+
|
|
219
|
+
All WebMCP operations are **best-effort**:
|
|
220
|
+
|
|
221
|
+
- Registration failures are logged as warnings, never thrown
|
|
222
|
+
- The worker-based system is unaffected by WebMCP errors
|
|
223
|
+
- Per spec, `registerTool()` throws if a duplicate name exists — the adapter unregisters first
|
|
224
|
+
- `clearAll()` falls back to individual `unregisterTool()` calls if `clearContext()` throws
|
|
225
|
+
|
|
226
|
+
## Browser Support
|
|
227
|
+
|
|
228
|
+
The WebMCP specification is a CG-DRAFT published by the W3C Web Machine Learning Community Group (February 2026). The adapter is forward-compatible:
|
|
229
|
+
|
|
230
|
+
- When the API is unavailable, all WebMCP operations are silent no-ops
|
|
231
|
+
- Zero runtime cost when browser doesn't support it (no feature detection on hot paths)
|
|
232
|
+
- The type definitions follow the spec and can be updated as the standard evolves
|