@toolsdk.ai/registry 1.0.113 → 1.0.115

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 (97) hide show
  1. package/README.md +66 -11
  2. package/dist/api/index.d.ts +1 -1
  3. package/dist/api/index.js +23 -25
  4. package/dist/domains/config/config-route.d.ts +2 -0
  5. package/dist/domains/config/config-route.js +31 -0
  6. package/dist/domains/config/config-schema.d.ts +57 -0
  7. package/dist/domains/config/config-schema.js +10 -0
  8. package/dist/domains/config/config-types.d.ts +3 -0
  9. package/dist/domains/executor/executor-factory.d.ts +9 -0
  10. package/dist/domains/executor/executor-factory.js +17 -0
  11. package/dist/domains/executor/executor-types.d.ts +15 -0
  12. package/dist/domains/executor/local-executor.d.ts +12 -0
  13. package/dist/domains/executor/local-executor.js +48 -0
  14. package/dist/domains/executor/sandbox-executor.d.ts +16 -0
  15. package/dist/domains/executor/sandbox-executor.js +83 -0
  16. package/dist/domains/package/package-handler.d.ts +17 -0
  17. package/dist/domains/package/package-handler.js +58 -0
  18. package/dist/domains/package/package-repository.d.ts +9 -0
  19. package/dist/domains/package/package-repository.js +26 -0
  20. package/dist/domains/package/package-route.d.ts +2 -0
  21. package/dist/{api → domains/package}/package-route.js +38 -52
  22. package/dist/domains/package/package-schema.d.ts +244 -0
  23. package/dist/domains/package/package-schema.js +52 -0
  24. package/dist/domains/package/package-so.d.ts +78 -0
  25. package/dist/domains/package/package-so.js +61 -0
  26. package/dist/domains/package/package-so.test.js +378 -0
  27. package/dist/domains/package/package-types.d.ts +9 -0
  28. package/dist/domains/package/package-types.js +1 -0
  29. package/dist/domains/sandbox/clients/daytona-client.d.ts +17 -0
  30. package/dist/domains/sandbox/clients/daytona-client.js +112 -0
  31. package/dist/domains/sandbox/clients/sandock-client.d.ts +19 -0
  32. package/dist/domains/sandbox/clients/sandock-client.js +178 -0
  33. package/dist/domains/sandbox/sandbox-factory.d.ts +8 -0
  34. package/dist/domains/sandbox/sandbox-factory.js +23 -0
  35. package/dist/domains/sandbox/sandbox-pool-so.d.ts +25 -0
  36. package/dist/domains/sandbox/sandbox-pool-so.js +123 -0
  37. package/dist/domains/sandbox/sandbox-types.d.ts +25 -0
  38. package/dist/domains/sandbox/sandbox-types.js +1 -0
  39. package/dist/domains/sandbox/sandbox-utils.d.ts +3 -0
  40. package/dist/domains/sandbox/sandbox-utils.js +109 -0
  41. package/dist/domains/search/search-handler.d.ts +47 -0
  42. package/dist/domains/search/search-handler.js +113 -0
  43. package/dist/domains/search/search-route.d.ts +2 -0
  44. package/dist/domains/search/search-route.js +101 -0
  45. package/dist/domains/search/search-schema.d.ts +384 -0
  46. package/dist/domains/search/search-schema.js +99 -0
  47. package/dist/domains/search/search-so.d.ts +55 -0
  48. package/dist/{search/search-service.js → domains/search/search-so.js} +200 -297
  49. package/dist/shared/config/environment.d.ts +16 -0
  50. package/dist/shared/config/environment.js +41 -0
  51. package/dist/shared/schemas/common-schema.d.ts +249 -0
  52. package/dist/{schema.js → shared/schemas/common-schema.js} +37 -80
  53. package/dist/shared/schemas/index.d.ts +1 -0
  54. package/dist/shared/schemas/index.js +1 -0
  55. package/dist/shared/scripts-helpers/index.d.ts +60 -0
  56. package/dist/shared/scripts-helpers/index.js +61 -0
  57. package/dist/shared/utils/file-util.d.ts +1 -0
  58. package/dist/shared/utils/file-util.js +5 -0
  59. package/dist/shared/utils/index.d.ts +5 -0
  60. package/dist/shared/utils/index.js +5 -0
  61. package/dist/shared/utils/mcp-client-util.d.ts +31 -0
  62. package/dist/shared/utils/mcp-client-util.js +79 -0
  63. package/dist/shared/utils/package-util.d.ts +6 -0
  64. package/dist/shared/utils/package-util.js +53 -0
  65. package/dist/shared/utils/promise-util.d.ts +1 -0
  66. package/dist/shared/utils/promise-util.js +14 -0
  67. package/dist/{utils.d.ts → shared/utils/response-util.d.ts} +6 -2
  68. package/dist/{utils.js → shared/utils/response-util.js} +1 -6
  69. package/dist/shared/utils/string-util.d.ts +1 -0
  70. package/dist/shared/utils/string-util.js +25 -0
  71. package/dist/shared/utils/validation-util.d.ts +12 -0
  72. package/dist/shared/utils/validation-util.js +99 -0
  73. package/indexes/categories-list.json +1 -0
  74. package/indexes/packages-list.json +6 -0
  75. package/package.json +9 -2
  76. package/packages/developer-tools/neurolink.json +23 -0
  77. package/packages/search-data-extraction/ref-tools-mcp.json +7 -2
  78. package/README.dev.md +0 -195
  79. package/dist/api/package-handler.d.ts +0 -18
  80. package/dist/api/package-handler.js +0 -72
  81. package/dist/api/package-route.d.ts +0 -2
  82. package/dist/api/package-so.d.ts +0 -19
  83. package/dist/api/package-so.js +0 -263
  84. package/dist/api/package.test.js +0 -19
  85. package/dist/helper.d.ts +0 -72
  86. package/dist/helper.js +0 -278
  87. package/dist/sandbox/mcp-sandbox-client.d.ts +0 -37
  88. package/dist/sandbox/mcp-sandbox-client.js +0 -428
  89. package/dist/schema.d.ts +0 -806
  90. package/dist/search/search-route.d.ts +0 -3
  91. package/dist/search/search-route.js +0 -305
  92. package/dist/search/search-service.d.ts +0 -120
  93. package/dist/search/search.test.js +0 -100
  94. package/dist/types.d.ts +0 -27
  95. /package/dist/{api/package.test.d.ts → domains/config/config-types.js} +0 -0
  96. /package/dist/{search/search.test.d.ts → domains/executor/executor-types.js} +0 -0
  97. /package/dist/{types.js → domains/package/package-so.test.d.ts} +0 -0
@@ -1,263 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { getMcpClient, getPackageConfigByKey, typedAllPackagesList } from "../helper.js";
4
- import { MCPSandboxClient } from "../sandbox/mcp-sandbox-client.js";
5
- import { getDirname } from "../utils";
6
- const __dirname = getDirname(import.meta.url);
7
- export class PackageSO {
8
- constructor(useSandbox = false) {
9
- this.useSandbox = false;
10
- this.sandboxClient = null;
11
- this.useSandbox = useSandbox;
12
- if (useSandbox) {
13
- const sandboxKey = "default";
14
- const record = PackageSO.sandboxInstances.get(sandboxKey);
15
- if (record) {
16
- record.refCount++;
17
- record.lastUsedAt = Date.now();
18
- this.sandboxClient = record.client;
19
- // Cancel all idle close timer
20
- record.client.touch();
21
- }
22
- else {
23
- // Create a new instance if none exists (subject to max limit)
24
- this.sandboxClient = new MCPSandboxClient();
25
- const newRecord = {
26
- client: this.sandboxClient,
27
- refCount: 1,
28
- lastUsedAt: Date.now(),
29
- idleCloseMs: PackageSO.IDLE_CLOSE_MS,
30
- };
31
- // Try to insert, evict LRU idle instance if MAX is reached
32
- if (PackageSO.sandboxInstances.size >= PackageSO.MAX_SANDBOXES) {
33
- // Find the oldest idle instance (refCount === 0)
34
- let lruKey = null;
35
- let lruTime = Infinity;
36
- for (const [k, r] of PackageSO.sandboxInstances) {
37
- if (r.refCount === 0 && r.lastUsedAt < lruTime) {
38
- lruKey = k;
39
- lruTime = r.lastUsedAt;
40
- }
41
- }
42
- if (lruKey) {
43
- const evict = PackageSO.sandboxInstances.get(lruKey);
44
- // Immediately close and delete
45
- if (evict) {
46
- evict.client.kill().catch((e) => {
47
- console.error("[PackageSO] Error killing evicted sandbox:", e);
48
- });
49
- PackageSO.sandboxInstances.delete(lruKey);
50
- }
51
- }
52
- else {
53
- // No recyclable instances -> throw error to prevent exceeding system limit
54
- throw new Error("Cannot create new sandbox: max sandboxes reached and none are idle");
55
- }
56
- }
57
- PackageSO.sandboxInstances.set(sandboxKey, newRecord);
58
- }
59
- }
60
- }
61
- // Acquire / Release explicit APIs (for external or future use)
62
- static async acquireSandbox(key = "default") {
63
- const record = PackageSO.sandboxInstances.get(key);
64
- if (record) {
65
- record.refCount++;
66
- record.lastUsedAt = Date.now();
67
- record.client.touch();
68
- return record.client;
69
- }
70
- // Create new instance (note MAX_SANDBOXES check, consistent with constructor logic)
71
- if (PackageSO.sandboxInstances.size >= PackageSO.MAX_SANDBOXES) {
72
- // Try to evict LRU idle instance
73
- let lruKey = null;
74
- let lruTime = Infinity;
75
- for (const [k, r] of PackageSO.sandboxInstances) {
76
- if (r.refCount === 0 && r.lastUsedAt < lruTime) {
77
- lruKey = k;
78
- lruTime = r.lastUsedAt;
79
- }
80
- }
81
- if (lruKey) {
82
- const evict = PackageSO.sandboxInstances.get(lruKey);
83
- if (evict) {
84
- await evict.client
85
- .kill()
86
- .catch((e) => console.error("[PackageSO] Error killing evicted sandbox:", e));
87
- PackageSO.sandboxInstances.delete(lruKey);
88
- }
89
- }
90
- else {
91
- throw new Error("Cannot create new sandbox: max sandboxes reached and none are idle");
92
- }
93
- }
94
- const client = new MCPSandboxClient();
95
- const newRecord = {
96
- client,
97
- refCount: 1,
98
- lastUsedAt: Date.now(),
99
- idleCloseMs: PackageSO.IDLE_CLOSE_MS,
100
- };
101
- PackageSO.sandboxInstances.set(key, newRecord);
102
- return client;
103
- }
104
- static async releaseSandbox(key = "default") {
105
- const record = PackageSO.sandboxInstances.get(key);
106
- if (!record)
107
- return;
108
- record.refCount = Math.max(0, record.refCount - 1);
109
- record.lastUsedAt = Date.now();
110
- if (record.refCount === 0) {
111
- // schedule idle close after IDLE_CLOSE_MS
112
- record.client.scheduleIdleClose(record.idleCloseMs || PackageSO.IDLE_CLOSE_MS);
113
- }
114
- }
115
- // Cleanup all static sandbox instances safely
116
- static async cleanupSandboxInstances() {
117
- const killers = [];
118
- for (const [key, record] of PackageSO.sandboxInstances) {
119
- killers.push((async () => {
120
- try {
121
- await record.client.kill();
122
- }
123
- catch (err) {
124
- console.error("[PackageSO] cleanup error for sandbox", key, err);
125
- }
126
- })());
127
- PackageSO.sandboxInstances.delete(key);
128
- }
129
- await Promise.all(killers);
130
- }
131
- async executeTool(request) {
132
- const mcpServerConfig = getPackageConfigByKey(request.packageName);
133
- if (this.useSandbox && mcpServerConfig.runtime === "node") {
134
- try {
135
- const result = await this.executeToolInSandbox(request);
136
- return result;
137
- }
138
- catch (error) {
139
- console.warn(`[executeTool] Sandbox mode failed for tool ${request.toolKey} in package ${request.packageName}, falling back to local mode:`, error);
140
- }
141
- }
142
- const { client, closeConnection } = await getMcpClient(mcpServerConfig, request.envs || {});
143
- try {
144
- const result = await client.callTool({
145
- name: request.toolKey,
146
- arguments: request.inputData,
147
- });
148
- console.log(`Tool ${request.toolKey} executed successfully`);
149
- return result;
150
- }
151
- finally {
152
- await closeConnection();
153
- }
154
- }
155
- async executeToolInSandbox(request) {
156
- if (!this.sandboxClient) {
157
- throw new Error("Sandbox client not initialized");
158
- }
159
- // Initialize if not already initialized (concurrency protection via MCPSandboxClient.initialize)
160
- await this.sandboxClient.initialize();
161
- // Mark usage
162
- this.sandboxClient.touch();
163
- try {
164
- const result = await this.sandboxClient.executeTool(request.packageName, request.toolKey, request.inputData || {}, request.envs);
165
- console.log(`Tool ${request.toolKey} executed successfully in sandbox`);
166
- return result;
167
- }
168
- catch (error) {
169
- // If it's a sandbox not found error, try reinitializing and retrying once
170
- if (error instanceof Error && error.message.includes("sandbox was not found")) {
171
- console.log("[PackageSO] Retrying tool execution after sandbox failure");
172
- await this.sandboxClient.initialize();
173
- // Retry tool execution
174
- const result = await this.sandboxClient.executeTool(request.packageName, request.toolKey, request.inputData || {}, request.envs);
175
- console.log(`Tool ${request.toolKey} executed successfully in sandbox (retry)`);
176
- return result;
177
- }
178
- throw error;
179
- }
180
- finally {
181
- // Release reference count
182
- await PackageSO.releaseSandbox("default");
183
- }
184
- }
185
- async listTools(packageName) {
186
- const mcpServerConfig = getPackageConfigByKey(packageName);
187
- if (this.useSandbox && mcpServerConfig.runtime === "node") {
188
- try {
189
- const tools = await this.listToolsInSandbox(packageName);
190
- return tools;
191
- }
192
- catch (error) {
193
- console.warn(`[listTools] Sandbox mode failed for package ${packageName}, falling back to local mode:`, error);
194
- }
195
- }
196
- const mockEnvs = {};
197
- if (mcpServerConfig.env) {
198
- Object.keys(mcpServerConfig.env).forEach((key) => {
199
- mockEnvs[key] = "mock_value";
200
- });
201
- }
202
- const { client, closeConnection } = await getMcpClient(mcpServerConfig, mockEnvs);
203
- try {
204
- const { tools } = await client.listTools();
205
- console.log(`Tools list retrieved successfully for package ${packageName}`);
206
- return tools;
207
- }
208
- finally {
209
- await closeConnection();
210
- }
211
- }
212
- async listToolsInSandbox(packageName) {
213
- if (!this.sandboxClient) {
214
- throw new Error("Sandbox client not initialized");
215
- }
216
- // Initialize only if sandbox is not initialized
217
- await this.sandboxClient.initialize();
218
- this.sandboxClient.touch();
219
- try {
220
- const tools = await this.sandboxClient.listTools(packageName);
221
- console.log(`Tools list retrieved successfully for package ${packageName} in sandbox`);
222
- return tools;
223
- }
224
- catch (error) {
225
- // If it's a sandbox not found error, try reinitializing and retrying once
226
- if (error instanceof Error && error.message.includes("sandbox was not found")) {
227
- console.log("[PackageSO] Retrying tools listing after sandbox failure");
228
- await this.sandboxClient.initialize();
229
- // Retry listing tools
230
- const tools = await this.sandboxClient.listTools(packageName);
231
- console.log(`Tools list retrieved successfully for package ${packageName} in sandbox (retry)`);
232
- return tools;
233
- }
234
- throw error;
235
- }
236
- finally {
237
- await PackageSO.releaseSandbox("default");
238
- }
239
- }
240
- async getPackageDetail(packageName) {
241
- const packageInfo = typedAllPackagesList[packageName];
242
- if (!packageInfo) {
243
- throw new Error(`Package ${packageName} not found`);
244
- }
245
- const jsonFilePath = path.join(__dirname, "../../packages/", packageInfo.path);
246
- const jsonStr = fs.readFileSync(jsonFilePath, "utf-8");
247
- const packageConfig = JSON.parse(jsonStr);
248
- let tools;
249
- try {
250
- tools = await this.listTools(packageName);
251
- }
252
- catch (error) {
253
- console.warn(`Warn retrieving tools for package ${packageName}:`, error.message);
254
- // if tools cannot be retrieved, set tools to undefined
255
- tools = undefined;
256
- }
257
- const packageConfigWithTools = Object.assign(Object.assign({}, packageConfig), { tools });
258
- return packageConfigWithTools;
259
- }
260
- }
261
- PackageSO.sandboxInstances = new Map();
262
- PackageSO.MAX_SANDBOXES = 10;
263
- PackageSO.IDLE_CLOSE_MS = 5 * 60 * 1000;
@@ -1,19 +0,0 @@
1
- // npx vitest run src/api/package.test.ts
2
- import { describe, expect, it } from "vitest";
3
- import { PackageSO } from "./package-so";
4
- describe("PackageSO - MCP Tool Execution Service Test", () => {
5
- it("should execute tool successfully", async () => {
6
- const toolSO = new PackageSO();
7
- const request = {
8
- packageName: "mcp-starter",
9
- toolKey: "hello_tool",
10
- inputData: { name: "Mike" },
11
- envs: {},
12
- };
13
- const result = await toolSO.executeTool(request);
14
- expect(result).toEqual({
15
- content: [],
16
- message: "Hello, Mike!",
17
- });
18
- });
19
- });
package/dist/helper.d.ts DELETED
@@ -1,72 +0,0 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
- import type { MCPServerPackageConfig } from "./types";
4
- export declare const typedAllPackagesList: Record<string, {
5
- path: string;
6
- category?: string | undefined;
7
- validated?: boolean | undefined;
8
- tools?: Record<string, {
9
- description?: string | undefined;
10
- name?: string | undefined;
11
- }> | undefined;
12
- }>;
13
- export declare function getPackageConfigByKey(packageKey: string): MCPServerPackageConfig;
14
- export declare function getPackageJSON(packageName: string): any;
15
- export declare function getMcpClient(mcpServerConfig: MCPServerPackageConfig, env?: Record<string, string>): Promise<{
16
- client: Client<{
17
- method: string;
18
- params?: {
19
- [x: string]: unknown;
20
- _meta?: {
21
- [x: string]: unknown;
22
- progressToken?: string | number | undefined;
23
- } | undefined;
24
- } | undefined;
25
- }, {
26
- method: string;
27
- params?: {
28
- [x: string]: unknown;
29
- _meta?: {
30
- [x: string]: unknown;
31
- } | undefined;
32
- } | undefined;
33
- }, {
34
- [x: string]: unknown;
35
- _meta?: {
36
- [x: string]: unknown;
37
- } | undefined;
38
- }>;
39
- transport: StdioClientTransport;
40
- closeConnection: () => Promise<void>;
41
- }>;
42
- export declare function updatePackageJsonDependencies({ packageDeps, enableValidation, }: {
43
- packageDeps: Record<string, string>;
44
- enableValidation?: boolean;
45
- }): void;
46
- export declare function getActualVersion(packageName: string, configuredVersion?: string): string;
47
- export declare function withTimeout<T>(ms: number, promise: Promise<T>): Promise<T>;
48
- export declare function isValidNpmPackage(packageName: string): Promise<boolean>;
49
- interface PyProjectToml {
50
- project?: {
51
- dependencies?: string[];
52
- [key: string]: unknown;
53
- };
54
- [key: string]: unknown;
55
- }
56
- /**
57
- * Parses the pyproject.toml file and returns its content
58
- * @returns Parsed pyproject.toml content
59
- */
60
- export declare function parsePyprojectToml(): PyProjectToml;
61
- /**
62
- * Extracts package name from a dependency string
63
- * @param dep - Dependency string (e.g., "package>=1.0.0")
64
- * @returns Package name without version constraints
65
- */
66
- export declare function extractPackageName(dep: string): string;
67
- /**
68
- * Gets Python dependencies from pyproject.toml
69
- * @returns Array of Python dependency names
70
- */
71
- export declare function getPythonDependencies(): string[];
72
- export {};
package/dist/helper.js DELETED
@@ -1,278 +0,0 @@
1
- import assert from "node:assert";
2
- import fs from "node:fs";
3
- import * as path from "node:path";
4
- import toml from "@iarna/toml";
5
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
6
- import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
7
- import axios from "axios";
8
- import semver from "semver";
9
- import allPackagesList from "../indexes/packages-list.json";
10
- import { getDirname } from "../src/utils";
11
- import { MCPServerPackageConfigSchema, PackagesListSchema } from "./schema";
12
- const __dirname = getDirname(import.meta.url);
13
- export const typedAllPackagesList = PackagesListSchema.parse(allPackagesList);
14
- export function getPackageConfigByKey(packageKey) {
15
- const value = typedAllPackagesList[packageKey];
16
- if (!value) {
17
- throw new Error(`Package '${packageKey}' not found in packages list.`);
18
- }
19
- const jsonFile = value.path;
20
- // read the JSON file and convert it to MCPServerPackageConfig
21
- const jsonStr = fs.readFileSync(`${__dirname}/../packages/${jsonFile}`, "utf-8");
22
- const mcpServerConfig = MCPServerPackageConfigSchema.parse(JSON.parse(jsonStr));
23
- return mcpServerConfig;
24
- }
25
- export function getPackageJSON(packageName) {
26
- const packageJSONFilePath = `${__dirname}/../node_modules/${packageName}/package.json`;
27
- // Check if the package exists in node_modules
28
- if (!fs.existsSync(packageJSONFilePath)) {
29
- throw new Error(`Package '${packageName}' not found in node_modules. Install it first with: pnpm add ${packageName}`);
30
- }
31
- const packageJSONStr = fs.readFileSync(packageJSONFilePath, "utf8");
32
- const packageJSON = JSON.parse(packageJSONStr);
33
- return packageJSON;
34
- }
35
- async function createMcpClient(mcpServerConfig, transport) {
36
- const { packageName, name } = mcpServerConfig;
37
- const client = new Client({
38
- name: `mcp-server-${name}-client`,
39
- version: "1.0.0",
40
- }, {
41
- capabilities: {
42
- tools: {},
43
- },
44
- });
45
- await client.connect(transport);
46
- const closeConnection = async () => {
47
- try {
48
- await client.close();
49
- }
50
- catch (e) {
51
- console.warn(`${packageName} mcp client close failure.`, e);
52
- }
53
- };
54
- return { client, transport, closeConnection };
55
- }
56
- async function getNodeMcpClient(mcpServerConfig, env) {
57
- const { packageName } = mcpServerConfig;
58
- const packageJSON = getPackageJSON(packageName);
59
- let binFilePath = "";
60
- let binPath;
61
- if (typeof packageJSON.bin === "string") {
62
- binPath = packageJSON.bin;
63
- }
64
- else if (typeof packageJSON.bin === "object") {
65
- binPath = Object.values(packageJSON.bin)[0];
66
- }
67
- else {
68
- binPath = packageJSON.main;
69
- }
70
- assert(binPath, `Package ${packageName} does not have a valid bin path in package.json.`);
71
- binFilePath = `${__dirname}/../node_modules/${packageName}/${binPath}`;
72
- const mcpServerBinPath = mcpServerConfig.bin || binFilePath;
73
- const binArgs = mcpServerConfig.binArgs || [];
74
- const transport = new StdioClientTransport({
75
- args: [mcpServerBinPath, ...binArgs],
76
- command: process.execPath,
77
- env: env || {},
78
- });
79
- return createMcpClient(mcpServerConfig, transport);
80
- }
81
- async function getPyMcpClient(mcpServerConfig, env) {
82
- const { packageName } = mcpServerConfig;
83
- const pythonModuleName = packageName;
84
- const transport = new StdioClientTransport({
85
- command: "uv",
86
- args: ["run", "--directory", "./python-mcp", pythonModuleName],
87
- env: Object.assign(Object.assign({}, Object.fromEntries(Object.entries(process.env).filter(([_, v]) => v !== undefined))), env),
88
- });
89
- return createMcpClient(mcpServerConfig, transport);
90
- }
91
- export async function getMcpClient(mcpServerConfig, env) {
92
- const { runtime } = mcpServerConfig;
93
- if (runtime === "python") {
94
- return getPyMcpClient(mcpServerConfig, env);
95
- }
96
- return getNodeMcpClient(mcpServerConfig, env);
97
- }
98
- export function updatePackageJsonDependencies({ packageDeps, enableValidation = false, }) {
99
- var _a;
100
- // Write package.json dependencies
101
- const packageJsonFile = "./package.json";
102
- const packageJSONStr = fs.readFileSync(packageJsonFile, "utf-8");
103
- const newDeps = {
104
- "@e2b/code-interpreter": "^2.0.0",
105
- "@modelcontextprotocol/sdk": "^1.12.0",
106
- "@hono/node-server": "1.15.0",
107
- "@hono/swagger-ui": "^0.5.2",
108
- "@hono/zod-openapi": "^0.16.4",
109
- "@iarna/toml": "^2.2.5",
110
- meilisearch: "^0.33.0",
111
- lodash: "^4.17.21",
112
- zod: "^3.23.30",
113
- axios: "^1.9.0",
114
- hono: "4.8.3",
115
- semver: "^7.5.4",
116
- };
117
- for (const [depName, depVer] of Object.entries(packageDeps)) {
118
- if (!enableValidation || ((_a = typedAllPackagesList[depName]) === null || _a === void 0 ? void 0 : _a.validated)) {
119
- newDeps[depName] = depVer || "latest";
120
- }
121
- }
122
- // const blacklistDeps = new Set([
123
- // "@mcp-server/google-search-mcp",
124
- // "@executeautomation/playwright-mcp-server",
125
- // ]);
126
- // for (const dep of blacklistDeps) {
127
- // if (newDeps[dep]) {
128
- // delete newDeps[dep];
129
- // }
130
- // }
131
- const packageJSON = JSON.parse(packageJSONStr);
132
- packageJSON.dependencies = newDeps;
133
- fs.writeFileSync(packageJsonFile, JSON.stringify(packageJSON, null, 2), "utf-8");
134
- console.log(`Generated new package.json file at ${packageJsonFile}`);
135
- return;
136
- }
137
- export function getActualVersion(packageName, configuredVersion) {
138
- if (configuredVersion && configuredVersion !== "latest") {
139
- return configuredVersion;
140
- }
141
- try {
142
- const packageJsonPath = path.join(__dirname, "../node_modules", packageName, "package.json");
143
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
144
- return packageJson.version;
145
- }
146
- catch (e) {
147
- console.warn(`Failed to read version for ${packageName}, using 'latest' by default`, e.message);
148
- return "latest";
149
- }
150
- }
151
- export function withTimeout(ms, promise) {
152
- return new Promise((resolve, reject) => {
153
- const timer = setTimeout(() => {
154
- reject(new Error(`Operation timed out after ${ms}ms`));
155
- }, ms);
156
- promise.then((res) => {
157
- clearTimeout(timer);
158
- resolve(res);
159
- }, (err) => {
160
- clearTimeout(timer);
161
- reject(err);
162
- });
163
- });
164
- }
165
- function checkDependencyValidity(dependencyData, versionRange) {
166
- // 兼容 "latest" 的情况
167
- if (versionRange === "latest") {
168
- return Object.keys(dependencyData.versions).length > 0;
169
- }
170
- // 使用 semver 检查是否有满足版本范围的有效版本
171
- const versions = Object.keys(dependencyData.versions);
172
- for (const version of versions) {
173
- if (semver.satisfies(version, versionRange)) {
174
- return true;
175
- }
176
- }
177
- return false;
178
- }
179
- async function checkDependencies(dependencies) {
180
- const dependencyCache = {};
181
- const checkSingleDependency = async (depName, depVersionRange) => {
182
- const cacheKey = `${depName}@${depVersionRange}`;
183
- if (dependencyCache[cacheKey] !== undefined) {
184
- return dependencyCache[cacheKey];
185
- }
186
- try {
187
- const depResponse = await axios.get(`https://registry.npmjs.org/${depName}`, {
188
- timeout: 5000,
189
- headers: {
190
- "User-Agent": "MyToolManager/1.0",
191
- },
192
- });
193
- if (depResponse.status !== 200 || !depResponse.data.versions) {
194
- console.error(`Failed to fetch ${depName}`);
195
- dependencyCache[cacheKey] = false;
196
- return false;
197
- }
198
- const isValid = checkDependencyValidity(depResponse.data, depVersionRange);
199
- dependencyCache[cacheKey] = isValid;
200
- if (!isValid) {
201
- console.error(`Invalid or missing: ${depName}`);
202
- }
203
- return isValid;
204
- }
205
- catch (error) {
206
- console.error(`Error fetching ${depName}: ${error.message}`);
207
- dependencyCache[cacheKey] = false;
208
- return false;
209
- }
210
- };
211
- const promises = Object.entries(dependencies).map(([depName, depVersionRange]) => checkSingleDependency(depName, depVersionRange));
212
- const results = await Promise.all(promises);
213
- return results.every((result) => result);
214
- }
215
- export async function isValidNpmPackage(packageName) {
216
- var _a, _b, _c, _d;
217
- try {
218
- // 检查主包是否存在
219
- console.log("checking package:", packageName);
220
- const response = await axios.get(`https://registry.npmjs.org/${packageName}`, {
221
- timeout: 5000,
222
- headers: {
223
- "User-Agent": "MyToolManager/1.0",
224
- },
225
- });
226
- // 检查主包是否被标记为 unpublished
227
- if (response.status !== 200 || !((_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a["dist-tags"]) === null || _b === void 0 ? void 0 : _b.latest)) {
228
- console.error(`Package marked as unpublished: ${packageName}`);
229
- return false;
230
- }
231
- // 获取主包的最新版本信息
232
- const latestVersion = response.data["dist-tags"].latest;
233
- const versionData = (_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.versions) === null || _d === void 0 ? void 0 : _d[latestVersion];
234
- if (!versionData) {
235
- console.error(`Invalid package: ${packageName} - No version data found`);
236
- return false;
237
- }
238
- // 检查 dependencies 和 devDependencies
239
- console.log(`Checking dependencies for ${packageName}`);
240
- const dependencies = Object.assign(Object.assign({}, versionData.dependencies), versionData.devDependencies);
241
- if (!(await checkDependencies(dependencies))) {
242
- return false;
243
- }
244
- console.log(`Valid package: ${packageName}`);
245
- return true;
246
- }
247
- catch (error) {
248
- console.error(`Error validating package ${packageName}:`, error.message);
249
- return false;
250
- }
251
- }
252
- /**
253
- * Parses the pyproject.toml file and returns its content
254
- * @returns Parsed pyproject.toml content
255
- */
256
- export function parsePyprojectToml() {
257
- const pyprojectPath = "./python-mcp/pyproject.toml";
258
- const content = fs.readFileSync(pyprojectPath, "utf-8");
259
- return toml.parse(content);
260
- }
261
- /**
262
- * Extracts package name from a dependency string
263
- * @param dep - Dependency string (e.g., "package>=1.0.0")
264
- * @returns Package name without version constraints
265
- */
266
- export function extractPackageName(dep) {
267
- return dep.split(/[=<>!]/)[0].trim();
268
- }
269
- /**
270
- * Gets Python dependencies from pyproject.toml
271
- * @returns Array of Python dependency names
272
- */
273
- export function getPythonDependencies() {
274
- var _a;
275
- const data = parsePyprojectToml();
276
- const deps = ((_a = data.project) === null || _a === void 0 ? void 0 : _a.dependencies) || [];
277
- return deps.map(extractPackageName);
278
- }
@@ -1,37 +0,0 @@
1
- import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
- export declare class MCPSandboxClient {
3
- private sandbox;
4
- private initializing;
5
- private readonly apiKey;
6
- private toolCache;
7
- private readonly E2B_SANDBOX_TIMEOUT_MS;
8
- private readonly TOOL_CACHE_TTL;
9
- TOOL_EXECUTION_TIMEOUT: number;
10
- private lastTouchTime;
11
- private readonly THROTTLE_DELAY_MS;
12
- createdAt: number | null;
13
- lastUsedAt: number | null;
14
- private ttlTimer;
15
- private autoCloseOnIdleTimer;
16
- private idleCloseMs;
17
- constructor(apiKey?: string);
18
- initialize(): Promise<void>;
19
- private setupTTLTimer;
20
- /**
21
- * Update sandbox last used time
22
- */
23
- touch(): void;
24
- /**
25
- * Actually perform the touch operation
26
- */
27
- private performTouch;
28
- scheduleIdleClose(idleMs: number): void;
29
- kill(): Promise<void>;
30
- clearPackageCache(packageKey: string): void;
31
- clearAllCache(): void;
32
- listTools(packageKey: string): Promise<Tool[]>;
33
- executeTool(packageKey: string, toolName: string, argumentsObj: Record<string, unknown>, envs?: Record<string, string>): Promise<unknown>;
34
- private runCodeWithTimeout;
35
- private generateMCPTestCode;
36
- private generateEnvVariables;
37
- }