mcp-use 1.11.0-canary.8 → 1.11.0

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 (91) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{chunk-5RTMAOZ6.js → chunk-A4QJRN7Z.js} +5 -1041
  3. package/dist/{chunk-4LZSXUFM.js → chunk-B7AGEK7F.js} +1 -1
  4. package/dist/{chunk-TAEHPLGV.js → chunk-GN5HOAV3.js} +664 -136
  5. package/dist/chunk-QPIDKGV4.js +1246 -0
  6. package/dist/chunk-UWWLWLS2.js +62 -0
  7. package/dist/{chunk-ZFZPZ4GE.js → chunk-V77WS6CS.js} +9 -0
  8. package/dist/{chunk-EBSNALCB.js → chunk-VRHAF2WT.js} +10 -4
  9. package/dist/{chunk-X7JKFBPN.js → chunk-Y2HHHJQB.js} +159 -8
  10. package/dist/{chunk-JPKFN73V.js → chunk-ZLZOOXMJ.js} +96 -43
  11. package/dist/index.cjs +316 -53
  12. package/dist/index.js +22 -24
  13. package/dist/notifications-FLGIFS56.js +9 -0
  14. package/dist/src/agents/index.cjs +153 -47
  15. package/dist/src/agents/index.d.ts +1 -1
  16. package/dist/src/agents/index.d.ts.map +1 -1
  17. package/dist/src/agents/index.js +7 -10
  18. package/dist/src/agents/mcp_agent.d.ts.map +1 -1
  19. package/dist/src/{client/prompts.d.ts → agents/prompts/index.d.ts} +3 -3
  20. package/dist/src/agents/prompts/index.d.ts.map +1 -0
  21. package/dist/src/browser.cjs +160 -48
  22. package/dist/src/browser.js +10 -12
  23. package/dist/src/client/browser.d.ts.map +1 -1
  24. package/dist/src/client.cjs +3852 -0
  25. package/dist/src/client.d.ts +2 -0
  26. package/dist/src/client.d.ts.map +1 -1
  27. package/dist/src/client.js +21 -0
  28. package/dist/src/config.d.ts.map +1 -1
  29. package/dist/src/connectors/http.d.ts +2 -0
  30. package/dist/src/connectors/http.d.ts.map +1 -1
  31. package/dist/src/react/index.cjs +313 -52
  32. package/dist/src/react/index.js +7 -8
  33. package/dist/src/react/types.d.ts +41 -1
  34. package/dist/src/react/types.d.ts.map +1 -1
  35. package/dist/src/react/useMcp.d.ts.map +1 -1
  36. package/dist/src/server/endpoints/mount-mcp.d.ts.map +1 -1
  37. package/dist/src/server/index.cjs +1339 -256
  38. package/dist/src/server/index.d.ts +2 -0
  39. package/dist/src/server/index.d.ts.map +1 -1
  40. package/dist/src/server/index.js +1119 -156
  41. package/dist/src/server/mcp-server.d.ts +4 -1
  42. package/dist/src/server/mcp-server.d.ts.map +1 -1
  43. package/dist/src/server/notifications/index.d.ts +1 -1
  44. package/dist/src/server/notifications/index.d.ts.map +1 -1
  45. package/dist/src/server/notifications/notification-registration.d.ts +51 -0
  46. package/dist/src/server/notifications/notification-registration.d.ts.map +1 -1
  47. package/dist/src/server/sessions/index.d.ts +3 -1
  48. package/dist/src/server/sessions/index.d.ts.map +1 -1
  49. package/dist/src/server/sessions/session-manager.d.ts +30 -16
  50. package/dist/src/server/sessions/session-manager.d.ts.map +1 -1
  51. package/dist/src/server/sessions/stores/filesystem.d.ts +121 -0
  52. package/dist/src/server/sessions/stores/filesystem.d.ts.map +1 -0
  53. package/dist/src/server/sessions/stores/index.d.ts +94 -0
  54. package/dist/src/server/sessions/stores/index.d.ts.map +1 -0
  55. package/dist/src/server/sessions/stores/memory.d.ts +82 -0
  56. package/dist/src/server/sessions/stores/memory.d.ts.map +1 -0
  57. package/dist/src/server/sessions/stores/redis.d.ts +164 -0
  58. package/dist/src/server/sessions/stores/redis.d.ts.map +1 -0
  59. package/dist/src/server/sessions/streams/index.d.ts +77 -0
  60. package/dist/src/server/sessions/streams/index.d.ts.map +1 -0
  61. package/dist/src/server/sessions/streams/memory.d.ts +76 -0
  62. package/dist/src/server/sessions/streams/memory.d.ts.map +1 -0
  63. package/dist/src/server/sessions/streams/redis.d.ts +146 -0
  64. package/dist/src/server/sessions/streams/redis.d.ts.map +1 -0
  65. package/dist/src/server/types/common.d.ts +82 -28
  66. package/dist/src/server/types/common.d.ts.map +1 -1
  67. package/dist/src/server/types/widget.d.ts +2 -2
  68. package/dist/src/server/types/widget.d.ts.map +1 -1
  69. package/dist/src/server/utils/response-helpers.d.ts +4 -2
  70. package/dist/src/server/utils/response-helpers.d.ts.map +1 -1
  71. package/dist/src/server/widgets/mount-widgets-dev.d.ts.map +1 -1
  72. package/dist/src/server/widgets/ui-resource-registration.d.ts.map +1 -1
  73. package/dist/src/task_managers/index.d.ts +10 -0
  74. package/dist/src/task_managers/index.d.ts.map +1 -1
  75. package/dist/src/task_managers/sse.d.ts +34 -1
  76. package/dist/src/task_managers/sse.d.ts.map +1 -1
  77. package/dist/src/task_managers/streamable_http.d.ts +8 -2
  78. package/dist/src/task_managers/streamable_http.d.ts.map +1 -1
  79. package/dist/src/telemetry/telemetry.d.ts +1 -0
  80. package/dist/src/telemetry/telemetry.d.ts.map +1 -1
  81. package/dist/src/version.d.ts +1 -1
  82. package/dist/src/version.d.ts.map +1 -1
  83. package/dist/{tool-execution-helpers-EYAIJERC.js → tool-execution-helpers-ZUA5D5IO.js} +2 -2
  84. package/dist/tsup.config.d.ts.map +1 -1
  85. package/package.json +62 -52
  86. package/dist/chunk-GVU7C2ZD.js +0 -12
  87. package/dist/chunk-JZNXOM7C.js +0 -204
  88. package/dist/chunk-XKTBHYNM.js +0 -491
  89. package/dist/src/client/prompts.cjs +0 -407
  90. package/dist/src/client/prompts.d.ts.map +0 -1
  91. package/dist/src/client/prompts.js +0 -11
@@ -0,0 +1,1246 @@
1
+ import {
2
+ BaseConnector,
3
+ BaseMCPClient,
4
+ ConnectionManager,
5
+ HttpConnector,
6
+ MCPSession
7
+ } from "./chunk-GN5HOAV3.js";
8
+ import {
9
+ Tel,
10
+ getPackageVersion
11
+ } from "./chunk-ZLZOOXMJ.js";
12
+ import {
13
+ logger
14
+ } from "./chunk-FRUZDWXH.js";
15
+ import {
16
+ __name,
17
+ __require
18
+ } from "./chunk-3GQAWCBQ.js";
19
+
20
+ // src/client.ts
21
+ import fs from "fs";
22
+ import path from "path";
23
+
24
+ // src/client/executors/base.ts
25
+ var BaseCodeExecutor = class {
26
+ static {
27
+ __name(this, "BaseCodeExecutor");
28
+ }
29
+ client;
30
+ _connecting = false;
31
+ constructor(client) {
32
+ this.client = client;
33
+ }
34
+ /**
35
+ * Ensure all configured MCP servers are connected before execution.
36
+ * Prevents race conditions with a connection lock.
37
+ */
38
+ async ensureServersConnected() {
39
+ const configuredServers = this.client.getServerNames();
40
+ const activeSessions = Object.keys(this.client.getAllActiveSessions());
41
+ const missingServers = configuredServers.filter(
42
+ (s) => !activeSessions.includes(s)
43
+ );
44
+ if (missingServers.length > 0 && !this._connecting) {
45
+ this._connecting = true;
46
+ try {
47
+ logger.debug(
48
+ `Connecting to configured servers for code execution: ${missingServers.join(", ")}`
49
+ );
50
+ await this.client.createAllSessions();
51
+ } finally {
52
+ this._connecting = false;
53
+ }
54
+ } else if (missingServers.length > 0 && this._connecting) {
55
+ logger.debug("Waiting for ongoing server connection...");
56
+ const startWait = Date.now();
57
+ while (this._connecting && Date.now() - startWait < 5e3) {
58
+ await new Promise((resolve) => setTimeout(resolve, 100));
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * Get tool namespace information from all active MCP sessions.
64
+ * Filters out the internal code_mode server.
65
+ */
66
+ getToolNamespaces() {
67
+ const namespaces = [];
68
+ const activeSessions = this.client.getAllActiveSessions();
69
+ for (const [serverName, session] of Object.entries(activeSessions)) {
70
+ if (serverName === "code_mode") continue;
71
+ try {
72
+ const connector = session.connector;
73
+ let tools;
74
+ try {
75
+ tools = connector.tools;
76
+ } catch (e) {
77
+ logger.warn(`Tools not available for server ${serverName}: ${e}`);
78
+ continue;
79
+ }
80
+ if (!tools || tools.length === 0) continue;
81
+ namespaces.push({ serverName, tools, session });
82
+ } catch (e) {
83
+ logger.warn(`Failed to load tools for server ${serverName}: ${e}`);
84
+ }
85
+ }
86
+ return namespaces;
87
+ }
88
+ /**
89
+ * Create a search function for discovering available MCP tools.
90
+ * Used by code execution environments to find tools at runtime.
91
+ */
92
+ createSearchToolsFunction() {
93
+ return async (query = "", detailLevel = "full") => {
94
+ const allTools = [];
95
+ const allNamespaces = /* @__PURE__ */ new Set();
96
+ const queryLower = query.toLowerCase();
97
+ const activeSessions = this.client.getAllActiveSessions();
98
+ for (const [serverName, session] of Object.entries(activeSessions)) {
99
+ if (serverName === "code_mode") continue;
100
+ try {
101
+ const tools = session.connector.tools;
102
+ if (tools && tools.length > 0) {
103
+ allNamespaces.add(serverName);
104
+ }
105
+ for (const tool of tools) {
106
+ if (detailLevel === "names") {
107
+ allTools.push({ name: tool.name, server: serverName });
108
+ } else if (detailLevel === "descriptions") {
109
+ allTools.push({
110
+ name: tool.name,
111
+ server: serverName,
112
+ description: tool.description
113
+ });
114
+ } else {
115
+ allTools.push({
116
+ name: tool.name,
117
+ server: serverName,
118
+ description: tool.description,
119
+ input_schema: tool.inputSchema
120
+ });
121
+ }
122
+ }
123
+ } catch (e) {
124
+ logger.warn(`Failed to search tools in server ${serverName}: ${e}`);
125
+ }
126
+ }
127
+ let filteredTools = allTools;
128
+ if (query) {
129
+ filteredTools = allTools.filter((tool) => {
130
+ const nameMatch = tool.name.toLowerCase().includes(queryLower);
131
+ const descMatch = tool.description?.toLowerCase().includes(queryLower);
132
+ const serverMatch = tool.server.toLowerCase().includes(queryLower);
133
+ return nameMatch || descMatch || serverMatch;
134
+ });
135
+ }
136
+ return {
137
+ meta: {
138
+ total_tools: allTools.length,
139
+ namespaces: Array.from(allNamespaces).sort(),
140
+ result_count: filteredTools.length
141
+ },
142
+ results: filteredTools
143
+ };
144
+ };
145
+ }
146
+ };
147
+
148
+ // src/client/executors/e2b.ts
149
+ var E2BCodeExecutor = class extends BaseCodeExecutor {
150
+ static {
151
+ __name(this, "E2BCodeExecutor");
152
+ }
153
+ e2bApiKey;
154
+ codeExecSandbox = null;
155
+ SandboxClass = null;
156
+ timeoutMs;
157
+ constructor(client, options) {
158
+ super(client);
159
+ this.e2bApiKey = options.apiKey;
160
+ this.timeoutMs = options.timeoutMs ?? 3e5;
161
+ }
162
+ /**
163
+ * Lazy load E2B Sandbox class.
164
+ * This allows the library to work without E2B installed.
165
+ */
166
+ async ensureSandboxClass() {
167
+ if (this.SandboxClass) return;
168
+ try {
169
+ const e2b = await import("@e2b/code-interpreter");
170
+ this.SandboxClass = e2b.Sandbox;
171
+ } catch (error) {
172
+ throw new Error(
173
+ "@e2b/code-interpreter is not installed. The E2B code executor requires this optional dependency. Install it with: yarn add @e2b/code-interpreter"
174
+ );
175
+ }
176
+ }
177
+ /**
178
+ * Get or create a dedicated sandbox for code execution.
179
+ */
180
+ async getOrCreateCodeExecSandbox() {
181
+ if (this.codeExecSandbox) return this.codeExecSandbox;
182
+ await this.ensureSandboxClass();
183
+ logger.debug("Starting E2B sandbox for code execution...");
184
+ this.codeExecSandbox = await this.SandboxClass.create("base", {
185
+ apiKey: this.e2bApiKey,
186
+ timeoutMs: this.timeoutMs
187
+ });
188
+ return this.codeExecSandbox;
189
+ }
190
+ /**
191
+ * Generate the shim code that exposes tools to the sandbox environment.
192
+ * Creates a bridge that intercepts tool calls and sends them back to host.
193
+ */
194
+ generateShim(tools) {
195
+ let shim = `
196
+ // MCP Bridge Shim
197
+ global.__callMcpTool = async (server, tool, args) => {
198
+ const id = Math.random().toString(36).substring(7);
199
+ console.log(JSON.stringify({
200
+ type: '__MCP_TOOL_CALL__',
201
+ id,
202
+ server,
203
+ tool,
204
+ args
205
+ }));
206
+
207
+ const resultPath = \`/tmp/mcp_result_\${id}.json\`;
208
+ const fs = require('fs');
209
+
210
+ // Poll for result file
211
+ let attempts = 0;
212
+ while (attempts < 300) { // 30 seconds timeout
213
+ if (fs.existsSync(resultPath)) {
214
+ const content = fs.readFileSync(resultPath, 'utf8');
215
+ const result = JSON.parse(content);
216
+ fs.unlinkSync(resultPath); // Clean up
217
+
218
+ if (result.error) {
219
+ throw new Error(result.error);
220
+ }
221
+ return result.data;
222
+ }
223
+ await new Promise(resolve => setTimeout(resolve, 100));
224
+ attempts++;
225
+ }
226
+ throw new Error('Tool execution timed out');
227
+ };
228
+
229
+ // Global search_tools helper
230
+ global.search_tools = async (query, detailLevel = 'full') => {
231
+ const allTools = ${JSON.stringify(
232
+ Object.entries(tools).flatMap(
233
+ ([server, serverTools]) => serverTools.map((tool) => ({
234
+ name: tool.name,
235
+ description: tool.description,
236
+ server,
237
+ input_schema: tool.inputSchema
238
+ }))
239
+ )
240
+ )};
241
+
242
+ const filtered = allTools.filter(tool => {
243
+ if (!query) return true;
244
+ const q = query.toLowerCase();
245
+ return tool.name.toLowerCase().includes(q) ||
246
+ (tool.description && tool.description.toLowerCase().includes(q));
247
+ });
248
+
249
+ if (detailLevel === 'names') {
250
+ return filtered.map(t => ({ name: t.name, server: t.server }));
251
+ } else if (detailLevel === 'descriptions') {
252
+ return filtered.map(t => ({ name: t.name, server: t.server, description: t.description }));
253
+ }
254
+ return filtered;
255
+ };
256
+ `;
257
+ for (const [serverName, serverTools] of Object.entries(tools)) {
258
+ if (!serverTools || serverTools.length === 0) continue;
259
+ const safeServerName = serverName.replace(/[^a-zA-Z0-9_]/g, "_");
260
+ shim += `
261
+ global['${serverName}'] = {`;
262
+ for (const tool of serverTools) {
263
+ shim += `
264
+ '${tool.name}': async (args) => await global.__callMcpTool('${serverName}', '${tool.name}', args),`;
265
+ }
266
+ shim += `
267
+ };
268
+
269
+ // Also expose as safe name if different
270
+ if ('${safeServerName}' !== '${serverName}') {
271
+ global['${safeServerName}'] = global['${serverName}'];
272
+ }
273
+ `;
274
+ }
275
+ return shim;
276
+ }
277
+ /**
278
+ * Build the tool catalog for the shim.
279
+ * Returns a map of server names to their available tools.
280
+ */
281
+ buildToolCatalog() {
282
+ const catalog = {};
283
+ const namespaces = this.getToolNamespaces();
284
+ for (const { serverName, tools } of namespaces) {
285
+ catalog[serverName] = tools;
286
+ }
287
+ return catalog;
288
+ }
289
+ /**
290
+ * Execute JavaScript/TypeScript code in an E2B sandbox with MCP tool access.
291
+ * Tool calls are proxied back to the host via the bridge pattern.
292
+ *
293
+ * @param code - Code to execute
294
+ * @param timeout - Execution timeout in milliseconds (default: 30000)
295
+ */
296
+ async execute(code, timeout = 3e4) {
297
+ const startTime = Date.now();
298
+ let result = null;
299
+ let error = null;
300
+ let logs = [];
301
+ try {
302
+ await this.ensureServersConnected();
303
+ const sandbox = await this.getOrCreateCodeExecSandbox();
304
+ const toolCatalog = this.buildToolCatalog();
305
+ const shim = this.generateShim(toolCatalog);
306
+ const wrappedCode = `
307
+ ${shim}
308
+
309
+ (async () => {
310
+ try {
311
+ const func = async () => {
312
+ ${code}
313
+ };
314
+ const result = await func();
315
+ console.log('__MCP_RESULT_START__');
316
+ console.log(JSON.stringify(result));
317
+ console.log('__MCP_RESULT_END__');
318
+ } catch (e) {
319
+ console.error(e);
320
+ process.exit(1);
321
+ }
322
+ })();
323
+ `;
324
+ const filename = `exec_${Date.now()}.js`;
325
+ await sandbox.files.write(filename, wrappedCode);
326
+ const execution = await sandbox.commands.run(`node ${filename}`, {
327
+ timeoutMs: timeout,
328
+ onStdout: /* @__PURE__ */ __name(async (data) => {
329
+ try {
330
+ const lines = data.split("\n");
331
+ for (const line of lines) {
332
+ if (line.trim().startsWith('{"type":"__MCP_TOOL_CALL__"')) {
333
+ const call = JSON.parse(line);
334
+ if (call.type === "__MCP_TOOL_CALL__") {
335
+ try {
336
+ logger.debug(
337
+ `[E2B Bridge] Calling tool ${call.server}.${call.tool}`
338
+ );
339
+ const activeSessions = this.client.getAllActiveSessions();
340
+ const session = activeSessions[call.server];
341
+ if (!session) {
342
+ throw new Error(`Server ${call.server} not found`);
343
+ }
344
+ const toolResult = await session.connector.callTool(
345
+ call.tool,
346
+ call.args
347
+ );
348
+ let extractedResult = toolResult;
349
+ if (toolResult.content && toolResult.content.length > 0) {
350
+ const item = toolResult.content[0];
351
+ if (item.type === "text") {
352
+ try {
353
+ extractedResult = JSON.parse(item.text);
354
+ } catch {
355
+ extractedResult = item.text;
356
+ }
357
+ } else {
358
+ extractedResult = item;
359
+ }
360
+ }
361
+ const resultPath = `/tmp/mcp_result_${call.id}.json`;
362
+ await sandbox.files.write(
363
+ resultPath,
364
+ JSON.stringify({ data: extractedResult })
365
+ );
366
+ } catch (err) {
367
+ logger.error(
368
+ `[E2B Bridge] Tool execution failed: ${err.message}`
369
+ );
370
+ const resultPath = `/tmp/mcp_result_${call.id}.json`;
371
+ await sandbox.files.write(
372
+ resultPath,
373
+ JSON.stringify({
374
+ error: err.message || String(err)
375
+ })
376
+ );
377
+ }
378
+ }
379
+ }
380
+ }
381
+ } catch (e) {
382
+ }
383
+ }, "onStdout")
384
+ });
385
+ logs = [execution.stdout, execution.stderr].filter(Boolean);
386
+ if (execution.exitCode !== 0) {
387
+ error = execution.stderr || "Execution failed";
388
+ } else {
389
+ const stdout = execution.stdout;
390
+ const startMarker = "__MCP_RESULT_START__";
391
+ const endMarker = "__MCP_RESULT_END__";
392
+ const startIndex = stdout.indexOf(startMarker);
393
+ const endIndex = stdout.indexOf(endMarker);
394
+ if (startIndex !== -1 && endIndex !== -1) {
395
+ const jsonStr = stdout.substring(startIndex + startMarker.length, endIndex).trim();
396
+ try {
397
+ result = JSON.parse(jsonStr);
398
+ } catch (e) {
399
+ result = jsonStr;
400
+ }
401
+ logs = logs.map((log) => {
402
+ let cleaned = log.replace(
403
+ new RegExp(startMarker + "[\\s\\S]*?" + endMarker),
404
+ "[Result captured]"
405
+ );
406
+ cleaned = cleaned.split("\n").filter((l) => !l.includes("__MCP_TOOL_CALL__")).join("\n");
407
+ return cleaned;
408
+ });
409
+ }
410
+ }
411
+ } catch (e) {
412
+ error = e.message || String(e);
413
+ if (error && (error.includes("timeout") || error.includes("timed out"))) {
414
+ error = "Script execution timed out";
415
+ }
416
+ }
417
+ return {
418
+ result,
419
+ logs,
420
+ error,
421
+ execution_time: (Date.now() - startTime) / 1e3
422
+ };
423
+ }
424
+ /**
425
+ * Clean up the E2B sandbox.
426
+ * Should be called when the executor is no longer needed.
427
+ */
428
+ async cleanup() {
429
+ if (this.codeExecSandbox) {
430
+ try {
431
+ await this.codeExecSandbox.kill();
432
+ this.codeExecSandbox = null;
433
+ logger.debug("E2B code execution sandbox stopped");
434
+ } catch (error) {
435
+ logger.error("Failed to stop E2B code execution sandbox:", error);
436
+ }
437
+ }
438
+ }
439
+ };
440
+
441
+ // src/client/executors/vm.ts
442
+ var vm = null;
443
+ var vmCheckAttempted = false;
444
+ function getVMModuleName() {
445
+ return ["node", "vm"].join(":");
446
+ }
447
+ __name(getVMModuleName, "getVMModuleName");
448
+ function tryLoadVM() {
449
+ if (vmCheckAttempted) {
450
+ return vm !== null;
451
+ }
452
+ vmCheckAttempted = true;
453
+ try {
454
+ const nodeRequire = typeof __require !== "undefined" ? __require : null;
455
+ if (nodeRequire) {
456
+ vm = nodeRequire(getVMModuleName());
457
+ return true;
458
+ }
459
+ } catch (error) {
460
+ logger.debug("node:vm module not available via require");
461
+ }
462
+ return false;
463
+ }
464
+ __name(tryLoadVM, "tryLoadVM");
465
+ async function tryLoadVMAsync() {
466
+ if (vm !== null) {
467
+ return true;
468
+ }
469
+ if (!vmCheckAttempted) {
470
+ if (tryLoadVM()) {
471
+ return true;
472
+ }
473
+ }
474
+ try {
475
+ vm = await import(
476
+ /* @vite-ignore */
477
+ getVMModuleName()
478
+ );
479
+ return true;
480
+ } catch (error) {
481
+ logger.debug(
482
+ "node:vm module not available in this environment (e.g., Deno)"
483
+ );
484
+ return false;
485
+ }
486
+ }
487
+ __name(tryLoadVMAsync, "tryLoadVMAsync");
488
+ function isVMAvailable() {
489
+ tryLoadVM();
490
+ return vm !== null;
491
+ }
492
+ __name(isVMAvailable, "isVMAvailable");
493
+ var VMCodeExecutor = class extends BaseCodeExecutor {
494
+ static {
495
+ __name(this, "VMCodeExecutor");
496
+ }
497
+ defaultTimeout;
498
+ memoryLimitMb;
499
+ constructor(client, options) {
500
+ super(client);
501
+ this.defaultTimeout = options?.timeoutMs ?? 3e4;
502
+ this.memoryLimitMb = options?.memoryLimitMb;
503
+ tryLoadVM();
504
+ }
505
+ /**
506
+ * Ensure VM module is loaded before execution
507
+ */
508
+ async ensureVMLoaded() {
509
+ if (vm !== null) {
510
+ return;
511
+ }
512
+ const loaded = await tryLoadVMAsync();
513
+ if (!loaded) {
514
+ throw new Error(
515
+ "node:vm module is not available in this environment. Please use E2B executor instead or run in a Node.js environment."
516
+ );
517
+ }
518
+ }
519
+ /**
520
+ * Execute JavaScript/TypeScript code with access to MCP tools.
521
+ *
522
+ * @param code - Code to execute
523
+ * @param timeout - Execution timeout in milliseconds (default: configured timeout or 30000)
524
+ */
525
+ async execute(code, timeout) {
526
+ const effectiveTimeout = timeout ?? this.defaultTimeout;
527
+ await this.ensureVMLoaded();
528
+ await this.ensureServersConnected();
529
+ const logs = [];
530
+ const startTime = Date.now();
531
+ let result = null;
532
+ let error = null;
533
+ try {
534
+ const context = await this._buildContext(logs);
535
+ const wrappedCode = `
536
+ (async () => {
537
+ try {
538
+ ${code}
539
+ } catch (e) {
540
+ throw e;
541
+ }
542
+ })()
543
+ `;
544
+ const script = new vm.Script(wrappedCode, {
545
+ filename: "agent_code.js"
546
+ });
547
+ const promise = script.runInNewContext(context, {
548
+ timeout: effectiveTimeout,
549
+ displayErrors: true
550
+ });
551
+ result = await promise;
552
+ } catch (e) {
553
+ error = e.message || String(e);
554
+ if (e.code === "ERR_SCRIPT_EXECUTION_TIMEOUT" || e.message === "Script execution timed out." || typeof error === "string" && (error.includes("timed out") || error.includes("timeout"))) {
555
+ error = "Script execution timed out";
556
+ }
557
+ if (e.stack) {
558
+ logger.debug(`Code execution error stack: ${e.stack}`);
559
+ }
560
+ }
561
+ const executionTime = (Date.now() - startTime) / 1e3;
562
+ return {
563
+ result,
564
+ logs,
565
+ error,
566
+ execution_time: executionTime
567
+ };
568
+ }
569
+ /**
570
+ * Build the VM execution context with MCP tools and standard globals.
571
+ *
572
+ * @param logs - Array to capture console output
573
+ */
574
+ async _buildContext(logs) {
575
+ const logHandler = /* @__PURE__ */ __name((...args) => {
576
+ logs.push(
577
+ args.map(
578
+ (arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg)
579
+ ).join(" ")
580
+ );
581
+ }, "logHandler");
582
+ const sandbox = {
583
+ console: {
584
+ log: logHandler,
585
+ error: /* @__PURE__ */ __name((...args) => {
586
+ logHandler("[ERROR]", ...args);
587
+ }, "error"),
588
+ warn: /* @__PURE__ */ __name((...args) => {
589
+ logHandler("[WARN]", ...args);
590
+ }, "warn"),
591
+ info: logHandler,
592
+ debug: logHandler
593
+ },
594
+ // Standard globals
595
+ Object,
596
+ Array,
597
+ String,
598
+ Number,
599
+ Boolean,
600
+ Date,
601
+ Math,
602
+ JSON,
603
+ RegExp,
604
+ Map,
605
+ Set,
606
+ Promise,
607
+ parseInt,
608
+ parseFloat,
609
+ isNaN,
610
+ isFinite,
611
+ encodeURI,
612
+ decodeURI,
613
+ encodeURIComponent,
614
+ decodeURIComponent,
615
+ setTimeout,
616
+ clearTimeout,
617
+ // Helper for tools
618
+ search_tools: this.createSearchToolsFunction(),
619
+ __tool_namespaces: []
620
+ };
621
+ const toolNamespaces = {};
622
+ const namespaceInfos = this.getToolNamespaces();
623
+ for (const { serverName, tools, session } of namespaceInfos) {
624
+ const serverNamespace = {};
625
+ for (const tool of tools) {
626
+ const toolName = tool.name;
627
+ serverNamespace[toolName] = async (args) => {
628
+ const result = await session.connector.callTool(toolName, args || {});
629
+ if (result.content && result.content.length > 0) {
630
+ const item = result.content[0];
631
+ if (item.type === "text") {
632
+ try {
633
+ return JSON.parse(item.text);
634
+ } catch {
635
+ return item.text;
636
+ }
637
+ }
638
+ return item;
639
+ }
640
+ return result;
641
+ };
642
+ }
643
+ sandbox[serverName] = serverNamespace;
644
+ toolNamespaces[serverName] = true;
645
+ }
646
+ sandbox.__tool_namespaces = Object.keys(toolNamespaces);
647
+ return vm.createContext(sandbox);
648
+ }
649
+ /**
650
+ * Clean up resources.
651
+ * VM executor doesn't need cleanup, but method kept for interface consistency.
652
+ */
653
+ async cleanup() {
654
+ }
655
+ };
656
+
657
+ // src/client/connectors/codeMode.ts
658
+ var CODE_MODE_AGENT_PROMPT = `
659
+ ## MCP Code Mode Tool Usage Guide
660
+
661
+ You have access to an MCP Code Mode Client that allows you to execute JavaScript/TypeScript code with access to registered tools. Follow this workflow:
662
+
663
+ ### 1. Tool Discovery Phase
664
+ **Always start by discovering available tools:**
665
+ - Tools are organized by server namespace (e.g., \`server_name.tool_name\`)
666
+ - Use the \`search_tools(query, detail_level)\` function to find available tools
667
+ - You can access \`__tool_namespaces\` to see all available server namespaces
668
+
669
+ \`\`\`javascript
670
+ // Find all GitHub-related tools
671
+ const tools = await search_tools("github");
672
+ for (const tool of tools) {
673
+ console.log(\`\${tool.server}.\${tool.name}: \${tool.description}\`);
674
+ }
675
+
676
+ // Get only tool names for quick overview
677
+ const tools = await search_tools("", "names");
678
+ \`\`\`
679
+
680
+ ### 2. Interface Introspection
681
+ **Understand tool contracts before using them:**
682
+ - Use \`search_tools\` to get tool descriptions and input schemas
683
+ - Look for "Access as: server.tool(args)" patterns in descriptions
684
+
685
+ ### 3. Code Execution Guidelines
686
+ **When writing code:**
687
+ - Use \`await server.tool({ param: value })\` syntax for all tool calls
688
+ - Tools are async functions that return promises
689
+ - You have access to standard JavaScript globals: \`console\`, \`JSON\`, \`Math\`, \`Date\`, etc.
690
+ - All console output (\`console.log\`, \`console.error\`, etc.) is automatically captured and returned
691
+ - Build properly structured input objects based on interface definitions
692
+ - Handle errors appropriately with try/catch blocks
693
+ - Chain tool calls by using results from previous calls
694
+
695
+ ### 4. Best Practices
696
+ - **Discover first, code second**: Always explore available tools before writing execution code
697
+ - **Respect namespaces**: Use full \`server.tool\` names to avoid conflicts
698
+ - **Minimize Context**: Process large data in code, return only essential results
699
+ - **Error handling**: Wrap tool calls in try/catch for robustness
700
+ - **Data flow**: Chain tools by passing outputs as inputs to subsequent tools
701
+
702
+ ### 5. Available Runtime Context
703
+ - \`search_tools(query, detail_level)\`: Function to discover tools
704
+ - \`__tool_namespaces\`: Array of available server namespaces
705
+ - All registered tools as \`server.tool\` functions
706
+ - Standard JavaScript built-ins for data processing
707
+
708
+ ### Example Workflow
709
+
710
+ \`\`\`javascript
711
+ // 1. Discover available tools
712
+ const github_tools = await search_tools("github pull request");
713
+ console.log(\`Available GitHub PR tools: \${github_tools.map(t => t.name)}\`);
714
+
715
+ // 2. Call tools with proper parameters
716
+ const pr = await github.get_pull_request({
717
+ owner: "facebook",
718
+ repo: "react",
719
+ number: 12345
720
+ });
721
+
722
+ // 3. Process results
723
+ let result;
724
+ if (pr.state === 'open' && pr.labels.some(l => l.name === 'bug')) {
725
+ // 4. Chain with other tools
726
+ await slack.post_message({
727
+ channel: "#bugs",
728
+ text: \`\u{1F41B} Bug PR needs review: \${pr.title}\`
729
+ });
730
+ result = "Notification sent";
731
+ } else {
732
+ result = "No action needed";
733
+ }
734
+
735
+ // 5. Return structured results
736
+ return {
737
+ pr_number: pr.number,
738
+ pr_title: pr.title,
739
+ action_taken: result
740
+ };
741
+ \`\`\`
742
+
743
+ Remember: Always discover and understand available tools before attempting to use them in code execution.
744
+ `;
745
+ var CodeModeConnector = class extends BaseConnector {
746
+ static {
747
+ __name(this, "CodeModeConnector");
748
+ }
749
+ mcpClient;
750
+ _tools;
751
+ constructor(client) {
752
+ super();
753
+ this.mcpClient = client;
754
+ this.connected = true;
755
+ this._tools = this._createToolsList();
756
+ }
757
+ async connect() {
758
+ this.connected = true;
759
+ }
760
+ async disconnect() {
761
+ this.connected = false;
762
+ }
763
+ get publicIdentifier() {
764
+ return { name: "code_mode", version: "1.0.0" };
765
+ }
766
+ _createToolsList() {
767
+ return [
768
+ {
769
+ name: "execute_code",
770
+ description: "Execute JavaScript/TypeScript code with access to MCP tools. This is the PRIMARY way to interact with MCP servers in code mode. Write code that discovers tools using search_tools(), calls tools as async functions (e.g., await github.get_pull_request(...)), processes data efficiently, and returns results. Use 'await' for async operations and 'return' to return values. Available in code: search_tools(), __tool_namespaces, and server.tool_name() functions.",
771
+ inputSchema: {
772
+ type: "object",
773
+ properties: {
774
+ code: {
775
+ type: "string",
776
+ description: "JavaScript/TypeScript code to execute. Use 'await' for async operations. Use 'return' to return a value. Available: search_tools(), server.tool_name(), __tool_namespaces"
777
+ },
778
+ timeout: {
779
+ type: "number",
780
+ description: "Execution timeout in milliseconds",
781
+ default: 3e4
782
+ }
783
+ },
784
+ required: ["code"]
785
+ }
786
+ },
787
+ {
788
+ name: "search_tools",
789
+ description: "Search and discover available MCP tools across all servers. Use this to find out what tools are available before writing code. Returns tool information including names, descriptions, and schemas. Can filter by query and control detail level.",
790
+ inputSchema: {
791
+ type: "object",
792
+ properties: {
793
+ query: {
794
+ type: "string",
795
+ description: "Search query to filter tools by name or description",
796
+ default: ""
797
+ },
798
+ detail_level: {
799
+ type: "string",
800
+ description: "Detail level: 'names', 'descriptions', or 'full'",
801
+ enum: ["names", "descriptions", "full"],
802
+ default: "full"
803
+ }
804
+ }
805
+ }
806
+ }
807
+ ];
808
+ }
809
+ // Override tools getter to return static list immediately
810
+ get tools() {
811
+ return this._tools;
812
+ }
813
+ async initialize() {
814
+ this.toolsCache = this._tools;
815
+ return { capabilities: {}, version: "1.0.0" };
816
+ }
817
+ async callTool(name, args) {
818
+ if (name === "execute_code") {
819
+ const code = args.code;
820
+ const timeout = args.timeout || 3e4;
821
+ const result = await this.mcpClient.executeCode(code, timeout);
822
+ return {
823
+ content: [
824
+ {
825
+ type: "text",
826
+ text: JSON.stringify(result)
827
+ }
828
+ ]
829
+ };
830
+ } else if (name === "search_tools") {
831
+ const query = args.query || "";
832
+ const detailLevel = args.detail_level;
833
+ const result = await this.mcpClient.searchTools(
834
+ query,
835
+ detailLevel && detailLevel in ["names", "descriptions", "full"] ? detailLevel : "full"
836
+ );
837
+ return {
838
+ content: [
839
+ {
840
+ type: "text",
841
+ text: JSON.stringify(result)
842
+ }
843
+ ]
844
+ };
845
+ }
846
+ throw new Error(`Unknown tool: ${name}`);
847
+ }
848
+ };
849
+
850
+ // src/config.ts
851
+ import { readFileSync } from "fs";
852
+
853
+ // src/connectors/stdio.ts
854
+ import process2 from "process";
855
+ import { Client } from "@mcp-use/modelcontextprotocol-sdk/client/index.js";
856
+
857
+ // src/task_managers/stdio.ts
858
+ import { StdioClientTransport } from "@mcp-use/modelcontextprotocol-sdk/client/stdio.js";
859
+ var StdioConnectionManager = class extends ConnectionManager {
860
+ static {
861
+ __name(this, "StdioConnectionManager");
862
+ }
863
+ serverParams;
864
+ errlog;
865
+ _transport = null;
866
+ /**
867
+ * Create a new stdio connection manager.
868
+ *
869
+ * @param serverParams Parameters for the stdio server process.
870
+ * @param errlog Stream to which the server's stderr should be piped.
871
+ * Defaults to `process.stderr`.
872
+ */
873
+ constructor(serverParams, errlog = process.stderr) {
874
+ super();
875
+ this.serverParams = serverParams;
876
+ this.errlog = errlog;
877
+ }
878
+ /**
879
+ * Establish the stdio connection by spawning the server process and starting
880
+ * the SDK's transport. Returns the live `StdioClientTransport` instance.
881
+ */
882
+ async establishConnection() {
883
+ this._transport = new StdioClientTransport(this.serverParams);
884
+ if (this._transport.stderr && typeof this._transport.stderr.pipe === "function") {
885
+ this._transport.stderr.pipe(
886
+ this.errlog
887
+ );
888
+ }
889
+ logger.debug(`${this.constructor.name} connected successfully`);
890
+ return this._transport;
891
+ }
892
+ /**
893
+ * Close the stdio connection, making sure the transport cleans up the child
894
+ * process and associated resources.
895
+ */
896
+ async closeConnection(_connection) {
897
+ if (this._transport) {
898
+ try {
899
+ await this._transport.close();
900
+ } catch (e) {
901
+ logger.warn(`Error closing stdio transport: ${e}`);
902
+ } finally {
903
+ this._transport = null;
904
+ }
905
+ }
906
+ }
907
+ };
908
+
909
+ // src/connectors/stdio.ts
910
+ var StdioConnector = class extends BaseConnector {
911
+ static {
912
+ __name(this, "StdioConnector");
913
+ }
914
+ command;
915
+ args;
916
+ env;
917
+ errlog;
918
+ clientInfo;
919
+ constructor({
920
+ command = "npx",
921
+ args = [],
922
+ env,
923
+ errlog = process2.stderr,
924
+ ...rest
925
+ } = {}) {
926
+ super(rest);
927
+ this.command = command;
928
+ this.args = args;
929
+ this.env = env;
930
+ this.errlog = errlog;
931
+ this.clientInfo = rest.clientInfo ?? {
932
+ name: "stdio-connector",
933
+ version: "1.0.0"
934
+ };
935
+ }
936
+ /** Establish connection to the MCP implementation. */
937
+ async connect() {
938
+ if (this.connected) {
939
+ logger.debug("Already connected to MCP implementation");
940
+ return;
941
+ }
942
+ logger.debug(`Connecting to MCP implementation via stdio: ${this.command}`);
943
+ try {
944
+ let mergedEnv;
945
+ if (this.env) {
946
+ mergedEnv = {};
947
+ for (const [key, value] of Object.entries(process2.env)) {
948
+ if (value !== void 0) {
949
+ mergedEnv[key] = value;
950
+ }
951
+ }
952
+ Object.assign(mergedEnv, this.env);
953
+ }
954
+ const serverParams = {
955
+ command: this.command,
956
+ args: this.args,
957
+ env: mergedEnv
958
+ };
959
+ this.connectionManager = new StdioConnectionManager(
960
+ serverParams,
961
+ this.errlog
962
+ );
963
+ const transport = await this.connectionManager.start();
964
+ const clientOptions = {
965
+ ...this.opts.clientOptions || {},
966
+ capabilities: {
967
+ ...this.opts.clientOptions?.capabilities || {},
968
+ roots: { listChanged: true },
969
+ // Always advertise roots capability
970
+ // Add sampling capability if callback is provided
971
+ ...this.opts.samplingCallback ? { sampling: {} } : {},
972
+ // Add elicitation capability if callback is provided
973
+ ...this.opts.elicitationCallback ? { elicitation: { form: {}, url: {} } } : {}
974
+ }
975
+ };
976
+ this.client = new Client(this.clientInfo, clientOptions);
977
+ await this.client.connect(transport);
978
+ this.connected = true;
979
+ this.setupNotificationHandler();
980
+ this.setupRootsHandler();
981
+ this.setupSamplingHandler();
982
+ this.setupElicitationHandler();
983
+ logger.debug(
984
+ `Successfully connected to MCP implementation: ${this.command}`
985
+ );
986
+ this.trackConnectorInit({
987
+ serverCommand: this.command,
988
+ serverArgs: this.args,
989
+ publicIdentifier: `${this.command} ${this.args.join(" ")}`
990
+ });
991
+ } catch (err) {
992
+ logger.error(`Failed to connect to MCP implementation: ${err}`);
993
+ await this.cleanupResources();
994
+ throw err;
995
+ }
996
+ }
997
+ get publicIdentifier() {
998
+ return {
999
+ type: "stdio",
1000
+ "command&args": `${this.command} ${this.args.join(" ")}`
1001
+ };
1002
+ }
1003
+ };
1004
+
1005
+ // src/config.ts
1006
+ function loadConfigFile(filepath) {
1007
+ const raw = readFileSync(filepath, "utf-8");
1008
+ return JSON.parse(raw);
1009
+ }
1010
+ __name(loadConfigFile, "loadConfigFile");
1011
+ function createConnectorFromConfig(serverConfig, connectorOptions) {
1012
+ if ("command" in serverConfig && "args" in serverConfig) {
1013
+ return new StdioConnector({
1014
+ command: serverConfig.command,
1015
+ args: serverConfig.args,
1016
+ env: serverConfig.env,
1017
+ ...connectorOptions
1018
+ });
1019
+ }
1020
+ if ("url" in serverConfig) {
1021
+ const transport = serverConfig.transport || "http";
1022
+ return new HttpConnector(serverConfig.url, {
1023
+ headers: serverConfig.headers,
1024
+ authToken: serverConfig.auth_token || serverConfig.authToken,
1025
+ // Only force SSE if explicitly requested
1026
+ preferSse: serverConfig.preferSse || transport === "sse",
1027
+ // Disable SSE fallback if explicitly disabled in config
1028
+ disableSseFallback: serverConfig.disableSseFallback,
1029
+ ...connectorOptions
1030
+ });
1031
+ }
1032
+ throw new Error("Cannot determine connector type from config");
1033
+ }
1034
+ __name(createConnectorFromConfig, "createConnectorFromConfig");
1035
+
1036
+ // src/client.ts
1037
+ var MCPClient = class _MCPClient extends BaseMCPClient {
1038
+ static {
1039
+ __name(this, "MCPClient");
1040
+ }
1041
+ /**
1042
+ * Get the mcp-use package version.
1043
+ * Works in all environments (Node.js, browser, Cloudflare Workers, Deno, etc.)
1044
+ */
1045
+ static getPackageVersion() {
1046
+ return getPackageVersion();
1047
+ }
1048
+ codeMode = false;
1049
+ _codeExecutor = null;
1050
+ _customCodeExecutor = null;
1051
+ _codeExecutorConfig = "vm";
1052
+ _executorOptions;
1053
+ _samplingCallback;
1054
+ _elicitationCallback;
1055
+ constructor(config, options) {
1056
+ if (config) {
1057
+ if (typeof config === "string") {
1058
+ super(loadConfigFile(config));
1059
+ } else {
1060
+ super(config);
1061
+ }
1062
+ } else {
1063
+ super();
1064
+ }
1065
+ let codeModeEnabled = false;
1066
+ let executorConfig = "vm";
1067
+ let executorOptions;
1068
+ if (options?.codeMode) {
1069
+ if (typeof options.codeMode === "boolean") {
1070
+ codeModeEnabled = options.codeMode;
1071
+ } else {
1072
+ codeModeEnabled = options.codeMode.enabled;
1073
+ executorConfig = options.codeMode.executor ?? "vm";
1074
+ executorOptions = options.codeMode.executorOptions;
1075
+ }
1076
+ }
1077
+ this.codeMode = codeModeEnabled;
1078
+ this._codeExecutorConfig = executorConfig;
1079
+ this._executorOptions = executorOptions;
1080
+ this._samplingCallback = options?.samplingCallback;
1081
+ this._elicitationCallback = options?.elicitationCallback;
1082
+ if (this.codeMode) {
1083
+ this._setupCodeModeConnector();
1084
+ }
1085
+ this._trackClientInit();
1086
+ }
1087
+ _trackClientInit() {
1088
+ const servers = Object.keys(this.config.mcpServers ?? {});
1089
+ const hasSamplingCallback = !!this._samplingCallback;
1090
+ const hasElicitationCallback = !!this._elicitationCallback;
1091
+ Tel.getInstance().trackMCPClientInit({
1092
+ codeMode: this.codeMode,
1093
+ sandbox: false,
1094
+ // Sandbox not supported in TS yet
1095
+ allCallbacks: hasSamplingCallback && hasElicitationCallback,
1096
+ verify: false,
1097
+ // No verify option in TS client
1098
+ servers,
1099
+ numServers: servers.length,
1100
+ isBrowser: false
1101
+ // Node.js MCPClient
1102
+ }).catch((e) => logger.debug(`Failed to track MCPClient init: ${e}`));
1103
+ }
1104
+ static fromDict(cfg, options) {
1105
+ return new _MCPClient(cfg, options);
1106
+ }
1107
+ static fromConfigFile(path2, options) {
1108
+ return new _MCPClient(loadConfigFile(path2), options);
1109
+ }
1110
+ /**
1111
+ * Save configuration to a file (Node.js only)
1112
+ */
1113
+ saveConfig(filepath) {
1114
+ const dir = path.dirname(filepath);
1115
+ if (!fs.existsSync(dir)) {
1116
+ fs.mkdirSync(dir, { recursive: true });
1117
+ }
1118
+ fs.writeFileSync(filepath, JSON.stringify(this.config, null, 2), "utf-8");
1119
+ }
1120
+ /**
1121
+ * Create a connector from server configuration (Node.js version)
1122
+ * Supports all connector types including StdioConnector
1123
+ */
1124
+ createConnectorFromConfig(serverConfig) {
1125
+ return createConnectorFromConfig(serverConfig, {
1126
+ samplingCallback: this._samplingCallback,
1127
+ elicitationCallback: this._elicitationCallback
1128
+ });
1129
+ }
1130
+ _setupCodeModeConnector() {
1131
+ logger.debug("Code mode connector initialized as internal meta server");
1132
+ const connector = new CodeModeConnector(this);
1133
+ const session = new MCPSession(connector);
1134
+ this.sessions["code_mode"] = session;
1135
+ this.activeSessions.push("code_mode");
1136
+ }
1137
+ _ensureCodeExecutor() {
1138
+ if (!this._codeExecutor) {
1139
+ const config = this._codeExecutorConfig;
1140
+ if (config instanceof BaseCodeExecutor) {
1141
+ this._codeExecutor = config;
1142
+ } else if (typeof config === "function") {
1143
+ this._customCodeExecutor = config;
1144
+ throw new Error(
1145
+ "Custom executor function should be handled in executeCode"
1146
+ );
1147
+ } else if (config === "e2b") {
1148
+ const opts = this._executorOptions;
1149
+ if (!opts?.apiKey) {
1150
+ logger.warn("E2B executor requires apiKey. Falling back to VM.");
1151
+ try {
1152
+ this._codeExecutor = new VMCodeExecutor(
1153
+ this,
1154
+ this._executorOptions
1155
+ );
1156
+ } catch (error) {
1157
+ throw new Error(
1158
+ "VM executor is not available in this environment and E2B API key is not provided. Please provide an E2B API key or run in a Node.js environment."
1159
+ );
1160
+ }
1161
+ } else {
1162
+ this._codeExecutor = new E2BCodeExecutor(this, opts);
1163
+ }
1164
+ } else {
1165
+ try {
1166
+ this._codeExecutor = new VMCodeExecutor(
1167
+ this,
1168
+ this._executorOptions
1169
+ );
1170
+ } catch (error) {
1171
+ const e2bOpts = this._executorOptions;
1172
+ const e2bApiKey = e2bOpts?.apiKey || process.env.E2B_API_KEY;
1173
+ if (e2bApiKey) {
1174
+ logger.info(
1175
+ "VM executor not available in this environment. Falling back to E2B."
1176
+ );
1177
+ this._codeExecutor = new E2BCodeExecutor(this, {
1178
+ ...e2bOpts,
1179
+ apiKey: e2bApiKey
1180
+ });
1181
+ } else {
1182
+ throw new Error(
1183
+ "VM executor is not available in this environment. Please provide an E2B API key via executorOptions or E2B_API_KEY environment variable, or run in a Node.js environment."
1184
+ );
1185
+ }
1186
+ }
1187
+ }
1188
+ }
1189
+ return this._codeExecutor;
1190
+ }
1191
+ /**
1192
+ * Execute code in code mode
1193
+ */
1194
+ async executeCode(code, timeout) {
1195
+ if (!this.codeMode) {
1196
+ throw new Error("Code execution mode is not enabled");
1197
+ }
1198
+ if (this._customCodeExecutor) {
1199
+ return this._customCodeExecutor(code, timeout);
1200
+ }
1201
+ return this._ensureCodeExecutor().execute(code, timeout);
1202
+ }
1203
+ /**
1204
+ * Search available tools (used by code mode)
1205
+ */
1206
+ async searchTools(query = "", detailLevel = "full") {
1207
+ if (!this.codeMode) {
1208
+ throw new Error("Code execution mode is not enabled");
1209
+ }
1210
+ return this._ensureCodeExecutor().createSearchToolsFunction()(
1211
+ query,
1212
+ detailLevel
1213
+ );
1214
+ }
1215
+ /**
1216
+ * Override getServerNames to exclude internal code_mode server
1217
+ */
1218
+ getServerNames() {
1219
+ const isCodeModeEnabled = this.codeMode;
1220
+ return super.getServerNames().filter((name) => {
1221
+ return !isCodeModeEnabled || name !== "code_mode";
1222
+ });
1223
+ }
1224
+ /**
1225
+ * Close the client and clean up resources including code executors.
1226
+ * This ensures E2B sandboxes and other resources are properly released.
1227
+ */
1228
+ async close() {
1229
+ if (this._codeExecutor) {
1230
+ await this._codeExecutor.cleanup();
1231
+ this._codeExecutor = null;
1232
+ }
1233
+ await this.closeAllSessions();
1234
+ }
1235
+ };
1236
+
1237
+ export {
1238
+ BaseCodeExecutor,
1239
+ E2BCodeExecutor,
1240
+ isVMAvailable,
1241
+ VMCodeExecutor,
1242
+ CODE_MODE_AGENT_PROMPT,
1243
+ StdioConnector,
1244
+ loadConfigFile,
1245
+ MCPClient
1246
+ };