@mcp-fe/mcp-worker 0.0.17 → 0.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 +184 -349
- package/docs/api.md +418 -0
- package/docs/architecture.md +195 -0
- package/docs/guide.md +454 -0
- package/docs/index.md +109 -0
- package/docs/initialization.md +188 -0
- package/docs/worker-details.md +435 -0
- package/index.js +365 -5
- package/mcp-service-worker.js +505 -204
- package/mcp-shared-worker.js +487 -173
- package/package.json +1 -1
- package/src/index.d.ts +2 -1
- package/src/index.d.ts.map +1 -1
- package/src/lib/built-in-tools.d.ts +9 -0
- package/src/lib/built-in-tools.d.ts.map +1 -0
- package/src/lib/mcp-controller.d.ts +18 -0
- package/src/lib/mcp-controller.d.ts.map +1 -1
- package/src/lib/mcp-server.d.ts +11 -0
- package/src/lib/mcp-server.d.ts.map +1 -1
- package/src/lib/tool-registry.d.ts +28 -0
- package/src/lib/tool-registry.d.ts.map +1 -0
- package/src/lib/worker-client.d.ts +123 -0
- package/src/lib/worker-client.d.ts.map +1 -1
package/docs/guide.md
ADDED
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# Dynamic Tool Registration Guide
|
|
2
|
+
|
|
3
|
+
Learn how to register custom MCP tools that run in your browser with full access to all APIs.
|
|
4
|
+
|
|
5
|
+
## How It Works
|
|
6
|
+
|
|
7
|
+
**Handlers run in the main thread**, not in the worker. This means you have full access to:
|
|
8
|
+
|
|
9
|
+
- ✅ React context, hooks, state
|
|
10
|
+
- ✅ DOM API, localStorage, fetch
|
|
11
|
+
- ✅ All your imports and dependencies
|
|
12
|
+
- ✅ Closures and external variables
|
|
13
|
+
|
|
14
|
+
The worker acts as a **proxy**, forwarding calls between the MCP protocol and your handler.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
MCP Client → Worker (proxy) → Your Handler (main thread) → Result
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { workerClient } from '@mcp-fe/mcp-worker';
|
|
24
|
+
|
|
25
|
+
// Initialize
|
|
26
|
+
await workerClient.init({
|
|
27
|
+
backendWsUrl: 'ws://localhost:3001'
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Register a tool
|
|
31
|
+
await workerClient.registerTool(
|
|
32
|
+
'get_time',
|
|
33
|
+
'Get current time',
|
|
34
|
+
{ type: 'object', properties: {} },
|
|
35
|
+
async () => ({
|
|
36
|
+
content: [{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: new Date().toISOString()
|
|
39
|
+
}]
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
### `workerClient.registerTool(name, description, inputSchema, handler)`
|
|
47
|
+
|
|
48
|
+
Register a new MCP tool.
|
|
49
|
+
|
|
50
|
+
**Parameters:**
|
|
51
|
+
- `name` (string) - Tool name (use snake_case)
|
|
52
|
+
- `description` (string) - What the tool does (AI uses this)
|
|
53
|
+
- `inputSchema` (object) - JSON Schema for input validation
|
|
54
|
+
- `handler` (function) - Async function that handles the tool execution
|
|
55
|
+
|
|
56
|
+
**Returns:** `Promise<void>`
|
|
57
|
+
|
|
58
|
+
**Example:**
|
|
59
|
+
```typescript
|
|
60
|
+
await workerClient.registerTool(
|
|
61
|
+
'calculate',
|
|
62
|
+
'Perform arithmetic operations',
|
|
63
|
+
{
|
|
64
|
+
type: 'object',
|
|
65
|
+
properties: {
|
|
66
|
+
operation: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
enum: ['add', 'subtract', 'multiply', 'divide']
|
|
69
|
+
},
|
|
70
|
+
a: { type: 'number' },
|
|
71
|
+
b: { type: 'number' }
|
|
72
|
+
},
|
|
73
|
+
required: ['operation', 'a', 'b']
|
|
74
|
+
},
|
|
75
|
+
async (args: any) => {
|
|
76
|
+
const { operation, a, b } = args;
|
|
77
|
+
let result: number;
|
|
78
|
+
|
|
79
|
+
switch (operation) {
|
|
80
|
+
case 'add': result = a + b; break;
|
|
81
|
+
case 'subtract': result = a - b; break;
|
|
82
|
+
case 'multiply': result = a * b; break;
|
|
83
|
+
case 'divide':
|
|
84
|
+
if (b === 0) {
|
|
85
|
+
throw new Error('Division by zero');
|
|
86
|
+
}
|
|
87
|
+
result = a / b;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
content: [{
|
|
93
|
+
type: 'text',
|
|
94
|
+
text: JSON.stringify({ operation, a, b, result })
|
|
95
|
+
}]
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### `workerClient.unregisterTool(name)`
|
|
102
|
+
|
|
103
|
+
Unregister a previously registered tool.
|
|
104
|
+
|
|
105
|
+
**Parameters:**
|
|
106
|
+
- `name` (string) - Tool name to unregister
|
|
107
|
+
|
|
108
|
+
**Returns:** `Promise<boolean>` - True if tool was found and removed
|
|
109
|
+
|
|
110
|
+
**Example:**
|
|
111
|
+
```typescript
|
|
112
|
+
const success = await workerClient.unregisterTool('calculate');
|
|
113
|
+
if (success) {
|
|
114
|
+
console.log('Tool unregistered');
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Handler Function
|
|
119
|
+
|
|
120
|
+
The handler receives the tool arguments and must return a result in MCP format.
|
|
121
|
+
|
|
122
|
+
**Signature:**
|
|
123
|
+
```typescript
|
|
124
|
+
async (args: unknown) => Promise<{
|
|
125
|
+
content: Array<{
|
|
126
|
+
type: 'text' | 'image' | 'resource';
|
|
127
|
+
text?: string;
|
|
128
|
+
data?: string;
|
|
129
|
+
mimeType?: string;
|
|
130
|
+
}>;
|
|
131
|
+
}>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Example with validation:**
|
|
135
|
+
```typescript
|
|
136
|
+
import { z } from 'zod';
|
|
137
|
+
|
|
138
|
+
const handler = async (args: unknown) => {
|
|
139
|
+
// Validate input
|
|
140
|
+
const schema = z.object({
|
|
141
|
+
username: z.string().min(3),
|
|
142
|
+
email: z.string().email()
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
try {
|
|
146
|
+
const validated = schema.parse(args);
|
|
147
|
+
|
|
148
|
+
// Your logic here
|
|
149
|
+
const result = await createUser(validated);
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
content: [{
|
|
153
|
+
type: 'text',
|
|
154
|
+
text: JSON.stringify(result)
|
|
155
|
+
}]
|
|
156
|
+
};
|
|
157
|
+
} catch (error) {
|
|
158
|
+
return {
|
|
159
|
+
content: [{
|
|
160
|
+
type: 'text',
|
|
161
|
+
text: JSON.stringify({
|
|
162
|
+
error: error.message
|
|
163
|
+
})
|
|
164
|
+
}]
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Common Patterns
|
|
171
|
+
|
|
172
|
+
### Accessing React State
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
function MyComponent() {
|
|
176
|
+
const [todos, setTodos] = useState([]);
|
|
177
|
+
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
workerClient.registerTool(
|
|
180
|
+
'get_todos',
|
|
181
|
+
'Get all todos',
|
|
182
|
+
{ type: 'object', properties: {} },
|
|
183
|
+
async () => ({
|
|
184
|
+
content: [{
|
|
185
|
+
type: 'text',
|
|
186
|
+
text: JSON.stringify(todos)
|
|
187
|
+
}]
|
|
188
|
+
})
|
|
189
|
+
);
|
|
190
|
+
}, [todos]);
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Using External APIs
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
await workerClient.registerTool(
|
|
198
|
+
'fetch_weather',
|
|
199
|
+
'Get weather for a city',
|
|
200
|
+
{
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {
|
|
203
|
+
city: { type: 'string' }
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
async (args: any) => {
|
|
207
|
+
const response = await fetch(
|
|
208
|
+
`https://api.weather.com/data?city=${args.city}`
|
|
209
|
+
);
|
|
210
|
+
const data = await response.json();
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
content: [{
|
|
214
|
+
type: 'text',
|
|
215
|
+
text: JSON.stringify(data)
|
|
216
|
+
}]
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Accessing localStorage
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
await workerClient.registerTool(
|
|
226
|
+
'get_settings',
|
|
227
|
+
'Get user settings',
|
|
228
|
+
{ type: 'object', properties: {} },
|
|
229
|
+
async () => {
|
|
230
|
+
const theme = localStorage.getItem('theme') || 'light';
|
|
231
|
+
const language = localStorage.getItem('lang') || 'en';
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
content: [{
|
|
235
|
+
type: 'text',
|
|
236
|
+
text: JSON.stringify({ theme, language })
|
|
237
|
+
}]
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Accessing DOM
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
await workerClient.registerTool(
|
|
247
|
+
'get_page_info',
|
|
248
|
+
'Get current page information',
|
|
249
|
+
{ type: 'object', properties: {} },
|
|
250
|
+
async () => ({
|
|
251
|
+
content: [{
|
|
252
|
+
type: 'text',
|
|
253
|
+
text: JSON.stringify({
|
|
254
|
+
title: document.title,
|
|
255
|
+
url: window.location.href,
|
|
256
|
+
headings: document.querySelectorAll('h1, h2').length
|
|
257
|
+
})
|
|
258
|
+
}]
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Best Practices
|
|
264
|
+
|
|
265
|
+
### 1. Tool Naming
|
|
266
|
+
|
|
267
|
+
Use **snake_case** for tool names:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
// ✅ Good
|
|
271
|
+
'get_user_profile'
|
|
272
|
+
'create_todo'
|
|
273
|
+
'fetch_data'
|
|
274
|
+
|
|
275
|
+
// ❌ Bad
|
|
276
|
+
'getUserProfile'
|
|
277
|
+
'CreateTodo'
|
|
278
|
+
'fetch-data'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### 2. Descriptions
|
|
282
|
+
|
|
283
|
+
Write clear, specific descriptions. The AI uses these to decide when to call your tool:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
// ✅ Good
|
|
287
|
+
'Get the current user profile including username, email, and avatar'
|
|
288
|
+
|
|
289
|
+
// ❌ Bad
|
|
290
|
+
'Get user'
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### 3. Input Validation
|
|
294
|
+
|
|
295
|
+
Always validate inputs:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// ✅ Good - with validation
|
|
299
|
+
const handler = async (args: unknown) => {
|
|
300
|
+
const schema = z.object({
|
|
301
|
+
email: z.string().email()
|
|
302
|
+
});
|
|
303
|
+
const validated = schema.parse(args);
|
|
304
|
+
// ...
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
// ❌ Bad - no validation
|
|
308
|
+
const handler = async (args: any) => {
|
|
309
|
+
const email = args.email; // Could be anything!
|
|
310
|
+
// ...
|
|
311
|
+
};
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### 4. Error Handling
|
|
315
|
+
|
|
316
|
+
Return helpful error messages:
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
try {
|
|
320
|
+
const result = await doSomething();
|
|
321
|
+
return {
|
|
322
|
+
content: [{
|
|
323
|
+
type: 'text',
|
|
324
|
+
text: JSON.stringify(result)
|
|
325
|
+
}]
|
|
326
|
+
};
|
|
327
|
+
} catch (error) {
|
|
328
|
+
return {
|
|
329
|
+
content: [{
|
|
330
|
+
type: 'text',
|
|
331
|
+
text: JSON.stringify({
|
|
332
|
+
error: error.message,
|
|
333
|
+
// Include context to help debug
|
|
334
|
+
input: args
|
|
335
|
+
})
|
|
336
|
+
}]
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### 5. TypeScript
|
|
342
|
+
|
|
343
|
+
Use proper types for better developer experience:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
interface CalculateArgs {
|
|
347
|
+
operation: 'add' | 'subtract' | 'multiply' | 'divide';
|
|
348
|
+
a: number;
|
|
349
|
+
b: number;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const handler = async (args: unknown) => {
|
|
353
|
+
const { operation, a, b } = args as CalculateArgs;
|
|
354
|
+
// TypeScript knows the types now
|
|
355
|
+
};
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Testing
|
|
359
|
+
|
|
360
|
+
Handlers are normal async functions - easy to test:
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
// Define handler
|
|
364
|
+
const myHandler = async (args: unknown) => {
|
|
365
|
+
return {
|
|
366
|
+
content: [{
|
|
367
|
+
type: 'text',
|
|
368
|
+
text: JSON.stringify({ result: 'ok' })
|
|
369
|
+
}]
|
|
370
|
+
};
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
// Test it
|
|
374
|
+
test('myHandler returns ok', async () => {
|
|
375
|
+
const result = await myHandler({});
|
|
376
|
+
expect(result.content[0].text).toContain('ok');
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// Then register
|
|
380
|
+
await workerClient.registerTool('my_tool', '...', {}, myHandler);
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Examples
|
|
384
|
+
|
|
385
|
+
See [examples/](../examples/) for complete, runnable examples:
|
|
386
|
+
|
|
387
|
+
- [quick-start.ts](../examples/quick-start.ts) - Simple examples
|
|
388
|
+
- [dynamic-tools.ts](../examples/dynamic-tools.ts) - Advanced patterns
|
|
389
|
+
|
|
390
|
+
## React Integration
|
|
391
|
+
|
|
392
|
+
For React applications, use the `useMCPTool` hook for automatic lifecycle management:
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
import { useMCPTool } from '@mcp-fe/react-event-tracker';
|
|
396
|
+
|
|
397
|
+
function MyComponent() {
|
|
398
|
+
useMCPTool({
|
|
399
|
+
name: 'my_tool',
|
|
400
|
+
description: 'My tool',
|
|
401
|
+
inputSchema: { type: 'object', properties: {} },
|
|
402
|
+
handler: async () => ({
|
|
403
|
+
content: [{ type: 'text', text: 'Hello!' }]
|
|
404
|
+
})
|
|
405
|
+
});
|
|
406
|
+
// Automatically registered on mount, unregistered on unmount
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
See [React Hooks Guide](../../react-event-tracker/REACT_MCP_TOOLS.md) for details.
|
|
411
|
+
|
|
412
|
+
## Troubleshooting
|
|
413
|
+
|
|
414
|
+
### Tool doesn't register
|
|
415
|
+
|
|
416
|
+
Check that the worker is initialized:
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
await workerClient.init();
|
|
420
|
+
console.log(workerClient.initialized); // should be true
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Handler not called
|
|
424
|
+
|
|
425
|
+
Verify the tool name matches exactly:
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
// Registration
|
|
429
|
+
await workerClient.registerTool('get_user', ...);
|
|
430
|
+
|
|
431
|
+
// MCP call must use: 'get_user' (exact match)
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Arguments not received
|
|
435
|
+
|
|
436
|
+
Check your input schema matches what the AI sends:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
// Schema says: { email: string }
|
|
440
|
+
inputSchema: {
|
|
441
|
+
type: 'object',
|
|
442
|
+
properties: {
|
|
443
|
+
email: { type: 'string' }
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Handler receives: { email: 'test@example.com' }
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
## Next Steps
|
|
451
|
+
|
|
452
|
+
- [Architecture](./architecture.md) - How the proxy pattern works
|
|
453
|
+
- [Initialization](./initialization.md) - Init queue handling
|
|
454
|
+
- [Examples](../examples/) - Runnable code examples
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Documentation Index
|
|
2
|
+
|
|
3
|
+
Complete guide to all documentation and examples in the MCP Worker library.
|
|
4
|
+
|
|
5
|
+
## 🎯 Quick Navigation
|
|
6
|
+
|
|
7
|
+
| I want to... | Go to... |
|
|
8
|
+
|--------------|----------|
|
|
9
|
+
| **Get started quickly** | [examples/quick-start.ts](../examples/quick-start.ts) |
|
|
10
|
+
| **See advanced patterns** | [examples/dynamic-tools.ts](../examples/dynamic-tools.ts) |
|
|
11
|
+
| **Learn step-by-step** | [Guide](./guide.md) |
|
|
12
|
+
| **Complete API reference** | [API Reference](./api.md) |
|
|
13
|
+
| **Worker implementation** | [Worker Details](./worker-details.md) |
|
|
14
|
+
| **Use with React** | [React Hooks Guide](../../react-event-tracker/REACT_MCP_TOOLS.md) |
|
|
15
|
+
| **Understand architecture** | [Architecture](./architecture.md) |
|
|
16
|
+
| **Handle initialization** | [Initialization](./initialization.md) |
|
|
17
|
+
|
|
18
|
+
## 📁 Documentation Structure
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
libs/mcp-worker/
|
|
22
|
+
├── README.md ← Start here!
|
|
23
|
+
│
|
|
24
|
+
├── docs/ ← Documentation
|
|
25
|
+
│ ├── index.md ← This file
|
|
26
|
+
│ ├── guide.md ← Complete guide
|
|
27
|
+
│ ├── api.md ← API reference
|
|
28
|
+
│ ├── worker-details.md ← Worker implementation
|
|
29
|
+
│ ├── architecture.md ← Technical architecture
|
|
30
|
+
│ └── initialization.md ← Init handling
|
|
31
|
+
│
|
|
32
|
+
├── examples/ ← Code examples
|
|
33
|
+
│ ├── README.md ← Examples guide
|
|
34
|
+
│ ├── quick-start.ts ← Simple examples
|
|
35
|
+
│ └── dynamic-tools.ts ← Advanced patterns
|
|
36
|
+
│
|
|
37
|
+
└── src/ ← Source code
|
|
38
|
+
└── lib/
|
|
39
|
+
└── worker-client.ts
|
|
40
|
+
|
|
41
|
+
libs/react-event-tracker/
|
|
42
|
+
├── REACT_MCP_TOOLS.md ← React hooks docs
|
|
43
|
+
└── src/examples/
|
|
44
|
+
└── ReactMCPToolsExamples.tsx ← React examples
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 📖 Documentation by Purpose
|
|
48
|
+
|
|
49
|
+
### For Beginners
|
|
50
|
+
|
|
51
|
+
1. [README.md](../README.md) - Overview and quick start
|
|
52
|
+
2. [examples/quick-start.ts](../examples/quick-start.ts) - Simple examples
|
|
53
|
+
3. [examples/README.md](../examples/README.md) - How to use examples
|
|
54
|
+
|
|
55
|
+
### For Developers
|
|
56
|
+
|
|
57
|
+
1. [Guide](./guide.md) - Step-by-step guide
|
|
58
|
+
2. [API Reference](./api.md) - Complete API documentation
|
|
59
|
+
3. [examples/dynamic-tools.ts](../examples/dynamic-tools.ts) - Advanced patterns
|
|
60
|
+
4. [Worker Details](./worker-details.md) - Implementation details
|
|
61
|
+
5. [Architecture](./architecture.md) - How it works
|
|
62
|
+
|
|
63
|
+
### For React Users
|
|
64
|
+
|
|
65
|
+
1. [React Hooks Guide](../../react-event-tracker/REACT_MCP_TOOLS.md) - React integration
|
|
66
|
+
2. [React Examples](../../react-event-tracker/src/examples/ReactMCPToolsExamples.tsx) - Component examples
|
|
67
|
+
|
|
68
|
+
## 🔍 Finding What You Need
|
|
69
|
+
|
|
70
|
+
### "How do I register a tool?"
|
|
71
|
+
→ [examples/quick-start.ts](../examples/quick-start.ts) (Example 1)
|
|
72
|
+
|
|
73
|
+
### "How do I validate inputs?"
|
|
74
|
+
→ [examples/dynamic-tools.ts](../examples/dynamic-tools.ts) (Calculator example)
|
|
75
|
+
|
|
76
|
+
### "How do I use this with React?"
|
|
77
|
+
→ [React Hooks Guide](../../react-event-tracker/REACT_MCP_TOOLS.md)
|
|
78
|
+
|
|
79
|
+
### "How does the proxy pattern work?"
|
|
80
|
+
→ [Architecture](./architecture.md)
|
|
81
|
+
|
|
82
|
+
### "How do I handle initialization?"
|
|
83
|
+
→ [Initialization](./initialization.md)
|
|
84
|
+
|
|
85
|
+
## 📦 What's in the npm Package
|
|
86
|
+
|
|
87
|
+
When you install `@mcp-fe/mcp-worker`, you get:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
node_modules/@mcp-fe/mcp-worker/
|
|
91
|
+
├── index.js # Main entry point
|
|
92
|
+
├── index.d.ts # TypeScript definitions
|
|
93
|
+
├── mcp-shared-worker.js # SharedWorker bundle
|
|
94
|
+
├── mcp-service-worker.js # ServiceWorker bundle
|
|
95
|
+
├── lib/ # Compiled library code
|
|
96
|
+
└── README.md # Basic documentation
|
|
97
|
+
|
|
98
|
+
# NOT included (development only):
|
|
99
|
+
# - examples/
|
|
100
|
+
# - docs/
|
|
101
|
+
# - src/
|
|
102
|
+
# - test files
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Note:** Examples and full documentation are in the [GitHub repository](https://github.com/mcp-fe/mcp-fe) but not in the npm package.
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
**Last updated:** 2026-02-02
|