@toolsdk.ai/registry 1.0.118 → 1.0.119
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.
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import type { SandboxClient } from "../sandbox-types";
|
|
3
|
+
/**
|
|
4
|
+
* E2B Sandbox Client
|
|
5
|
+
* Implements SandboxClient interface for E2B provider
|
|
6
|
+
*/
|
|
7
|
+
export declare class E2BSandboxClient implements SandboxClient {
|
|
8
|
+
private sandbox;
|
|
9
|
+
private initializing;
|
|
10
|
+
private readonly packageRepository;
|
|
11
|
+
private readonly apiKey;
|
|
12
|
+
private readonly runtime;
|
|
13
|
+
constructor(runtime?: "node" | "python" | "java" | "go");
|
|
14
|
+
initialize(): Promise<void>;
|
|
15
|
+
private executeCode;
|
|
16
|
+
listTools(packageKey: string): Promise<Tool[]>;
|
|
17
|
+
executeTool(packageKey: string, toolName: string, argumentsObj: Record<string, unknown>, envs?: Record<string, string>): Promise<unknown>;
|
|
18
|
+
destroy(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { Sandbox } from "@e2b/code-interpreter";
|
|
3
|
+
import { getE2BConfig } from "../../../shared/config/environment";
|
|
4
|
+
import { getDirname } from "../../../shared/utils/file-util";
|
|
5
|
+
import { extractLastOuterJSON } from "../../../shared/utils/string-util";
|
|
6
|
+
import { PackageRepository } from "../../package/package-repository";
|
|
7
|
+
import { generateMCPTestCode } from "../sandbox-utils";
|
|
8
|
+
/**
|
|
9
|
+
* E2B Sandbox Client
|
|
10
|
+
* Implements SandboxClient interface for E2B provider
|
|
11
|
+
*/
|
|
12
|
+
export class E2BSandboxClient {
|
|
13
|
+
constructor(runtime = "node") {
|
|
14
|
+
this.sandbox = null;
|
|
15
|
+
this.initializing = null;
|
|
16
|
+
const __dirname = getDirname(import.meta.url);
|
|
17
|
+
const packagesDir = path.join(__dirname, "../../../../packages");
|
|
18
|
+
this.packageRepository = new PackageRepository(packagesDir);
|
|
19
|
+
const config = getE2BConfig();
|
|
20
|
+
this.apiKey = config.apiKey;
|
|
21
|
+
this.runtime = runtime;
|
|
22
|
+
}
|
|
23
|
+
async initialize() {
|
|
24
|
+
if (this.sandbox) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (this.initializing) {
|
|
28
|
+
await this.initializing;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.initializing = (async () => {
|
|
32
|
+
try {
|
|
33
|
+
const templateMap = {
|
|
34
|
+
python: "mcp-sandbox-python",
|
|
35
|
+
node: "mcp-sandbox-node",
|
|
36
|
+
java: "mcp-sandbox-java",
|
|
37
|
+
go: "mcp-sandbox-go",
|
|
38
|
+
};
|
|
39
|
+
const template = templateMap[this.runtime];
|
|
40
|
+
if (!template) {
|
|
41
|
+
throw new Error(`[E2BSandboxClient] Unsupported runtime: ${this.runtime}`);
|
|
42
|
+
}
|
|
43
|
+
this.sandbox = await Sandbox.create(template, {
|
|
44
|
+
apiKey: this.apiKey,
|
|
45
|
+
timeoutMs: 30 * 1000,
|
|
46
|
+
});
|
|
47
|
+
console.log(`[E2BSandboxClient] Sandbox (${template}) created successfully`);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
this.initializing = null;
|
|
51
|
+
}
|
|
52
|
+
})();
|
|
53
|
+
await this.initializing;
|
|
54
|
+
}
|
|
55
|
+
async executeCode(code) {
|
|
56
|
+
var _a;
|
|
57
|
+
if (!this.sandbox) {
|
|
58
|
+
throw new Error("Sandbox not initialized. Call initialize() first.");
|
|
59
|
+
}
|
|
60
|
+
// Map runtime to language string expected by the sandbox
|
|
61
|
+
const runtimeToLanguage = {
|
|
62
|
+
node: "javascript",
|
|
63
|
+
python: "python",
|
|
64
|
+
java: "java",
|
|
65
|
+
go: "go",
|
|
66
|
+
};
|
|
67
|
+
const language = runtimeToLanguage[this.runtime] || "javascript";
|
|
68
|
+
const result = await this.sandbox.runCode(code, { language });
|
|
69
|
+
if (result.error) {
|
|
70
|
+
return {
|
|
71
|
+
exitCode: 1,
|
|
72
|
+
result: result.error.toString(),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const stdout = ((_a = result.logs) === null || _a === void 0 ? void 0 : _a.stdout) || [];
|
|
76
|
+
const output = stdout[stdout.length - 1] || "";
|
|
77
|
+
return {
|
|
78
|
+
exitCode: 0,
|
|
79
|
+
result: output,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async listTools(packageKey) {
|
|
83
|
+
const mcpServerConfig = this.packageRepository.getPackageConfig(packageKey);
|
|
84
|
+
const testCode = generateMCPTestCode(mcpServerConfig, "listTools");
|
|
85
|
+
const response = await this.executeCode(testCode);
|
|
86
|
+
if (response.exitCode !== 0) {
|
|
87
|
+
throw new Error(`Failed to list tools: ${response.result}`);
|
|
88
|
+
}
|
|
89
|
+
const parsedResultStr = extractLastOuterJSON(response.result);
|
|
90
|
+
const result = JSON.parse(parsedResultStr);
|
|
91
|
+
return result.tools;
|
|
92
|
+
}
|
|
93
|
+
async executeTool(packageKey, toolName, argumentsObj, envs) {
|
|
94
|
+
const mcpServerConfig = this.packageRepository.getPackageConfig(packageKey);
|
|
95
|
+
const testCode = generateMCPTestCode(mcpServerConfig, "executeTool", toolName, argumentsObj, envs);
|
|
96
|
+
const response = await this.executeCode(testCode);
|
|
97
|
+
if (response.exitCode !== 0) {
|
|
98
|
+
throw new Error(`Failed to execute tool: ${response.result}`);
|
|
99
|
+
}
|
|
100
|
+
const parsedResultStr = extractLastOuterJSON(response.result);
|
|
101
|
+
const result = JSON.parse(parsedResultStr);
|
|
102
|
+
if (result.isError) {
|
|
103
|
+
console.error("[E2BSandboxClient] Tool execution error:", result.errorMessage);
|
|
104
|
+
throw new Error(result.errorMessage);
|
|
105
|
+
}
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
async destroy() {
|
|
109
|
+
if (!this.sandbox) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const sandboxToDelete = this.sandbox;
|
|
113
|
+
this.sandbox = null; // Clear immediately to avoid duplicate calls
|
|
114
|
+
// Asynchronously clean up sandbox without blocking result return
|
|
115
|
+
sandboxToDelete
|
|
116
|
+
.kill()
|
|
117
|
+
.then(() => {
|
|
118
|
+
console.log("[E2BSandboxClient] Sandbox destroyed successfully");
|
|
119
|
+
})
|
|
120
|
+
.catch((err) => {
|
|
121
|
+
const errorMessage = err.message;
|
|
122
|
+
if (errorMessage.includes("not found")) {
|
|
123
|
+
console.log("[E2BSandboxClient] Sandbox already destroyed (not found on platform)");
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
console.warn("[E2BSandboxClient] Warning: Could not destroy sandbox:", errorMessage);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DaytonaSandboxClient } from "./clients/daytona-client";
|
|
2
|
+
import { E2BSandboxClient } from "./clients/e2b-client";
|
|
2
3
|
import { SandockSandboxClient } from "./clients/sandock-client";
|
|
3
4
|
/**
|
|
4
5
|
* Sandbox Factory
|
|
@@ -13,7 +14,7 @@ export class SandboxFactory {
|
|
|
13
14
|
case "DAYTONA":
|
|
14
15
|
return new DaytonaSandboxClient(runtime);
|
|
15
16
|
case "E2B":
|
|
16
|
-
|
|
17
|
+
return new E2BSandboxClient(runtime);
|
|
17
18
|
case "LOCAL":
|
|
18
19
|
throw new Error("LOCAL provider should not use sandbox client");
|
|
19
20
|
default:
|
|
@@ -26,6 +26,11 @@ export function getSandockConfig() {
|
|
|
26
26
|
apiUrl: process.env.SANDOCK_API_URL || "https://sandock.ai",
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
+
export function getE2BConfig() {
|
|
30
|
+
return {
|
|
31
|
+
apiKey: process.env.E2B_API_KEY || "",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
29
34
|
export function getMeiliSearchConfig() {
|
|
30
35
|
return {
|
|
31
36
|
host: process.env.MEILI_HTTP_ADDR || "http://localhost:7700",
|