@mcp-fe/mcp-worker 0.1.11 → 0.2.2

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,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
@@ -1,172 +1,172 @@
1
- # Project Structure
2
-
3
- This document explains the organization of the `@mcp-fe/mcp-worker` codebase.
4
-
5
- ## Directory Layout
6
-
7
- ```
8
- libs/mcp-worker/src/
9
- ├── index.ts # Main entry point (re-exports from client/)
10
- ├── mcp-shared-worker.ts # SharedWorker entry point
11
- ├── mcp-service-worker.ts # ServiceWorker entry point
12
- ├── client/ # Client-side code (application runtime)
13
- │ ├── index.ts # Client API exports
14
- │ └── worker-client.ts # Main WorkerClient class
15
- ├── worker/ # Worker-side code (background processing)
16
- │ ├── index.ts # Worker internal exports
17
- │ ├── mcp-controller.ts # MCP server controller & lifecycle
18
- │ ├── mcp-server.ts # MCP server setup & handlers
19
- │ ├── websocket-transport.ts # WebSocket transport for MCP
20
- │ ├── tool-registry.ts # Dynamic tool registration
21
- │ ├── tab-manager.ts # Multi-tab coordination
22
- │ ├── built-in-tools.ts # Default MCP tools
23
- │ └── tab-manager.spec.ts # Tests for TabManager
24
- └── shared/ # Shared code (both contexts)
25
- ├── types.ts # TypeScript type definitions
26
- ├── logger.ts # Logging utilities
27
- └── database.ts # IndexedDB operations
28
- ```
29
-
30
- ## Module Responsibilities
31
-
32
- ### Client (`client/`)
33
-
34
- **Purpose:** Code that runs in the main browser thread (your application).
35
-
36
- **Key Files:**
37
- - `worker-client.ts` - Main API for communicating with workers
38
- - Handles worker initialization (SharedWorker vs ServiceWorker)
39
- - Manages tool registration and lifecycle
40
- - Handles multi-tab coordination
41
- - Provides request/response messaging
42
-
43
- **Used by:** Your application code
44
-
45
- **Example:**
46
- ```typescript
47
- import { workerClient } from '@mcp-fe/mcp-worker';
48
- await workerClient.init();
49
- ```
50
-
51
- ### Worker (`worker/`)
52
-
53
- **Purpose:** Code that runs inside Web Workers (background processing).
54
-
55
- **Key Files:**
56
- - `mcp-controller.ts` - Main controller for MCP server lifecycle
57
- - WebSocket connection management
58
- - Tool call routing and execution
59
- - Tab management coordination
60
- - Event storage and querying
61
-
62
- - `mcp-server.ts` - MCP server setup using @modelcontextprotocol/sdk
63
- - Request handlers (ListTools, CallTool)
64
- - Server configuration and capabilities
65
-
66
- - `tool-registry.ts` - Dynamic tool management
67
- - Tool definition storage
68
- - Handler registration and lookup
69
- - Tool lifecycle management
70
-
71
- - `tab-manager.ts` - Multi-tab coordination
72
- - Tab registration and tracking
73
- - Active tab management
74
- - Smart tool routing across tabs
75
-
76
- - `built-in-tools.ts` - Default MCP tools
77
- - Event querying tools
78
- - Tab listing tools
79
- - Navigation history tools
80
-
81
- **Used by:** Worker entry points (`mcp-shared-worker.ts`, `mcp-service-worker.ts`)
82
-
83
- ### Shared (`shared/`)
84
-
85
- **Purpose:** Code used by both client and worker contexts.
86
-
87
- **Key Files:**
88
- - `types.ts` - TypeScript type definitions
89
- - `UserEvent`, `ToolDefinition`, `ToolHandler`
90
- - `TabInfo`, `EventFilters`, etc.
91
- - Ensures type consistency across contexts
92
-
93
- - `logger.ts` - Logging utilities
94
- - Environment-aware logging (dev vs production)
95
- - Consistent logging interface
96
- - Works in both main thread and workers
97
-
98
- - `database.ts` - IndexedDB operations
99
- - Event storage and retrieval
100
- - Query filtering and pagination
101
- - Available in both contexts (IndexedDB works everywhere)
102
-
103
- **Used by:** Both client and worker code
104
-
105
- ## Communication Flow
106
-
107
- ```
108
- Application Code
109
- ↓ (imports)
110
- client/worker-client.ts
111
- ↓ (postMessage)
112
- mcp-shared-worker.ts or mcp-service-worker.ts
113
- ↓ (uses)
114
- worker/mcp-controller.ts
115
- ↓ (uses)
116
- worker/mcp-server.ts
117
- ↓ (uses)
118
- worker/tool-registry.ts
119
- ↓ (WebSocket)
120
- MCP Proxy Server
121
- ```
122
-
123
- ## Import Patterns
124
-
125
- ### For Application Code
126
-
127
- ```typescript
128
- // Import from the main package
129
- import { workerClient, type ToolDefinition } from '@mcp-fe/mcp-worker';
130
- ```
131
-
132
- ### Internal Worker Code
133
-
134
- ```typescript
135
- // Worker modules import from shared/
136
- import { logger } from '../shared/logger';
137
- import type { UserEvent } from '../shared/types';
138
-
139
- // Worker modules import from other worker modules
140
- import { toolRegistry } from './tool-registry';
141
- import { TabManager } from './tab-manager';
142
- ```
143
-
144
- ### Internal Client Code
145
-
146
- ```typescript
147
- // Client modules import from shared/
148
- import { logger } from '../shared/logger';
149
- import type { ToolDefinition } from '../shared/types';
150
- ```
151
-
152
- ## Why This Structure?
153
-
154
- ### Clear Separation of Concerns
155
- - **Client code** only deals with communication and API
156
- - **Worker code** handles MCP protocol and business logic
157
- - **Shared code** provides common utilities and types
158
-
159
- ### Better Tree-Shaking
160
- - Applications only import client code
161
- - Worker bundles only include worker code
162
- - No unnecessary code in either bundle
163
-
164
- ### Maintainability
165
- - Easy to find where specific functionality lives
166
- - Clear boundaries between contexts
167
- - Prevents accidental mixing of client/worker code
168
-
169
- ### Future-Proof
170
- - Ready for splitting into separate npm packages if needed
171
- - Can add more worker types (e.g., dedicated workers)
172
- - Easy to add more shared utilities
1
+ # Project Structure
2
+
3
+ This document explains the organization of the `@mcp-fe/mcp-worker` codebase.
4
+
5
+ ## Directory Layout
6
+
7
+ ```
8
+ libs/mcp-worker/src/
9
+ ├── index.ts # Main entry point (re-exports from client/)
10
+ ├── mcp-shared-worker.ts # SharedWorker entry point
11
+ ├── mcp-service-worker.ts # ServiceWorker entry point
12
+ ├── client/ # Client-side code (application runtime)
13
+ │ ├── index.ts # Client API exports
14
+ │ └── worker-client.ts # Main WorkerClient class
15
+ ├── worker/ # Worker-side code (background processing)
16
+ │ ├── index.ts # Worker internal exports
17
+ │ ├── mcp-controller.ts # MCP server controller & lifecycle
18
+ │ ├── mcp-server.ts # MCP server setup & handlers
19
+ │ ├── websocket-transport.ts # WebSocket transport for MCP
20
+ │ ├── tool-registry.ts # Dynamic tool registration
21
+ │ ├── tab-manager.ts # Multi-tab coordination
22
+ │ ├── built-in-tools.ts # Default MCP tools
23
+ │ └── tab-manager.spec.ts # Tests for TabManager
24
+ └── shared/ # Shared code (both contexts)
25
+ ├── types.ts # TypeScript type definitions
26
+ ├── logger.ts # Logging utilities
27
+ └── database.ts # IndexedDB operations
28
+ ```
29
+
30
+ ## Module Responsibilities
31
+
32
+ ### Client (`client/`)
33
+
34
+ **Purpose:** Code that runs in the main browser thread (your application).
35
+
36
+ **Key Files:**
37
+ - `worker-client.ts` - Main API for communicating with workers
38
+ - Handles worker initialization (SharedWorker vs ServiceWorker)
39
+ - Manages tool registration and lifecycle
40
+ - Handles multi-tab coordination
41
+ - Provides request/response messaging
42
+
43
+ **Used by:** Your application code
44
+
45
+ **Example:**
46
+ ```typescript
47
+ import { workerClient } from '@mcp-fe/mcp-worker';
48
+ await workerClient.init();
49
+ ```
50
+
51
+ ### Worker (`worker/`)
52
+
53
+ **Purpose:** Code that runs inside Web Workers (background processing).
54
+
55
+ **Key Files:**
56
+ - `mcp-controller.ts` - Main controller for MCP server lifecycle
57
+ - WebSocket connection management
58
+ - Tool call routing and execution
59
+ - Tab management coordination
60
+ - Event storage and querying
61
+
62
+ - `mcp-server.ts` - MCP server setup using @modelcontextprotocol/sdk
63
+ - Request handlers (ListTools, CallTool)
64
+ - Server configuration and capabilities
65
+
66
+ - `tool-registry.ts` - Dynamic tool management
67
+ - Tool definition storage
68
+ - Handler registration and lookup
69
+ - Tool lifecycle management
70
+
71
+ - `tab-manager.ts` - Multi-tab coordination
72
+ - Tab registration and tracking
73
+ - Active tab management
74
+ - Smart tool routing across tabs
75
+
76
+ - `built-in-tools.ts` - Default MCP tools
77
+ - Event querying tools
78
+ - Tab listing tools
79
+ - Navigation history tools
80
+
81
+ **Used by:** Worker entry points (`mcp-shared-worker.ts`, `mcp-service-worker.ts`)
82
+
83
+ ### Shared (`shared/`)
84
+
85
+ **Purpose:** Code used by both client and worker contexts.
86
+
87
+ **Key Files:**
88
+ - `types.ts` - TypeScript type definitions
89
+ - `UserEvent`, `ToolDefinition`, `ToolHandler`
90
+ - `TabInfo`, `EventFilters`, etc.
91
+ - Ensures type consistency across contexts
92
+
93
+ - `logger.ts` - Logging utilities
94
+ - Environment-aware logging (dev vs production)
95
+ - Consistent logging interface
96
+ - Works in both main thread and workers
97
+
98
+ - `database.ts` - IndexedDB operations
99
+ - Event storage and retrieval
100
+ - Query filtering and pagination
101
+ - Available in both contexts (IndexedDB works everywhere)
102
+
103
+ **Used by:** Both client and worker code
104
+
105
+ ## Communication Flow
106
+
107
+ ```
108
+ Application Code
109
+ ↓ (imports)
110
+ client/worker-client.ts
111
+ ↓ (postMessage)
112
+ mcp-shared-worker.ts or mcp-service-worker.ts
113
+ ↓ (uses)
114
+ worker/mcp-controller.ts
115
+ ↓ (uses)
116
+ worker/mcp-server.ts
117
+ ↓ (uses)
118
+ worker/tool-registry.ts
119
+ ↓ (WebSocket)
120
+ MCP Proxy Server
121
+ ```
122
+
123
+ ## Import Patterns
124
+
125
+ ### For Application Code
126
+
127
+ ```typescript
128
+ // Import from the main package
129
+ import { workerClient, type ToolDefinition } from '@mcp-fe/mcp-worker';
130
+ ```
131
+
132
+ ### Internal Worker Code
133
+
134
+ ```typescript
135
+ // Worker modules import from shared/
136
+ import { logger } from '../shared/logger';
137
+ import type { UserEvent } from '../shared/types';
138
+
139
+ // Worker modules import from other worker modules
140
+ import { toolRegistry } from './tool-registry';
141
+ import { TabManager } from './tab-manager';
142
+ ```
143
+
144
+ ### Internal Client Code
145
+
146
+ ```typescript
147
+ // Client modules import from shared/
148
+ import { logger } from '../shared/logger';
149
+ import type { ToolDefinition } from '../shared/types';
150
+ ```
151
+
152
+ ## Why This Structure?
153
+
154
+ ### Clear Separation of Concerns
155
+ - **Client code** only deals with communication and API
156
+ - **Worker code** handles MCP protocol and business logic
157
+ - **Shared code** provides common utilities and types
158
+
159
+ ### Better Tree-Shaking
160
+ - Applications only import client code
161
+ - Worker bundles only include worker code
162
+ - No unnecessary code in either bundle
163
+
164
+ ### Maintainability
165
+ - Easy to find where specific functionality lives
166
+ - Clear boundaries between contexts
167
+ - Prevents accidental mixing of client/worker code
168
+
169
+ ### Future-Proof
170
+ - Ready for splitting into separate npm packages if needed
171
+ - Can add more worker types (e.g., dedicated workers)
172
+ - Easy to add more shared utilities