@mcp-fe/mcp-worker 0.1.7 → 0.1.8

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.
Files changed (46) hide show
  1. package/README.md +26 -0
  2. package/docs/index.md +15 -4
  3. package/docs/initialization.md +2 -2
  4. package/docs/project-structure.md +172 -0
  5. package/index.js +34 -250
  6. package/mcp-service-worker.js +526 -7468
  7. package/mcp-shared-worker.js +528 -7470
  8. package/package.json +1 -1
  9. package/src/client/index.d.ts +10 -0
  10. package/src/client/index.d.ts.map +1 -0
  11. package/src/client/worker-client.d.ts.map +1 -0
  12. package/src/index.d.ts +3 -7
  13. package/src/index.d.ts.map +1 -1
  14. package/src/shared/database.d.ts +8 -0
  15. package/src/shared/database.d.ts.map +1 -0
  16. package/src/shared/logger.d.ts.map +1 -0
  17. package/src/{lib/tool-registry.d.ts → shared/types.d.ts} +27 -13
  18. package/src/shared/types.d.ts.map +1 -0
  19. package/src/worker/built-in-tools.d.ts.map +1 -0
  20. package/src/worker/index.d.ts +12 -0
  21. package/src/worker/index.d.ts.map +1 -0
  22. package/src/{lib → worker}/mcp-controller.d.ts +2 -1
  23. package/src/worker/mcp-controller.d.ts.map +1 -0
  24. package/src/worker/mcp-server.d.ts.map +1 -0
  25. package/src/{lib → worker}/tab-manager.d.ts +2 -5
  26. package/src/worker/tab-manager.d.ts.map +1 -0
  27. package/src/worker/tool-registry.d.ts +17 -0
  28. package/src/worker/tool-registry.d.ts.map +1 -0
  29. package/src/worker/validation.d.ts +31 -0
  30. package/src/worker/validation.d.ts.map +1 -0
  31. package/src/worker/websocket-transport.d.ts.map +1 -0
  32. package/src/lib/built-in-tools.d.ts.map +0 -1
  33. package/src/lib/database.d.ts +0 -27
  34. package/src/lib/database.d.ts.map +0 -1
  35. package/src/lib/logger.d.ts.map +0 -1
  36. package/src/lib/mcp-controller.d.ts.map +0 -1
  37. package/src/lib/mcp-server.d.ts.map +0 -1
  38. package/src/lib/tab-manager.d.ts.map +0 -1
  39. package/src/lib/tool-registry.d.ts.map +0 -1
  40. package/src/lib/websocket-transport.d.ts.map +0 -1
  41. package/src/lib/worker-client.d.ts.map +0 -1
  42. /package/src/{lib → client}/worker-client.d.ts +0 -0
  43. /package/src/{lib → shared}/logger.d.ts +0 -0
  44. /package/src/{lib → worker}/built-in-tools.d.ts +0 -0
  45. /package/src/{lib → worker}/mcp-server.d.ts +0 -0
  46. /package/src/{lib → worker}/websocket-transport.d.ts +0 -0
package/README.md CHANGED
@@ -67,6 +67,31 @@ Frontend App ←→ WorkerClient ←→ Web Worker ←→ WebSocket ←→ MCP P
67
67
  5. **MCP Proxy** - Bridges browser with AI agents
68
68
  6. **AI Agent** - Queries your app via MCP protocol
69
69
 
70
+ ### Project Structure
71
+
72
+ The library is organized into three main directories:
73
+
74
+ ```
75
+ libs/mcp-worker/src/
76
+ ├── client/ # Client-side code (application runtime)
77
+ │ ├── worker-client.ts # Main WorkerClient class
78
+ │ └── index.ts # Client API exports
79
+ ├── worker/ # Worker-side code (background processing)
80
+ │ ├── mcp-controller.ts # MCP server controller
81
+ │ ├── mcp-server.ts # MCP server setup
82
+ │ ├── tab-manager.ts # Multi-tab coordination
83
+ │ ├── tool-registry.ts # Dynamic tool management
84
+ │ └── built-in-tools.ts # Default MCP tools
85
+ └── shared/ # Shared code (both contexts)
86
+ ├── types.ts # TypeScript type definitions
87
+ ├── logger.ts # Logging utilities
88
+ └── database.ts # IndexedDB operations
89
+ ```
90
+
91
+ **Entry points:**
92
+ - `mcp-shared-worker.ts` - SharedWorker implementation (preferred)
93
+ - `mcp-service-worker.ts` - ServiceWorker fallback
94
+
70
95
  ## Quick Start
71
96
 
72
97
  ### Installation
@@ -130,6 +155,7 @@ await workerClient.registerTool(
130
155
 
131
156
  - **[Quick Start Guide](./docs/guide.md)** - Complete guide to dynamic tool registration
132
157
  - **[API Reference](./docs/api.md)** - Full API documentation
158
+ - **[Project Structure](./docs/project-structure.md)** - Codebase organization explained
133
159
  - **[Worker Details](./docs/worker-details.md)** - Implementation details
134
160
  - **[Architecture](./docs/architecture.md)** - How the proxy pattern works
135
161
  - **[Initialization](./docs/initialization.md)** - Init queue handling
package/docs/index.md CHANGED
@@ -12,6 +12,7 @@ Complete guide to all documentation and examples in the MCP Worker library.
12
12
  | **Complete API reference** | [API Reference](./api.md) |
13
13
  | **Multi-tab applications** | [Multi-Tab Guide](./multi-tab.md) |
14
14
  | **Worker implementation** | [Worker Details](./worker-details.md) |
15
+ | **Understand codebase structure** | [Project Structure](./project-structure.md) |
15
16
  | **Use with React** | [React Hooks Guide](../../react-event-tracker/REACT_MCP_TOOLS.md) |
16
17
  | **Understand architecture** | [Architecture](./architecture.md) |
17
18
  | **Handle initialization** | [Initialization](./initialization.md) |
@@ -29,16 +30,26 @@ libs/mcp-worker/
29
30
  │ ├── multi-tab.md ← Multi-tab support
30
31
  │ ├── worker-details.md ← Worker implementation
31
32
  │ ├── architecture.md ← Technical architecture
32
- └── initialization.md ← Init handling
33
+ ├── initialization.md ← Init handling
34
+ │ ├── project-structure.md ← Codebase organization
35
+ │ └── tab-manager.md ← Tab management
33
36
 
34
37
  ├── examples/ ← Code examples
35
38
  │ ├── README.md ← Examples guide
36
39
  │ ├── quick-start.ts ← Simple examples
37
- └── dynamic-tools.ts ← Advanced patterns
40
+ ├── dynamic-tools.ts ← Advanced patterns
41
+ │ └── structured-output.ts ← Structured outputs
38
42
 
39
43
  └── src/ ← Source code
40
- └── lib/
41
- └── worker-client.ts
44
+ ├── client/ ← Application runtime
45
+ └── worker-client.ts
46
+ ├── worker/ ← Worker implementation
47
+ │ ├── mcp-controller.ts
48
+ │ └── ...
49
+ └── shared/ ← Shared utilities
50
+ ├── types.ts
51
+ ├── logger.ts
52
+ └── database.ts
42
53
 
43
54
  libs/react-event-tracker/
44
55
  ├── REACT_MCP_TOOLS.md ← React hooks docs
@@ -182,7 +182,7 @@ For contributors:
182
182
  - Queues are processed in order (FIFO)
183
183
 
184
184
  See source code for implementation details:
185
- - `libs/mcp-worker/src/lib/worker-client.ts`
186
- - `libs/mcp-worker/src/lib/mcp-controller.ts`
185
+ - `libs/mcp-worker/src/client/worker-client.ts`
186
+ - `libs/mcp-worker/src/worker/mcp-controller.ts`
187
187
 
188
188
 
@@ -0,0 +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
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // libs/mcp-worker/src/lib/logger.ts
1
+ // libs/mcp-worker/src/shared/logger.ts
2
2
  var isProduction = typeof process !== "undefined" && true;
3
3
  var mcpDebug = typeof process !== "undefined" && process.env?.["MCP_DEBUG"];
4
4
  var debugEnabled = mcpDebug === "true" || !isProduction && mcpDebug !== "false";
@@ -26,7 +26,7 @@ var logger = {
26
26
  }
27
27
  };
28
28
 
29
- // libs/mcp-worker/src/lib/worker-client.ts
29
+ // libs/mcp-worker/src/client/worker-client.ts
30
30
  var WorkerClient = class _WorkerClient {
31
31
  // Configurable worker script URLs (defaults kept for backward compatibility)
32
32
  sharedWorkerUrl = "/mcp-shared-worker.js";
@@ -1046,7 +1046,10 @@ var WorkerClient = class _WorkerClient {
1046
1046
  }
1047
1047
  };
1048
1048
 
1049
- // libs/mcp-worker/src/lib/database.ts
1049
+ // libs/mcp-worker/src/client/index.ts
1050
+ var workerClient = new WorkerClient();
1051
+
1052
+ // libs/mcp-worker/src/shared/database.ts
1050
1053
  var DB_NAME = "user-activity-db";
1051
1054
  var DB_VERSION = 1;
1052
1055
  var STORE_NAME = "user-events";
@@ -1066,6 +1069,33 @@ async function initDB() {
1066
1069
  };
1067
1070
  });
1068
1071
  }
1072
+ async function storeEvent(event) {
1073
+ const db = await initDB();
1074
+ const transaction = db.transaction([STORE_NAME], "readwrite");
1075
+ const store = transaction.objectStore(STORE_NAME);
1076
+ const eventWithId = {
1077
+ ...event,
1078
+ id: `${event.timestamp}-${Math.random().toString(36).substr(2, 9)}`
1079
+ };
1080
+ await new Promise((resolve, reject) => {
1081
+ const request = store.add(eventWithId);
1082
+ request.onsuccess = () => resolve();
1083
+ request.onerror = () => reject(request.error);
1084
+ });
1085
+ const countRequest = store.count();
1086
+ countRequest.onsuccess = () => {
1087
+ if (countRequest.result > 1e3) {
1088
+ const index = store.index("timestamp");
1089
+ const getAllRequest = index.getAll();
1090
+ getAllRequest.onsuccess = () => {
1091
+ const events = getAllRequest.result;
1092
+ events.sort((a, b) => a.timestamp - b.timestamp);
1093
+ const toDelete = events.slice(0, events.length - 1e3);
1094
+ toDelete.forEach((event2) => store.delete(event2.id));
1095
+ };
1096
+ }
1097
+ };
1098
+ }
1069
1099
  async function queryEvents(filters) {
1070
1100
  const db = await initDB();
1071
1101
  const transaction = db.transaction([STORE_NAME], "readonly");
@@ -1096,256 +1126,10 @@ async function queryEvents(filters) {
1096
1126
  request.onerror = () => reject(request.error);
1097
1127
  });
1098
1128
  }
1099
-
1100
- // libs/mcp-worker/src/lib/tab-manager.ts
1101
- var TabManager = class {
1102
- // Registry of all active tabs
1103
- tabRegistry = /* @__PURE__ */ new Map();
1104
- // Currently active/focused tab
1105
- activeTabId = null;
1106
- // Tool handlers per tab: Map<ToolName, Set<TabId>>
1107
- toolHandlersByTab = /* @__PURE__ */ new Map();
1108
- /**
1109
- * Register a new tab
1110
- */
1111
- registerTab(tabId, url, title) {
1112
- if (!tabId) {
1113
- logger.warn("[TabManager] Cannot register tab: missing tabId");
1114
- return;
1115
- }
1116
- this.tabRegistry.set(tabId, {
1117
- url: url || "",
1118
- title: title || "",
1119
- lastSeen: Date.now()
1120
- });
1121
- logger.log(`[TabManager] Registered tab: ${tabId} (${title})`);
1122
- }
1123
- /**
1124
- * Set the active/focused tab
1125
- */
1126
- setActiveTab(tabId) {
1127
- if (!tabId) {
1128
- logger.warn("[TabManager] Cannot set active tab: missing tabId");
1129
- return;
1130
- }
1131
- this.activeTabId = tabId;
1132
- logger.log(`[TabManager] Active tab changed: ${tabId}`);
1133
- const tab = this.tabRegistry.get(tabId);
1134
- if (tab) {
1135
- tab.lastSeen = Date.now();
1136
- }
1137
- }
1138
- /**
1139
- * Get the currently active tab ID
1140
- */
1141
- getActiveTabId() {
1142
- return this.activeTabId;
1143
- }
1144
- /**
1145
- * Get all registered tabs
1146
- */
1147
- getAllTabs() {
1148
- return Array.from(this.tabRegistry.entries()).map(([tabId, info]) => ({
1149
- tabId,
1150
- ...info
1151
- }));
1152
- }
1153
- /**
1154
- * Get tab info by ID
1155
- */
1156
- getTabInfo(tabId) {
1157
- return this.tabRegistry.get(tabId);
1158
- }
1159
- /**
1160
- * Check if tab exists
1161
- */
1162
- hasTab(tabId) {
1163
- return this.tabRegistry.has(tabId);
1164
- }
1165
- /**
1166
- * Remove a tab from registry
1167
- */
1168
- removeTab(tabId) {
1169
- const existed = this.tabRegistry.delete(tabId);
1170
- if (existed) {
1171
- logger.log(`[TabManager] Removed tab: ${tabId}`);
1172
- if (this.activeTabId === tabId) {
1173
- this.activeTabId = null;
1174
- }
1175
- this.cleanupTabTools(tabId);
1176
- }
1177
- return existed;
1178
- }
1179
- /**
1180
- * Register a tool for a specific tab
1181
- */
1182
- registerToolForTab(toolName, tabId) {
1183
- if (!this.toolHandlersByTab.has(toolName)) {
1184
- this.toolHandlersByTab.set(toolName, /* @__PURE__ */ new Set());
1185
- }
1186
- const tabHandlers = this.toolHandlersByTab.get(toolName);
1187
- const isNewTab = !tabHandlers.has(tabId);
1188
- tabHandlers.add(tabId);
1189
- if (isNewTab) {
1190
- logger.log(
1191
- `[TabManager] Tab ${tabId} registered tool '${toolName}' (${tabHandlers.size} tab(s) total)`
1192
- );
1193
- } else {
1194
- logger.log(
1195
- `[TabManager] Tab ${tabId} re-registered tool '${toolName}' (already tracked)`
1196
- );
1197
- }
1198
- return isNewTab;
1199
- }
1200
- /**
1201
- * Unregister a tool from a specific tab
1202
- */
1203
- unregisterToolFromTab(toolName, tabId) {
1204
- const tabHandlers = this.toolHandlersByTab.get(toolName);
1205
- if (!tabHandlers || !tabHandlers.has(tabId)) {
1206
- return { wasRemoved: false, remainingTabs: 0, wasActiveTab: false };
1207
- }
1208
- const wasActiveTab = tabId === this.activeTabId;
1209
- tabHandlers.delete(tabId);
1210
- const remainingTabs = tabHandlers.size;
1211
- logger.log(
1212
- `[TabManager] Removed tab ${tabId} from tool '${toolName}' (${remainingTabs} tab(s) remaining)`
1213
- );
1214
- if (remainingTabs === 0) {
1215
- this.toolHandlersByTab.delete(toolName);
1216
- }
1217
- return { wasRemoved: true, remainingTabs, wasActiveTab };
1218
- }
1219
- /**
1220
- * Get all tabs that have a specific tool
1221
- */
1222
- getTabsForTool(toolName) {
1223
- return this.toolHandlersByTab.get(toolName) || /* @__PURE__ */ new Set();
1224
- }
1225
- /**
1226
- * Check if a tab has a specific tool
1227
- */
1228
- tabHasTool(toolName, tabId) {
1229
- const tabHandlers = this.toolHandlersByTab.get(toolName);
1230
- return tabHandlers ? tabHandlers.has(tabId) : false;
1231
- }
1232
- /**
1233
- * Smart routing: determine which tab should handle a tool call
1234
- *
1235
- * Priority:
1236
- * 1. Explicit tabId parameter (if provided and valid)
1237
- * 2. Only one tab has tool -> use it (regardless of focus)
1238
- * 3. Active tab has tool -> use it
1239
- * 4. Active tab doesn't have tool -> use first available
1240
- * 5. No active tab -> use first available
1241
- */
1242
- routeToolCall(toolName, explicitTabId) {
1243
- const tabHandlers = this.toolHandlersByTab.get(toolName);
1244
- if (!tabHandlers || tabHandlers.size === 0) {
1245
- return null;
1246
- }
1247
- if (explicitTabId) {
1248
- if (tabHandlers.has(explicitTabId)) {
1249
- return {
1250
- targetTabId: explicitTabId,
1251
- reason: "explicit tabId parameter"
1252
- };
1253
- } else {
1254
- return null;
1255
- }
1256
- }
1257
- if (tabHandlers.size === 1) {
1258
- const targetTabId = tabHandlers.values().next().value;
1259
- return {
1260
- targetTabId,
1261
- reason: "only one tab has tool"
1262
- };
1263
- }
1264
- if (this.activeTabId && tabHandlers.has(this.activeTabId)) {
1265
- return {
1266
- targetTabId: this.activeTabId,
1267
- reason: "active tab has tool"
1268
- };
1269
- }
1270
- const firstTab = tabHandlers.values().next().value;
1271
- const reason = this.activeTabId ? "active tab lacks tool, using first available" : "no active tab, using first available";
1272
- return {
1273
- targetTabId: firstTab,
1274
- reason
1275
- };
1276
- }
1277
- /**
1278
- * Get routing statistics for debugging
1279
- */
1280
- getRoutingInfo(toolName) {
1281
- const tabHandlers = this.toolHandlersByTab.get(toolName);
1282
- const tabsWithTool = tabHandlers ? Array.from(tabHandlers) : [];
1283
- return {
1284
- toolExists: tabsWithTool.length > 0,
1285
- tabsWithTool,
1286
- activeTabHasTool: this.activeTabId ? this.tabHasTool(toolName, this.activeTabId) : false,
1287
- recommendedTab: this.routeToolCall(toolName)?.targetTabId || null
1288
- };
1289
- }
1290
- /**
1291
- * Clean up all tools for a specific tab
1292
- * @private
1293
- */
1294
- cleanupTabTools(tabId) {
1295
- const removedTools = [];
1296
- for (const [toolName, tabHandlers] of this.toolHandlersByTab.entries()) {
1297
- if (tabHandlers.has(tabId)) {
1298
- tabHandlers.delete(tabId);
1299
- removedTools.push(toolName);
1300
- if (tabHandlers.size === 0) {
1301
- this.toolHandlersByTab.delete(toolName);
1302
- }
1303
- }
1304
- }
1305
- if (removedTools.length > 0) {
1306
- logger.log(
1307
- `[TabManager] Cleaned up ${removedTools.length} tool(s) for tab ${tabId}: ${removedTools.join(", ")}`
1308
- );
1309
- }
1310
- }
1311
- /**
1312
- * Get statistics for monitoring
1313
- */
1314
- getStats() {
1315
- const toolsPerTab = {};
1316
- for (const [tabId] of this.tabRegistry) {
1317
- let toolCount = 0;
1318
- for (const tabHandlers of this.toolHandlersByTab.values()) {
1319
- if (tabHandlers.has(tabId)) {
1320
- toolCount++;
1321
- }
1322
- }
1323
- toolsPerTab[tabId] = toolCount;
1324
- }
1325
- return {
1326
- totalTabs: this.tabRegistry.size,
1327
- activeTabId: this.activeTabId,
1328
- totalTools: this.toolHandlersByTab.size,
1329
- toolsPerTab
1330
- };
1331
- }
1332
- /**
1333
- * Clear all data (for testing)
1334
- */
1335
- clear() {
1336
- this.tabRegistry.clear();
1337
- this.activeTabId = null;
1338
- this.toolHandlersByTab.clear();
1339
- logger.log("[TabManager] Cleared all data");
1340
- }
1341
- };
1342
-
1343
- // libs/mcp-worker/src/index.ts
1344
- var workerClient = new WorkerClient();
1345
1129
  export {
1346
- TabManager,
1347
1130
  WorkerClient,
1348
1131
  logger,
1349
1132
  queryEvents,
1133
+ storeEvent,
1350
1134
  workerClient
1351
1135
  };