@mcp-fe/mcp-worker 0.2.0 → 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.
@@ -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
@@ -1,150 +1,150 @@
1
- # TabManager
2
-
3
- Manages browser tabs and tool registration routing.
4
-
5
- ## API
6
-
7
- ### Tab Management
8
-
9
- ```typescript
10
- // Register tab
11
- tabManager.registerTab(tabId, url, title);
12
-
13
- // Set active tab
14
- tabManager.setActiveTab(tabId);
15
-
16
- // Get active tab
17
- const activeId = tabManager.getActiveTabId(); // → string | null
18
-
19
- // Get all tabs
20
- const tabs = tabManager.getAllTabs(); // → TabInfo[]
21
-
22
- // Remove tab
23
- tabManager.removeTab(tabId); // → boolean
24
- ```
25
-
26
- ### Tool Registration
27
-
28
- ```typescript
29
- // Register tool for tab
30
- const isNew = tabManager.registerToolForTab(toolName, tabId);
31
-
32
- // Unregister tool from tab
33
- const result = tabManager.unregisterToolFromTab(toolName, tabId);
34
- // → { wasRemoved, remainingTabs, wasActiveTab }
35
-
36
- // Get tabs with tool
37
- const tabs = tabManager.getTabsForTool(toolName); // → Set<string>
38
-
39
- // Check if tab has tool
40
- const has = tabManager.tabHasTool(toolName, tabId); // → boolean
41
- ```
42
-
43
- ### Smart Routing
44
-
45
- ```typescript
46
- const route = tabManager.routeToolCall(toolName, explicitTabId?);
47
- // → { targetTabId: string, reason: string } | null
48
- ```
49
-
50
- **Priority:**
51
- 1. Explicit `tabId` (if valid)
52
- 2. Only one tab has tool → use it
53
- 3. Active tab has tool → use it
54
- 4. Use first available
55
-
56
- ### Diagnostics
57
-
58
- ```typescript
59
- // Debug routing
60
- const info = tabManager.getRoutingInfo(toolName);
61
-
62
- // Get stats
63
- const stats = tabManager.getStats();
64
-
65
- // Clear all (testing)
66
- tabManager.clear();
67
- ```
68
-
69
- ## Usage
70
-
71
- ```typescript
72
- import { TabManager } from '@mcp-fe/mcp-worker';
73
-
74
- const tabs = new TabManager();
75
-
76
- // Register tabs
77
- tabs.registerTab('tab-1', '/dashboard', 'Dashboard');
78
- tabs.registerTab('tab-2', '/settings', 'Settings');
79
-
80
- // Register tools
81
- tabs.registerToolForTab('get_data', 'tab-1');
82
- tabs.registerToolForTab('get_data', 'tab-2');
83
-
84
- // Set active
85
- tabs.setActiveTab('tab-1');
86
-
87
- // Route
88
- const route = tabs.routeToolCall('get_data');
89
- // → { targetTabId: 'tab-1', reason: 'active tab has tool' }
90
-
91
- // Route to specific tab
92
- const route2 = tabs.routeToolCall('get_data', 'tab-2');
93
- // → { targetTabId: 'tab-2', reason: 'explicit tabId parameter' }
94
- ```
95
-
96
- ## Integration
97
-
98
- MCPController uses TabManager internally:
99
-
100
- ```typescript
101
- class MCPController {
102
- private tabManager = new TabManager();
103
-
104
- handleRegisterTab(data) {
105
- this.tabManager.registerTab(data.tabId, data.url, data.title);
106
- }
107
-
108
- async handleRegisterToolInternal(toolData) {
109
- const isNew = this.tabManager.registerToolForTab(toolData.name, toolData.tabId);
110
-
111
- if (!isNew) return;
112
-
113
- // Create handler with routing
114
- const handler = async (args) => {
115
- const route = this.tabManager.routeToolCall(toolData.name, args.tabId);
116
- if (!route) throw new Error('Tool not available');
117
-
118
- return this.sendToolCall(route.targetTabId, args);
119
- };
120
-
121
- toolRegistry.register({ name: toolData.name }, handler);
122
- }
123
- }
124
- ```
125
-
126
- ## Why Separate Class?
127
-
128
- - **Separation of Concerns**: Tab logic separate from MCP protocol
129
- - **Testable**: Easy to unit test without MCP dependencies
130
- - **Reusable**: Can be used in other contexts
131
- - **Type Safe**: Strong typing throughout
132
-
133
- ```typescript
134
- // Example test
135
- test('routes to only available tab', () => {
136
- const tabs = new TabManager();
137
- tabs.registerTab('tab-1', '/page', 'Page');
138
- tabs.registerTab('tab-2', '/page', 'Page');
139
- tabs.registerToolForTab('tool', 'tab-1');
140
- tabs.setActiveTab('tab-2'); // Active tab doesn't have tool
141
-
142
- const route = tabs.routeToolCall('tool');
143
- expect(route.targetTabId).toBe('tab-1');
144
- });
145
- ```
146
-
147
- ## See Also
148
-
149
- - [Multi-Tab Guide](./multi-tab.md) - Complete multi-tab docs
150
- - [Architecture](./architecture.md) - System architecture
1
+ # TabManager
2
+
3
+ Manages browser tabs and tool registration routing.
4
+
5
+ ## API
6
+
7
+ ### Tab Management
8
+
9
+ ```typescript
10
+ // Register tab
11
+ tabManager.registerTab(tabId, url, title);
12
+
13
+ // Set active tab
14
+ tabManager.setActiveTab(tabId);
15
+
16
+ // Get active tab
17
+ const activeId = tabManager.getActiveTabId(); // → string | null
18
+
19
+ // Get all tabs
20
+ const tabs = tabManager.getAllTabs(); // → TabInfo[]
21
+
22
+ // Remove tab
23
+ tabManager.removeTab(tabId); // → boolean
24
+ ```
25
+
26
+ ### Tool Registration
27
+
28
+ ```typescript
29
+ // Register tool for tab
30
+ const isNew = tabManager.registerToolForTab(toolName, tabId);
31
+
32
+ // Unregister tool from tab
33
+ const result = tabManager.unregisterToolFromTab(toolName, tabId);
34
+ // → { wasRemoved, remainingTabs, wasActiveTab }
35
+
36
+ // Get tabs with tool
37
+ const tabs = tabManager.getTabsForTool(toolName); // → Set<string>
38
+
39
+ // Check if tab has tool
40
+ const has = tabManager.tabHasTool(toolName, tabId); // → boolean
41
+ ```
42
+
43
+ ### Smart Routing
44
+
45
+ ```typescript
46
+ const route = tabManager.routeToolCall(toolName, explicitTabId?);
47
+ // → { targetTabId: string, reason: string } | null
48
+ ```
49
+
50
+ **Priority:**
51
+ 1. Explicit `tabId` (if valid)
52
+ 2. Only one tab has tool → use it
53
+ 3. Active tab has tool → use it
54
+ 4. Use first available
55
+
56
+ ### Diagnostics
57
+
58
+ ```typescript
59
+ // Debug routing
60
+ const info = tabManager.getRoutingInfo(toolName);
61
+
62
+ // Get stats
63
+ const stats = tabManager.getStats();
64
+
65
+ // Clear all (testing)
66
+ tabManager.clear();
67
+ ```
68
+
69
+ ## Usage
70
+
71
+ ```typescript
72
+ import { TabManager } from '@mcp-fe/mcp-worker';
73
+
74
+ const tabs = new TabManager();
75
+
76
+ // Register tabs
77
+ tabs.registerTab('tab-1', '/dashboard', 'Dashboard');
78
+ tabs.registerTab('tab-2', '/settings', 'Settings');
79
+
80
+ // Register tools
81
+ tabs.registerToolForTab('get_data', 'tab-1');
82
+ tabs.registerToolForTab('get_data', 'tab-2');
83
+
84
+ // Set active
85
+ tabs.setActiveTab('tab-1');
86
+
87
+ // Route
88
+ const route = tabs.routeToolCall('get_data');
89
+ // → { targetTabId: 'tab-1', reason: 'active tab has tool' }
90
+
91
+ // Route to specific tab
92
+ const route2 = tabs.routeToolCall('get_data', 'tab-2');
93
+ // → { targetTabId: 'tab-2', reason: 'explicit tabId parameter' }
94
+ ```
95
+
96
+ ## Integration
97
+
98
+ MCPController uses TabManager internally:
99
+
100
+ ```typescript
101
+ class MCPController {
102
+ private tabManager = new TabManager();
103
+
104
+ handleRegisterTab(data) {
105
+ this.tabManager.registerTab(data.tabId, data.url, data.title);
106
+ }
107
+
108
+ async handleRegisterToolInternal(toolData) {
109
+ const isNew = this.tabManager.registerToolForTab(toolData.name, toolData.tabId);
110
+
111
+ if (!isNew) return;
112
+
113
+ // Create handler with routing
114
+ const handler = async (args) => {
115
+ const route = this.tabManager.routeToolCall(toolData.name, args.tabId);
116
+ if (!route) throw new Error('Tool not available');
117
+
118
+ return this.sendToolCall(route.targetTabId, args);
119
+ };
120
+
121
+ toolRegistry.register({ name: toolData.name }, handler);
122
+ }
123
+ }
124
+ ```
125
+
126
+ ## Why Separate Class?
127
+
128
+ - **Separation of Concerns**: Tab logic separate from MCP protocol
129
+ - **Testable**: Easy to unit test without MCP dependencies
130
+ - **Reusable**: Can be used in other contexts
131
+ - **Type Safe**: Strong typing throughout
132
+
133
+ ```typescript
134
+ // Example test
135
+ test('routes to only available tab', () => {
136
+ const tabs = new TabManager();
137
+ tabs.registerTab('tab-1', '/page', 'Page');
138
+ tabs.registerTab('tab-2', '/page', 'Page');
139
+ tabs.registerToolForTab('tool', 'tab-1');
140
+ tabs.setActiveTab('tab-2'); // Active tab doesn't have tool
141
+
142
+ const route = tabs.routeToolCall('tool');
143
+ expect(route.targetTabId).toBe('tab-1');
144
+ });
145
+ ```
146
+
147
+ ## See Also
148
+
149
+ - [Multi-Tab Guide](./multi-tab.md) - Complete multi-tab docs
150
+ - [Architecture](./architecture.md) - System architecture