@yukkit/e2b-mcp-server 0.2.2 → 0.4.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.
package/README.md CHANGED
@@ -22,7 +22,7 @@ This server implements the [Model Context Protocol (MCP)](https://modelcontextpr
22
22
 
23
23
  ## Features
24
24
 
25
- - **8 Production-Ready Tools**: Complete toolkit for sandbox interaction
25
+ - **10 Production-Ready Tools**: Complete toolkit for sandbox interaction
26
26
  - **Resource Management**: Automatic sandbox lifecycle management with configurable limits (default: 10 concurrent sandboxes)
27
27
  - **Robust Error Handling**: Custom error classes for clear diagnostics (SandboxError, SandboxNotFoundError, SandboxLimitExceededError)
28
28
  - **Production Logging**: Multi-level logging system (DEBUG, INFO, WARNING, ERROR) with timestamps
@@ -168,7 +168,30 @@ Get a public URL for accessing a service running in a sandbox.
168
168
  - `port`: Port number (1-65535)
169
169
  - `sandboxId`: Target sandbox ID
170
170
 
171
- ### 8. kill_sandbox
171
+ ### 8. get_file_download_url
172
+
173
+ Get a download URL for a file in the sandbox.
174
+
175
+ **Parameters:**
176
+
177
+ - `filePath`: Path to the file
178
+ - `sandboxId`: Target sandbox ID
179
+
180
+ ### 9. list_sandbox_ids
181
+
182
+ List all active sandbox IDs and get sandbox statistics.
183
+
184
+ **Parameters:**
185
+
186
+ None
187
+
188
+ **Returns:**
189
+
190
+ - `sandbox_ids`: Array of active sandbox IDs
191
+ - `active_sandboxes`: Current number of active sandboxes
192
+ - `max_sandboxes`: Maximum allowed sandboxes
193
+
194
+ ### 10. kill_sandbox
172
195
 
173
196
  Terminate a sandbox and clean up resources.
174
197
 
package/build/index.js CHANGED
@@ -64,9 +64,14 @@ const getSandboxUrlSchema = z.object({
64
64
  port: z.number().min(1).max(65535).describe("Port number"),
65
65
  sandboxId: z.string().describe("Sandbox ID"),
66
66
  });
67
+ const getFileDownloadUrlSchema = z.object({
68
+ filePath: z.string().min(1).describe("Path to the file"),
69
+ sandboxId: z.string().describe("Sandbox ID"),
70
+ });
67
71
  const killSandboxSchema = z.object({
68
72
  sandboxId: z.string().describe("Sandbox ID"),
69
73
  });
74
+ const listSandboxIdsSchema = z.object({});
70
75
  // Custom Errors
71
76
  class SandboxError extends Error {
72
77
  constructor(message) {
@@ -263,11 +268,21 @@ class E2BServer {
263
268
  description: "Get the URL for a sandbox on a specific port",
264
269
  inputSchema: zodToJsonSchema(getSandboxUrlSchema),
265
270
  },
271
+ {
272
+ name: "get_file_download_url",
273
+ description: "Get a download URL for a file in the sandbox",
274
+ inputSchema: zodToJsonSchema(getFileDownloadUrlSchema),
275
+ },
266
276
  {
267
277
  name: "kill_sandbox",
268
278
  description: "Kill a sandbox",
269
279
  inputSchema: zodToJsonSchema(killSandboxSchema),
270
280
  },
281
+ {
282
+ name: "list_sandbox_ids",
283
+ description: "List all active sandbox IDs and statistics",
284
+ inputSchema: zodToJsonSchema(listSandboxIdsSchema),
285
+ },
271
286
  ],
272
287
  }));
273
288
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
@@ -284,12 +299,16 @@ class E2BServer {
284
299
  return await this.handleWriteFile(request.params.arguments);
285
300
  case "list_files":
286
301
  return await this.handleListFiles(request.params.arguments);
302
+ case "get_file_download_url":
303
+ return await this.handleGetFileDownloadUrl(request.params.arguments);
287
304
  case "run_code":
288
305
  return await this.handleRunCode(request.params.arguments);
289
306
  case "get_sandbox_url":
290
307
  return await this.handleGetSandboxUrl(request.params.arguments);
291
308
  case "kill_sandbox":
292
309
  return await this.handleKillSandbox(request.params.arguments);
310
+ case "list_sandbox_ids":
311
+ return await this.handleListSandboxIds(request.params.arguments);
293
312
  default:
294
313
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}`);
295
314
  }
@@ -318,7 +337,6 @@ class E2BServer {
318
337
  const result = {
319
338
  sandboxId,
320
339
  message: `Sandbox created successfully with timeout ${timeout}ms`,
321
- stats: this.sandboxManager.getStats(),
322
340
  };
323
341
  return {
324
342
  content: [
@@ -519,6 +537,31 @@ class E2BServer {
519
537
  throw new SandboxError(`Failed to get sandbox URL: ${error}`);
520
538
  }
521
539
  }
540
+ async handleGetFileDownloadUrl(args) {
541
+ const parsed = getFileDownloadUrlSchema.parse(args);
542
+ const sandbox = this.sandboxManager.getSandbox(parsed.sandboxId);
543
+ try {
544
+ const url = sandbox.downloadUrl(parsed.filePath);
545
+ const result = {
546
+ sandboxId: parsed.sandboxId,
547
+ filePath: parsed.filePath,
548
+ url,
549
+ };
550
+ logger.info(`Got download URL for file ${parsed.filePath} in sandbox ${parsed.sandboxId}`);
551
+ return {
552
+ content: [
553
+ {
554
+ type: "text",
555
+ text: JSON.stringify(result, null, 2),
556
+ },
557
+ ],
558
+ };
559
+ }
560
+ catch (error) {
561
+ logger.error(`Error getting file download URL: ${error}`);
562
+ throw new SandboxError(`Failed to get file download URL: ${error}`);
563
+ }
564
+ }
522
565
  async handleKillSandbox(args) {
523
566
  const parsed = killSandboxSchema.parse(args);
524
567
  await this.sandboxManager.killSandbox(parsed.sandboxId);
@@ -536,6 +579,24 @@ class E2BServer {
536
579
  ],
537
580
  };
538
581
  }
582
+ async handleListSandboxIds(args) {
583
+ listSandboxIdsSchema.parse(args);
584
+ const stats = this.sandboxManager.getStats();
585
+ const result = {
586
+ sandbox_ids: stats.sandbox_ids,
587
+ active_sandboxes: stats.active_sandboxes,
588
+ max_sandboxes: stats.max_sandboxes,
589
+ };
590
+ logger.info(`Listed ${stats.active_sandboxes} active sandboxes`);
591
+ return {
592
+ content: [
593
+ {
594
+ type: "text",
595
+ text: JSON.stringify(result, null, 2),
596
+ },
597
+ ],
598
+ };
599
+ }
539
600
  async run() {
540
601
  const transport = new StdioServerTransport();
541
602
  await this.server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yukkit/e2b-mcp-server",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
4
4
  "description": "A Model Context Protocol server",
5
5
  "repository": {
6
6
  "type": "git",