@toolsdk.ai/registry 1.0.115 → 1.0.117
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 +122 -34
- package/dist/domains/sandbox/clients/daytona-client.js +18 -8
- package/dist/domains/sandbox/clients/sandock-client.d.ts +2 -0
- package/dist/domains/sandbox/clients/sandock-client.js +86 -46
- package/dist/domains/sandbox/sandbox-utils.js +16 -1
- package/dist/shared/utils/mcp-client-util.js +7 -0
- package/package.json +32 -2
package/README.md
CHANGED
|
@@ -9,25 +9,53 @@
|
|
|
9
9
|

|
|
10
10
|

|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
🚀 **Open-source**, **production-ready**, and **developer-friendly** registry for 4108+ Model Context Protocol (MCP) servers, plugins, and AI agent tools.
|
|
13
|
+
|
|
14
|
+
Perfect for **AI automation**, **chatbot development**, **LLM integrations**, and **enterprise AI deployments**.
|
|
13
15
|
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
</div>
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
## 🌟 Why Awesome MCP Registry?
|
|
21
|
+
|
|
22
|
+
**Awesome MCP Registry** is the most comprehensive, self-hosted registry for Model Context Protocol (MCP) servers and AI agent tools. Built for developers, teams, and enterprises who need full control over their AI infrastructure.
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
### 🎯 Key Features
|
|
21
25
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
26
|
+
- 🔐 **Private & Self-Hosted** - Deploy your own secure MCP registry with Docker in minutes
|
|
27
|
+
- 🤖 **4108+ AI Tools** - Largest curated collection of MCP servers for Claude, LLMs, and AI agents
|
|
28
|
+
- ⚡ **Remote Execution** - Run MCP tools in isolated sandbox environments via REST API
|
|
29
|
+
- 🔍 **Powerful Search** - Fast, full-text search powered by Meilisearch
|
|
30
|
+
- 📦 **NPM Integration** - Use as a TypeScript/Node.js SDK in your projects
|
|
31
|
+
- 🛠️ **Developer-Friendly** - OpenAPI/Swagger documentation, structured JSON configs
|
|
32
|
+
- 🐳 **Docker Ready** - Production-grade deployment with Docker Compose
|
|
33
|
+
- 🔌 **Plugin System** - Extensible architecture for custom integrations
|
|
25
34
|
|
|
26
|
-
|
|
35
|
+
### 💡 Use Cases
|
|
27
36
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
37
|
+
- 🏢 **Enterprise AI Teams** - Deploy private MCP registry for your organization
|
|
38
|
+
- 🤖 **AI Agent Development** - Build and test AI agents with verified MCP tools
|
|
39
|
+
- 💬 **Chatbot Builders** - Integrate LLM-powered chatbots with MCP servers
|
|
40
|
+
- 🔧 **Developer Tools** - Access automation tools, APIs, and integrations
|
|
41
|
+
- 🚀 **CI/CD Automation** - Execute MCP tools in your deployment pipelines
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 📦 What You Get
|
|
46
|
+
|
|
47
|
+
This open-source registry provides:
|
|
48
|
+
|
|
49
|
+
- 📚 **Structured Database** - 4108+ validated MCP servers with metadata
|
|
50
|
+
- 🔗 **Multiple Formats** - JSON, npm package, and generated documentation
|
|
51
|
+
- 🌐 **REST API** - Query and execute tools remotely
|
|
52
|
+
- 📖 **Auto-Generated Docs** - Always up-to-date README and API documentation
|
|
53
|
+
|
|
54
|
+
**Available as:**
|
|
55
|
+
|
|
56
|
+
- 📄 `README.md` - Human-readable documentation
|
|
57
|
+
- 📦 [npm package](https://www.npmjs.com/package/@toolsdk.ai/registry) - TypeScript/JavaScript SDK
|
|
58
|
+
- 🔗 [packages-list.json](https://toolsdk-ai.github.io/awesome-mcp-registry/indexes/packages-list.json) - Raw data API
|
|
31
59
|
|
|
32
60
|
---
|
|
33
61
|
|
|
@@ -78,75 +106,118 @@ This registry leverages structured JSON configs to generate:
|
|
|
78
106
|
|
|
79
107
|
## 🚀 Quick Start
|
|
80
108
|
|
|
81
|
-
### 🐳
|
|
109
|
+
### 🐳 Self-Hosted MCP Registry with Docker
|
|
110
|
+
|
|
111
|
+
Deploy your own **private MCP registry** in 5 minutes! Get a production-ready AI agent tool registry with full-text search, REST API, and secure sandbox execution.
|
|
82
112
|
|
|
83
|
-
|
|
113
|
+
Perfect for **AI developers**, **LLM teams**, and **enterprises** building with Claude, Anthropic, and other AI platforms.
|
|
84
114
|
|
|
85
|
-
#### Quick Deploy (2 Steps)
|
|
115
|
+
#### ⚡ Quick Deploy (2 Steps)
|
|
86
116
|
|
|
87
|
-
**Step 1:
|
|
117
|
+
**Step 1: Configure Sandbox Environment**
|
|
88
118
|
|
|
89
|
-
- Get your Sandock API Key from https://sandock.ai
|
|
119
|
+
- Get your Sandock API Key from https://sandock.ai (for secure remote code execution)
|
|
90
120
|
- Edit `.env` and set: `SANDOCK_API_KEY=your-api-key-here`
|
|
91
121
|
|
|
92
|
-
**Step 2:
|
|
122
|
+
**Step 2: Launch with Docker Compose**
|
|
93
123
|
|
|
94
124
|
```bash
|
|
95
125
|
docker compose up -d
|
|
96
126
|
```
|
|
97
127
|
|
|
98
|
-
|
|
128
|
+
That's it! Your self-hosted MCP registry is now running with:
|
|
129
|
+
- 🔍 **Full-text search** (Meilisearch)
|
|
130
|
+
- 🌐 **REST API** with OpenAPI documentation
|
|
131
|
+
- 🛡️ **Sandbox execution** for AI agent tools
|
|
132
|
+
|
|
133
|
+
#### 🎉 Access Your Private AI Tool Registry
|
|
99
134
|
|
|
100
135
|
- 🌐 **Web Interface**: http://localhost:3003
|
|
101
|
-
- 📚 **API
|
|
102
|
-
- 🔍 **Search & Execute** MCP tools remotely
|
|
136
|
+
- 📚 **Swagger API Docs**: http://localhost:3003/swagger
|
|
137
|
+
- 🔍 **Search & Execute** 4108+ MCP tools remotely
|
|
138
|
+
- 🤖 **Integrate** with your AI agents, chatbots, and LLM applications
|
|
139
|
+
|
|
140
|
+
#### 💻 Remote Tool Execution Example
|
|
103
141
|
|
|
104
|
-
|
|
142
|
+
Execute any MCP tool via REST API - perfect for AI automation, chatbot integrations, and serverless deployments:
|
|
105
143
|
|
|
106
144
|
```bash
|
|
107
|
-
# Execute a tool remotely
|
|
108
145
|
curl -X POST http://localhost:3003/api/v1/packages/run \
|
|
109
146
|
-H "Content-Type: application/json" \
|
|
110
147
|
-d '{
|
|
111
148
|
"packageName": "@modelcontextprotocol/server-everything",
|
|
112
149
|
"toolKey": "echo",
|
|
113
150
|
"inputData": {
|
|
114
|
-
"message": "Hello
|
|
151
|
+
"message": "Hello from Awesome MCP Registry!"
|
|
115
152
|
},
|
|
116
153
|
"envs": {}
|
|
117
154
|
}'
|
|
118
155
|
```
|
|
119
156
|
|
|
120
|
-
|
|
157
|
+
**Use Cases:**
|
|
158
|
+
- 🤖 Build AI agents with remote tool execution
|
|
159
|
+
- 💬 Power chatbots with MCP server integrations
|
|
160
|
+
- 🚀 Create serverless AI workflows
|
|
161
|
+
- 🔧 Automate tasks with LLM-powered tools
|
|
162
|
+
|
|
163
|
+
> 📖 For advanced deployment options and configuration, see the [DEVELOPMENT documentation](./docs/DEVELOPMENT.md#4--quick-start-with-docker).
|
|
121
164
|
|
|
122
165
|
<a id="install-via-package-manager"></a>
|
|
123
166
|
|
|
124
|
-
### Install
|
|
167
|
+
### 📦 Install as NPM Package (TypeScript/Node.js SDK)
|
|
168
|
+
|
|
169
|
+
Use the MCP Registry as a TypeScript/JavaScript SDK in your AI agent, chatbot, or LLM integration projects:
|
|
125
170
|
|
|
126
171
|
```bash
|
|
127
172
|
npm install @toolsdk.ai/registry
|
|
128
173
|
```
|
|
129
174
|
|
|
130
|
-
|
|
175
|
+
#### Use in TypeScript/JavaScript Projects
|
|
176
|
+
|
|
177
|
+
Perfect for AI agent development, chatbot builders, and LLM tool integrations:
|
|
131
178
|
|
|
132
179
|
```ts
|
|
133
180
|
import mcpServerLists from '@toolsdk.ai/registry/indexes/packages-lists.json';
|
|
134
181
|
```
|
|
135
182
|
|
|
136
|
-
|
|
183
|
+
#### 🌐 Access via Public API (No Installation Required)
|
|
184
|
+
|
|
185
|
+
Fetch the complete MCP server registry programmatically - ideal for AI applications, integrations, and automation:
|
|
137
186
|
|
|
138
187
|
```bash
|
|
139
188
|
curl https://toolsdk-ai.github.io/awesome-mcp-registry/indexes/packages-list.json
|
|
140
189
|
```
|
|
141
190
|
|
|
142
191
|
```ts
|
|
143
|
-
// JavaScript
|
|
144
|
-
|
|
192
|
+
// JavaScript/TypeScript - Fetch API
|
|
193
|
+
const mcpServers = await (
|
|
194
|
+
await fetch('https://toolsdk-ai.github.io/awesome-mcp-registry/indexes/packages-list.json')
|
|
195
|
+
).json();
|
|
196
|
+
|
|
197
|
+
// Use for AI agent tool discovery, LLM integrations, etc.
|
|
198
|
+
console.log(mcpServers);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
# Python - For AI/ML projects
|
|
203
|
+
import requests
|
|
204
|
+
|
|
205
|
+
mcp_servers = requests.get(
|
|
206
|
+
'https://toolsdk-ai.github.io/awesome-mcp-registry/indexes/packages-list.json'
|
|
207
|
+
).json()
|
|
208
|
+
|
|
209
|
+
# Perfect for LangChain, CrewAI, AutoGen integrations
|
|
145
210
|
```
|
|
146
211
|
|
|
147
212
|
<a id="submit-new-mcp-servers"></a>
|
|
148
213
|
|
|
149
|
-
##
|
|
214
|
+
## 🤝 Contribute Your MCP Server
|
|
215
|
+
|
|
216
|
+
Help grow the world's largest open-source MCP registry! Share your AI tools, plugins, and integrations with the community.
|
|
217
|
+
|
|
218
|
+
### How to Submit
|
|
219
|
+
|
|
220
|
+
**1. Create JSON Config** - Simple, structured format:
|
|
150
221
|
|
|
151
222
|
```json
|
|
152
223
|
{
|
|
@@ -166,17 +237,34 @@ console.log(await(await fetch('https://toolsdk-ai.github.io/awesome-mcp-registry
|
|
|
166
237
|
}
|
|
167
238
|
```
|
|
168
239
|
|
|
169
|
-
|
|
240
|
+
**2. Submit via Pull Request**
|
|
241
|
+
|
|
242
|
+
- [Fork this repository](https://github.com/toolsdk-ai/awesome-mcp-registry/fork)
|
|
243
|
+
- Create `your-mcp-server.json` in [packages/uncategorized](./packages/uncategorized)
|
|
244
|
+
- Submit a PR and join 4108+ MCP servers!
|
|
245
|
+
|
|
246
|
+
**3. Get Discovered**
|
|
247
|
+
|
|
248
|
+
Your MCP server will be:
|
|
249
|
+
- ✅ Listed in the registry
|
|
250
|
+
- 🔍 Searchable via REST API
|
|
251
|
+
- 📦 Available in npm package
|
|
252
|
+
- 🌐 Featured on our website
|
|
170
253
|
|
|
171
|
-
|
|
254
|
+
📖 **Detailed Guide**: [Contributing Documentation](./docs/guide.md)
|
|
255
|
+
|
|
256
|
+
---
|
|
172
257
|
|
|
173
258
|
<a id="mcp-servers"></a>
|
|
174
259
|
|
|
175
|
-
## MCP Servers
|
|
260
|
+
## 📋 MCP Servers Directory
|
|
261
|
+
|
|
262
|
+
**4108+ AI Agent Tools, LLM Integrations & Automation Servers**
|
|
176
263
|
|
|
177
|
-
|
|
264
|
+
- ✅ **Validated & Tested** (709) - Production-ready MCP servers
|
|
265
|
+
- ⚙️ **Community Contributed** (3399) - Requires configuration
|
|
178
266
|
|
|
179
|
-
|
|
267
|
+
Browse by category: Developer Tools, AI Agents, Databases, Cloud Platforms, APIs, and more!
|
|
180
268
|
|
|
181
269
|
|
|
182
270
|
|
|
@@ -5,6 +5,22 @@ import { getDirname } from "../../../shared/utils/file-util";
|
|
|
5
5
|
import { extractLastOuterJSON } from "../../../shared/utils/string-util";
|
|
6
6
|
import { PackageRepository } from "../../package/package-repository";
|
|
7
7
|
import { generateMCPTestCode } from "../sandbox-utils";
|
|
8
|
+
// Singleton Daytona client shared across all instances to prevent memory leaks
|
|
9
|
+
let sharedDaytonaClient = null;
|
|
10
|
+
function getDaytonaClient() {
|
|
11
|
+
if (!sharedDaytonaClient) {
|
|
12
|
+
const config = getDaytonaConfig();
|
|
13
|
+
const daytonaConfig = {
|
|
14
|
+
apiKey: config.apiKey,
|
|
15
|
+
};
|
|
16
|
+
if (config.apiUrl) {
|
|
17
|
+
daytonaConfig.apiUrl = config.apiUrl;
|
|
18
|
+
}
|
|
19
|
+
sharedDaytonaClient = new Daytona(daytonaConfig);
|
|
20
|
+
console.log("[DaytonaSandboxClient] Shared Daytona client initialized");
|
|
21
|
+
}
|
|
22
|
+
return sharedDaytonaClient;
|
|
23
|
+
}
|
|
8
24
|
/**
|
|
9
25
|
* Daytona Sandbox Client
|
|
10
26
|
* Implements SandboxClient interface for Daytona provider
|
|
@@ -27,14 +43,8 @@ export class DaytonaSandboxClient {
|
|
|
27
43
|
}
|
|
28
44
|
this.initializing = (async () => {
|
|
29
45
|
try {
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
apiKey: config.apiKey,
|
|
33
|
-
};
|
|
34
|
-
if (config.apiUrl) {
|
|
35
|
-
daytonaConfig.apiUrl = config.apiUrl;
|
|
36
|
-
}
|
|
37
|
-
const daytona = new Daytona(daytonaConfig);
|
|
46
|
+
// Use shared singleton Daytona client instead of creating new one per initialization
|
|
47
|
+
const daytona = getDaytonaClient();
|
|
38
48
|
const declarativeImage = Image.base("node:20")
|
|
39
49
|
.runCommands("npm install -g pnpm", "mkdir -p /workspace", "cd /workspace && npm init -y", "cd /workspace && pnpm add @modelcontextprotocol/sdk")
|
|
40
50
|
.workdir("/workspace");
|
|
@@ -13,7 +13,9 @@ export declare class SandockSandboxClient implements SandboxClient {
|
|
|
13
13
|
initialize(): Promise<void>;
|
|
14
14
|
private executeShellCommand;
|
|
15
15
|
private executeCode;
|
|
16
|
+
private cleanupTempFileAsync;
|
|
16
17
|
listTools(packageKey: string): Promise<Tool[]>;
|
|
17
18
|
executeTool(packageKey: string, toolName: string, argumentsObj: Record<string, unknown>, envs?: Record<string, string>): Promise<unknown>;
|
|
18
19
|
destroy(): Promise<void>;
|
|
20
|
+
private destroySandboxAsync;
|
|
19
21
|
}
|
|
@@ -5,6 +5,21 @@ import { getDirname } from "../../../shared/utils/file-util";
|
|
|
5
5
|
import { extractLastOuterJSON } from "../../../shared/utils/string-util";
|
|
6
6
|
import { PackageRepository } from "../../package/package-repository";
|
|
7
7
|
import { generateMCPTestCode } from "../sandbox-utils";
|
|
8
|
+
// Singleton HTTP client shared across all instances to prevent memory leaks
|
|
9
|
+
let sharedSandockClient = null;
|
|
10
|
+
function getSandockClient() {
|
|
11
|
+
if (!sharedSandockClient) {
|
|
12
|
+
const config = getSandockConfig();
|
|
13
|
+
sharedSandockClient = createSandockClient({
|
|
14
|
+
baseUrl: config.apiUrl,
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
console.log("[SandockSandboxClient] Shared HTTP client initialized");
|
|
20
|
+
}
|
|
21
|
+
return sharedSandockClient;
|
|
22
|
+
}
|
|
8
23
|
/**
|
|
9
24
|
* Sandock Sandbox Client
|
|
10
25
|
* Implements SandboxClient interface for Sandock provider
|
|
@@ -16,13 +31,8 @@ export class SandockSandboxClient {
|
|
|
16
31
|
const __dirname = getDirname(import.meta.url);
|
|
17
32
|
const packagesDir = path.join(__dirname, "../../../../packages");
|
|
18
33
|
this.packageRepository = new PackageRepository(packagesDir);
|
|
19
|
-
|
|
20
|
-
this.client =
|
|
21
|
-
baseUrl: config.apiUrl,
|
|
22
|
-
headers: {
|
|
23
|
-
Authorization: `Bearer ${config.apiKey}`,
|
|
24
|
-
},
|
|
25
|
-
});
|
|
34
|
+
// Use shared singleton client instead of creating new one per instance
|
|
35
|
+
this.client = getSandockClient();
|
|
26
36
|
}
|
|
27
37
|
async initialize() {
|
|
28
38
|
if (this.sandboxId) {
|
|
@@ -35,17 +45,16 @@ export class SandockSandboxClient {
|
|
|
35
45
|
this.initializing = (async () => {
|
|
36
46
|
try {
|
|
37
47
|
// Create sandbox with pre-built MCP image
|
|
38
|
-
const
|
|
48
|
+
const { data, error } = await this.client.POST("/api/sandbox", {
|
|
39
49
|
body: {
|
|
40
50
|
image: "seey/sandock-mcp:latest",
|
|
41
51
|
workdir: "/mcpspace",
|
|
42
52
|
},
|
|
43
53
|
});
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
throw new Error(`Failed to create sandbox: ${errorMsg}`);
|
|
54
|
+
if (error) {
|
|
55
|
+
throw new Error(`Failed to create sandbox: ${JSON.stringify(error)}`);
|
|
47
56
|
}
|
|
48
|
-
this.sandboxId =
|
|
57
|
+
this.sandboxId = data.data.id;
|
|
49
58
|
console.log(`[SandockSandboxClient] Sandbox created successfully: ${this.sandboxId}`);
|
|
50
59
|
}
|
|
51
60
|
catch (error) {
|
|
@@ -62,7 +71,7 @@ export class SandockSandboxClient {
|
|
|
62
71
|
if (!this.sandboxId) {
|
|
63
72
|
throw new Error("Sandbox not initialized. Call initialize() first.");
|
|
64
73
|
}
|
|
65
|
-
const
|
|
74
|
+
const { data, error } = await this.client.POST("/api/sandbox/{id}/shell", {
|
|
66
75
|
params: {
|
|
67
76
|
path: {
|
|
68
77
|
id: this.sandboxId,
|
|
@@ -72,12 +81,11 @@ export class SandockSandboxClient {
|
|
|
72
81
|
cmd,
|
|
73
82
|
},
|
|
74
83
|
});
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
throw new Error(`Shell command failed: ${errorMsg}`);
|
|
84
|
+
if (error) {
|
|
85
|
+
throw new Error(`Shell command failed: ${JSON.stringify(error)}`);
|
|
78
86
|
}
|
|
79
|
-
const stdout =
|
|
80
|
-
const stderr =
|
|
87
|
+
const stdout = data.data.stdout || "";
|
|
88
|
+
const stderr = data.data.stderr || "";
|
|
81
89
|
if (stderr.trim()) {
|
|
82
90
|
console.log(`[SandockSandboxClient] stderr: ${stderr}`);
|
|
83
91
|
}
|
|
@@ -100,22 +108,40 @@ export class SandockSandboxClient {
|
|
|
100
108
|
},
|
|
101
109
|
});
|
|
102
110
|
const output = await this.executeShellCommand(`cd /mcpspace && node ${tempFile}`);
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
query: { path: tempFile },
|
|
109
|
-
},
|
|
110
|
-
})
|
|
111
|
-
.catch((error) => {
|
|
112
|
-
console.warn("[SandockSandboxClient] Warning: Could not delete temp file:", error);
|
|
111
|
+
// Fire-and-forget: cleanup temp file in background without blocking result return
|
|
112
|
+
// The cleanup will complete asynchronously, and logs will appear when it does
|
|
113
|
+
this.cleanupTempFileAsync(tempFile, this.sandboxId).catch((err) => {
|
|
114
|
+
// This should never happen due to internal error handling, but just in case
|
|
115
|
+
console.error("[SandockSandboxClient] Unexpected error in cleanupTempFileAsync:", err);
|
|
113
116
|
});
|
|
114
117
|
return {
|
|
115
118
|
exitCode: 0,
|
|
116
119
|
result: output,
|
|
117
120
|
};
|
|
118
121
|
}
|
|
122
|
+
async cleanupTempFileAsync(tempFile, sandboxId) {
|
|
123
|
+
if (!sandboxId) {
|
|
124
|
+
console.warn("[SandockSandboxClient] Sandbox ID is null, skipping temp file cleanup");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const { error } = await this.client.DELETE("/api/sandbox/{id}/fs", {
|
|
129
|
+
params: {
|
|
130
|
+
path: { id: sandboxId },
|
|
131
|
+
query: { path: tempFile },
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
if (error) {
|
|
135
|
+
console.warn(`[SandockSandboxClient] Warning: Could not delete temp file ${tempFile}:`, error);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
console.log(`[SandockSandboxClient] Temp file ${tempFile} deleted successfully`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (cleanupError) {
|
|
142
|
+
console.warn(`[SandockSandboxClient] Error during temp file cleanup for ${tempFile}:`, cleanupError);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
119
145
|
async listTools(packageKey) {
|
|
120
146
|
const mcpServerConfig = this.packageRepository.getPackageConfig(packageKey);
|
|
121
147
|
const testCode = generateMCPTestCode(mcpServerConfig, "listTools");
|
|
@@ -146,33 +172,47 @@ export class SandockSandboxClient {
|
|
|
146
172
|
if (!this.sandboxId) {
|
|
147
173
|
return;
|
|
148
174
|
}
|
|
149
|
-
const
|
|
175
|
+
const sandboxIdToDelete = this.sandboxId;
|
|
150
176
|
this.sandboxId = null; // Clear immediately to avoid duplicate calls
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
177
|
+
// Fire-and-forget: destroy sandbox in background without blocking
|
|
178
|
+
// The cleanup will complete asynchronously, and logs will appear when it does
|
|
179
|
+
this.destroySandboxAsync(sandboxIdToDelete).catch((err) => {
|
|
180
|
+
// This should never happen due to internal error handling, but just in case
|
|
181
|
+
console.error("[SandockSandboxClient] Unexpected error in destroySandboxAsync:", err);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async destroySandboxAsync(sandboxId) {
|
|
185
|
+
try {
|
|
186
|
+
// Delete sandbox completely using the fs delete API with root path
|
|
187
|
+
// This removes all files and effectively shuts down the sandbox
|
|
188
|
+
const { error } = await this.client.DELETE("/api/sandbox/{id}/fs", {
|
|
189
|
+
params: {
|
|
190
|
+
path: { id: sandboxId },
|
|
191
|
+
query: { path: "/" },
|
|
157
192
|
},
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
193
|
+
});
|
|
194
|
+
if (error) {
|
|
195
|
+
// Check if error is "not found" (already deleted)
|
|
196
|
+
const errorStr = JSON.stringify(error);
|
|
197
|
+
if (errorStr.includes("not found") || errorStr.includes("404")) {
|
|
198
|
+
console.log(`[SandockSandboxClient] Sandbox ${sandboxId} already deleted (not found on platform)`);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
console.warn(`[SandockSandboxClient] Warning: Could not delete sandbox ${sandboxId}: ${errorStr}`);
|
|
202
|
+
}
|
|
163
203
|
}
|
|
164
204
|
else {
|
|
165
|
-
console.log(
|
|
205
|
+
console.log(`[SandockSandboxClient] Sandbox ${sandboxId} deleted successfully`);
|
|
166
206
|
}
|
|
167
|
-
}
|
|
168
|
-
|
|
207
|
+
}
|
|
208
|
+
catch (err) {
|
|
169
209
|
const errorMessage = err.message;
|
|
170
210
|
if (errorMessage.includes("not found") || errorMessage.includes("404")) {
|
|
171
|
-
console.log(
|
|
211
|
+
console.log(`[SandockSandboxClient] Sandbox ${sandboxId} already deleted (not found on platform)`);
|
|
172
212
|
}
|
|
173
213
|
else {
|
|
174
|
-
console.warn(
|
|
214
|
+
console.warn(`[SandockSandboxClient] Warning: Could not delete sandbox ${sandboxId}: ${errorMessage}`);
|
|
175
215
|
}
|
|
176
|
-
}
|
|
216
|
+
}
|
|
177
217
|
}
|
|
178
218
|
}
|
|
@@ -17,10 +17,11 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
|
|
|
17
17
|
|
|
18
18
|
async function runMCP() {
|
|
19
19
|
let client;
|
|
20
|
+
let transport;
|
|
20
21
|
try {
|
|
21
22
|
const packageName = "${mcpServerConfig.packageName}";
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
transport = new StdioClientTransport({
|
|
24
25
|
command: "pnpx",
|
|
25
26
|
args: ["--silent", packageName],
|
|
26
27
|
env: {
|
|
@@ -69,6 +70,13 @@ async function runMCP() {
|
|
|
69
70
|
console.error("Error closing MCP client:", closeError);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
73
|
+
if (transport) {
|
|
74
|
+
try {
|
|
75
|
+
await transport.close();
|
|
76
|
+
} catch (transportError) {
|
|
77
|
+
console.error("Error closing transport:", transportError);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
72
80
|
}
|
|
73
81
|
}
|
|
74
82
|
|
|
@@ -100,6 +108,13 @@ runMCP();
|
|
|
100
108
|
console.error("Error closing MCP client:", closeError);
|
|
101
109
|
}
|
|
102
110
|
}
|
|
111
|
+
if (transport) {
|
|
112
|
+
try {
|
|
113
|
+
await transport.close();
|
|
114
|
+
} catch (transportError) {
|
|
115
|
+
console.error("Error closing transport:", transportError);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
103
118
|
}
|
|
104
119
|
}
|
|
105
120
|
|
|
@@ -32,6 +32,13 @@ async function createMcpClient(mcpServerConfig, transport) {
|
|
|
32
32
|
catch (e) {
|
|
33
33
|
console.warn(`${packageName} mcp client close failure.`, e);
|
|
34
34
|
}
|
|
35
|
+
// Close transport to release child process and file descriptors
|
|
36
|
+
try {
|
|
37
|
+
await transport.close();
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
console.warn(`${packageName} mcp transport close failure.`, e);
|
|
41
|
+
}
|
|
35
42
|
};
|
|
36
43
|
return { client, transport, closeConnection };
|
|
37
44
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toolsdk.ai/registry",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.117",
|
|
4
4
|
"description": "An Open, Structured, and Standard Registry for MCP Servers and Packages.",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"mcp-server",
|
|
9
|
+
"mcp-registry",
|
|
10
|
+
"ai",
|
|
11
|
+
"llm",
|
|
12
|
+
"ai-agent",
|
|
13
|
+
"agent",
|
|
14
|
+
"ai-tools",
|
|
15
|
+
"claude",
|
|
16
|
+
"anthropic",
|
|
17
|
+
"chatbot",
|
|
18
|
+
"automation",
|
|
19
|
+
"registry",
|
|
20
|
+
"package-registry",
|
|
21
|
+
"self-hosted",
|
|
22
|
+
"private-registry",
|
|
23
|
+
"docker",
|
|
24
|
+
"typescript",
|
|
25
|
+
"nodejs",
|
|
26
|
+
"plugin",
|
|
27
|
+
"integration",
|
|
28
|
+
"sdk",
|
|
29
|
+
"openapi",
|
|
30
|
+
"rest-api",
|
|
31
|
+
"sandbox",
|
|
32
|
+
"remote-execution",
|
|
33
|
+
"search",
|
|
34
|
+
"developer-tools"
|
|
35
|
+
],
|
|
6
36
|
"license": "MIT",
|
|
7
37
|
"author": "",
|
|
8
38
|
"type": "module",
|