@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.
- package/LICENSE +27 -29
- package/docs/index.md +1 -0
- package/docs/multi-tab.md +637 -637
- package/docs/native-webmcp.md +232 -0
- package/docs/project-structure.md +172 -172
- package/docs/tab-manager.md +150 -150
- package/index.js +356 -59
- package/mcp-service-worker.js +43 -2
- package/mcp-shared-worker.js +43 -2
- 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/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 +31 -0
- package/src/client/worker-client.d.ts.map +1 -1
- package/src/worker/mcp-controller.d.ts +5 -0
- package/src/worker/mcp-controller.d.ts.map +1 -1
|
@@ -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
|