@toolsdk.ai/registry 1.0.92 → 1.0.94

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,3 @@
1
+ import { Hono } from 'hono';
2
+ declare const app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
+ export default app;
@@ -0,0 +1,26 @@
1
+ import dotenv from 'dotenv';
2
+ import path from 'path';
3
+ import { Hono } from 'hono';
4
+ import { serve } from '@hono/node-server';
5
+ import { packageRoutes } from './package-route';
6
+ dotenv.config({ path: path.resolve(process.cwd(), '.env.local') });
7
+ dotenv.config({ path: path.resolve(process.cwd(), '.env') });
8
+ const app = new Hono();
9
+ app.route('/api/v1', packageRoutes);
10
+ app.get('/', (c) => {
11
+ return c.text('MCP Registry API Server is running!');
12
+ });
13
+ app.notFound((c) => {
14
+ return c.json({ success: false, code: 404, message: 'Route not found' }, 404);
15
+ });
16
+ app.onError((err, c) => {
17
+ console.error('Server Error:', err);
18
+ return c.json({ success: false, code: 500, message: 'Internal server error' }, 500);
19
+ });
20
+ const port = process.env.MCP_SERVER_PORT ? parseInt(process.env.MCP_SERVER_PORT) : 3000;
21
+ console.log(`Server is running on: http://localhost:${port}`);
22
+ serve({
23
+ fetch: app.fetch,
24
+ port,
25
+ });
26
+ export default app;
@@ -0,0 +1,39 @@
1
+ import { Context } from 'hono';
2
+ export declare const packageHandler: {
3
+ executeTool: (c: Context) => Promise<(globalThis.Response & import("hono").TypedResponse<never, 200 | 500, "json">) | (globalThis.Response & import("hono").TypedResponse<{
4
+ success: false;
5
+ code: number;
6
+ message: string;
7
+ }, 404, "json">)>;
8
+ getPackageDetail: (c: Context) => Promise<(globalThis.Response & import("hono").TypedResponse<{
9
+ success: false;
10
+ code: number;
11
+ message: string;
12
+ }, 400, "json">) | (globalThis.Response & import("hono").TypedResponse<{
13
+ success: boolean;
14
+ code: number;
15
+ message: string;
16
+ data?: {
17
+ type: "mcp-server";
18
+ packageName: string;
19
+ runtime: "node" | "python" | "java" | "go";
20
+ key?: string | undefined;
21
+ name?: string | undefined;
22
+ description?: string | undefined;
23
+ packageVersion?: string | undefined;
24
+ bin?: string | undefined;
25
+ binArgs?: string[] | undefined;
26
+ readme?: string | undefined;
27
+ url?: string | undefined;
28
+ license?: string | undefined;
29
+ logo?: string | undefined;
30
+ author?: string | undefined;
31
+ env?: {
32
+ [x: string]: {
33
+ description: string;
34
+ required: boolean;
35
+ };
36
+ } | undefined;
37
+ } | undefined;
38
+ }, 200 | 404, "json">)>;
39
+ };
@@ -0,0 +1,37 @@
1
+ import { PackageSO } from './package-so';
2
+ export const packageHandler = {
3
+ executeTool: async (c) => {
4
+ const requestBody = await c.req.json();
5
+ try {
6
+ const toolSO = new PackageSO();
7
+ const result = await toolSO.executeTool(requestBody);
8
+ const statusCode = result.success ? 200 : 500;
9
+ return c.json(result, statusCode);
10
+ }
11
+ catch (error) {
12
+ if (error instanceof Error && (error.message.includes('not found') || error.message.includes('Unknown tool'))) {
13
+ return c.json({
14
+ success: false,
15
+ code: 404,
16
+ message: `Package '${requestBody.packageName}' or tool '${requestBody.toolKey}' not found`,
17
+ }, 404);
18
+ }
19
+ // Other errors are still thrown
20
+ throw error;
21
+ }
22
+ },
23
+ getPackageDetail: async (c) => {
24
+ const packageName = c.req.query('packageName');
25
+ if (!packageName) {
26
+ return c.json({
27
+ success: false,
28
+ code: 400,
29
+ message: 'Missing packageName query parameter',
30
+ }, 400);
31
+ }
32
+ const toolSO = new PackageSO();
33
+ const result = await toolSO.getPackageDetail(packageName);
34
+ const statusCode = result.success ? 200 : 404;
35
+ return c.json(result, statusCode);
36
+ },
37
+ };
@@ -0,0 +1,2 @@
1
+ import { Hono } from 'hono';
2
+ export declare const packageRoutes: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
@@ -0,0 +1,36 @@
1
+ /* eslint-disable @typescript-eslint/no-require-imports */
2
+ import { Hono } from 'hono';
3
+ import { packageHandler } from './package-handler';
4
+ export const packageRoutes = new Hono();
5
+ packageRoutes.post('/packages/run', packageHandler.executeTool);
6
+ packageRoutes.get('/packages/detail', packageHandler.getPackageDetail);
7
+ packageRoutes.get('/config/categories', (c) => {
8
+ const categories = require('../../config/categories.mjs').default;
9
+ const response = {
10
+ success: true,
11
+ code: 200,
12
+ message: 'Categories retrieved successfully',
13
+ data: categories,
14
+ };
15
+ return c.json(response);
16
+ });
17
+ packageRoutes.get('/config/featured', (c) => {
18
+ const featured = require('../../config/featured.mjs').default;
19
+ const response = {
20
+ success: true,
21
+ code: 200,
22
+ message: 'Featured list retrieved successfully',
23
+ data: featured,
24
+ };
25
+ return c.json(response);
26
+ });
27
+ packageRoutes.get('/indexes/packages-list', async (c) => {
28
+ const packagesList = (await import('../../indexes/packages-list.json')).default;
29
+ const response = {
30
+ success: true,
31
+ code: 200,
32
+ message: 'Packages list retrieved successfully',
33
+ data: packagesList,
34
+ };
35
+ return c.json(response);
36
+ });
@@ -0,0 +1,5 @@
1
+ import type { MCPServerPackageConfig, ToolExecute, Response } from '../types';
2
+ export declare class PackageSO {
3
+ executeTool(request: ToolExecute): Promise<Response<unknown>>;
4
+ getPackageDetail(packageName: string): Promise<Response<MCPServerPackageConfig>>;
5
+ }
@@ -0,0 +1,44 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { getPackageConfigByKey, getMcpClient, typedAllPackagesList } from '../helper.js';
4
+ export class PackageSO {
5
+ async executeTool(request) {
6
+ const mcpServerConfig = getPackageConfigByKey(request.packageName);
7
+ const { client, closeConnection } = await getMcpClient(mcpServerConfig, request.envs || {});
8
+ try {
9
+ const result = await client.callTool({
10
+ name: request.toolKey,
11
+ arguments: request.inputData,
12
+ });
13
+ console.log(`Tool ${request.toolKey} executed successfully`);
14
+ return {
15
+ success: true,
16
+ code: 200,
17
+ message: 'Tool executed successfully',
18
+ data: result,
19
+ };
20
+ }
21
+ finally {
22
+ await closeConnection();
23
+ }
24
+ }
25
+ async getPackageDetail(packageName) {
26
+ const packageInfo = typedAllPackagesList[packageName];
27
+ if (!packageInfo) {
28
+ return {
29
+ success: false,
30
+ code: 404,
31
+ message: `Package ${packageName} not found`,
32
+ };
33
+ }
34
+ const jsonFilePath = path.join(__dirname, '../../packages/', packageInfo.path);
35
+ const jsonStr = fs.readFileSync(jsonFilePath, 'utf-8');
36
+ const packageConfig = JSON.parse(jsonStr);
37
+ return {
38
+ success: true,
39
+ code: 200,
40
+ message: 'Package detail retrieved successfully',
41
+ data: packageConfig,
42
+ };
43
+ }
44
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ // npx vitest run src/api/package.test.ts
2
+ import { describe, it, expect } 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.success).toBe(true);
15
+ expect(result.data).toEqual({
16
+ content: [],
17
+ message: 'Hello, Mike!',
18
+ });
19
+ });
20
+ });
package/dist/helper.js CHANGED
@@ -1,141 +1,89 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
1
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
2
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
+ import fs from 'fs';
4
+ import axios from 'axios';
5
+ import semver from 'semver';
6
+ import * as path from 'path';
7
+ import allPackagesList from '../indexes/packages-list.json';
8
+ import assert from 'assert';
9
+ import { MCPServerPackageConfigSchema, PackagesListSchema } from './schema';
10
+ export const typedAllPackagesList = PackagesListSchema.parse(allPackagesList);
11
+ export function getPackageConfigByKey(packageKey) {
12
+ const value = typedAllPackagesList[packageKey];
13
+ if (!value) {
14
+ throw new Error(`Package '${packageKey}' not found in packages list.`);
7
15
  }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __importDefault = (this && this.__importDefault) || function (mod) {
45
- return (mod && mod.__esModule) ? mod : { "default": mod };
46
- };
47
- Object.defineProperty(exports, "__esModule", { value: true });
48
- exports.typedAllPackagesList = void 0;
49
- exports.getPackageConfigByKey = getPackageConfigByKey;
50
- exports.getPackageJSON = getPackageJSON;
51
- exports.getMcpClient = getMcpClient;
52
- exports.updatePackageJsonDependencies = updatePackageJsonDependencies;
53
- exports.getActualVersion = getActualVersion;
54
- exports.withTimeout = withTimeout;
55
- exports.isValidNpmPackage = isValidNpmPackage;
56
- const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
57
- const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
58
- const fs_1 = __importDefault(require("fs"));
59
- const axios_1 = __importDefault(require("axios"));
60
- const semver_1 = __importDefault(require("semver"));
61
- const path = __importStar(require("path"));
62
- const packages_list_json_1 = __importDefault(require("../indexes/packages-list.json"));
63
- const assert_1 = __importDefault(require("assert"));
64
- const schema_1 = require("./schema");
65
- exports.typedAllPackagesList = schema_1.PackagesListSchema.parse(packages_list_json_1.default);
66
- function getPackageConfigByKey(packageKey) {
67
- const value = exports.typedAllPackagesList[packageKey];
68
16
  const jsonFile = value.path;
69
17
  // read the JSON file and convert it to MCPServerPackageConfig
70
- const jsonStr = fs_1.default.readFileSync(__dirname + '/../packages/' + jsonFile, 'utf-8');
71
- const mcpServerConfig = schema_1.MCPServerPackageConfigSchema.parse(JSON.parse(jsonStr));
18
+ const jsonStr = fs.readFileSync(__dirname + '/../packages/' + jsonFile, 'utf-8');
19
+ const mcpServerConfig = MCPServerPackageConfigSchema.parse(JSON.parse(jsonStr));
72
20
  return mcpServerConfig;
73
21
  }
74
- function getPackageJSON(packageName) {
22
+ export function getPackageJSON(packageName) {
75
23
  const packageJSONFilePath = __dirname + '/../node_modules/' + packageName + '/package.json';
76
- const packageJSONStr = fs_1.default.readFileSync(packageJSONFilePath, 'utf8');
24
+ const packageJSONStr = fs.readFileSync(packageJSONFilePath, 'utf8');
77
25
  const packageJSON = JSON.parse(packageJSONStr);
78
26
  return packageJSON;
79
27
  }
80
- function getMcpClient(mcpServerConfig, env) {
81
- return __awaiter(this, void 0, void 0, function* () {
82
- const { packageName } = mcpServerConfig;
83
- const packageJSON = getPackageJSON(packageName);
84
- let binFilePath = '';
85
- let binPath;
86
- if (typeof packageJSON.bin === 'string') {
87
- binPath = packageJSON.bin;
88
- }
89
- else if (typeof packageJSON.bin === 'object') {
90
- binPath = Object.values(packageJSON.bin)[0];
28
+ export async function getMcpClient(mcpServerConfig, env) {
29
+ const { packageName } = mcpServerConfig;
30
+ const packageJSON = getPackageJSON(packageName);
31
+ let binFilePath = '';
32
+ let binPath;
33
+ if (typeof packageJSON.bin === 'string') {
34
+ binPath = packageJSON.bin;
35
+ }
36
+ else if (typeof packageJSON.bin === 'object') {
37
+ binPath = Object.values(packageJSON.bin)[0];
38
+ }
39
+ else {
40
+ binPath = packageJSON.main;
41
+ }
42
+ assert(binPath, `Package ${packageName} does not have a valid bin path in package.json.`);
43
+ // binFilePath = 'plugin_packages/' + packageName + `/${binPath}`;
44
+ binFilePath = __dirname + '/../node_modules/' + packageName + `/${binPath}`;
45
+ const mcpServerBinPath = mcpServerConfig.bin || binFilePath;
46
+ const binArgs = mcpServerConfig.binArgs || [];
47
+ const transport = new StdioClientTransport({
48
+ command: process.execPath,
49
+ args: [mcpServerBinPath, ...binArgs],
50
+ env: env || {},
51
+ });
52
+ const client = new Client({
53
+ name: `mcp-server-${mcpServerConfig.name}-client`,
54
+ version: '1.0.0',
55
+ }, {
56
+ capabilities: {
57
+ tools: {},
58
+ },
59
+ });
60
+ await client.connect(transport);
61
+ const closeConnection = async () => {
62
+ try {
63
+ await client.close();
91
64
  }
92
- else {
93
- binPath = packageJSON.main;
65
+ catch (e) {
66
+ console.warn(`${packageName} mcp client close failure.`, e);
94
67
  }
95
- (0, assert_1.default)(binPath, `Package ${packageName} does not have a valid bin path in package.json.`);
96
- // binFilePath = 'plugin_packages/' + packageName + `/${binPath}`;
97
- binFilePath = __dirname + '/../node_modules/' + packageName + `/${binPath}`;
98
- const mcpServerBinPath = mcpServerConfig.bin || binFilePath;
99
- const binArgs = mcpServerConfig.binArgs || [];
100
- const transport = new stdio_js_1.StdioClientTransport({
101
- command: process.execPath,
102
- args: [mcpServerBinPath, ...binArgs],
103
- env: env || {},
104
- });
105
- const client = new index_js_1.Client({
106
- name: `mcp-server-${mcpServerConfig.name}-client`,
107
- version: '1.0.0',
108
- }, {
109
- capabilities: {
110
- tools: {},
111
- },
112
- });
113
- yield client.connect(transport);
114
- const closeConnection = () => __awaiter(this, void 0, void 0, function* () {
115
- try {
116
- yield client.close();
117
- }
118
- catch (e) {
119
- console.warn(`${packageName} mcp client close failure.`, e);
120
- }
121
- });
122
- return { client, transport, closeConnection };
123
- });
68
+ };
69
+ return { client, transport, closeConnection };
124
70
  }
125
- function updatePackageJsonDependencies({ packageDeps, enableValidation = false, }) {
71
+ export function updatePackageJsonDependencies({ packageDeps, enableValidation = false, }) {
126
72
  var _a;
127
73
  // Write package.json dependencies
128
74
  const packageJsonFile = './package.json';
129
- const packageJSONStr = fs_1.default.readFileSync(packageJsonFile, 'utf-8');
75
+ const packageJSONStr = fs.readFileSync(packageJsonFile, 'utf-8');
130
76
  const newDeps = {
131
77
  '@modelcontextprotocol/sdk': '^1.12.0',
78
+ '@hono/node-server': '1.15.0',
132
79
  lodash: '^4.17.21',
133
80
  zod: '^3.23.30',
134
81
  axios: '^1.9.0',
82
+ hono: '4.8.3',
135
83
  semver: '^7.5.4',
136
84
  };
137
85
  for (const [depName, depVer] of Object.entries(packageDeps)) {
138
- if (!enableValidation || ((_a = exports.typedAllPackagesList[depName]) === null || _a === void 0 ? void 0 : _a.validated)) {
86
+ if (!enableValidation || ((_a = typedAllPackagesList[depName]) === null || _a === void 0 ? void 0 : _a.validated)) {
139
87
  newDeps[depName] = depVer || 'latest';
140
88
  }
141
89
  }
@@ -147,17 +95,17 @@ function updatePackageJsonDependencies({ packageDeps, enableValidation = false,
147
95
  }
148
96
  const packageJSON = JSON.parse(packageJSONStr);
149
97
  packageJSON.dependencies = newDeps;
150
- fs_1.default.writeFileSync(packageJsonFile, JSON.stringify(packageJSON, null, 2), 'utf-8');
98
+ fs.writeFileSync(packageJsonFile, JSON.stringify(packageJSON, null, 2), 'utf-8');
151
99
  console.log(`Generated new package.json file at ${packageJsonFile}`);
152
100
  return;
153
101
  }
154
- function getActualVersion(packageName, configuredVersion) {
102
+ export function getActualVersion(packageName, configuredVersion) {
155
103
  if (configuredVersion && configuredVersion !== 'latest') {
156
104
  return configuredVersion;
157
105
  }
158
106
  try {
159
107
  const packageJsonPath = path.join(__dirname, '../node_modules', packageName, 'package.json');
160
- const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
108
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
161
109
  return packageJson.version;
162
110
  }
163
111
  catch (e) {
@@ -165,7 +113,7 @@ function getActualVersion(packageName, configuredVersion) {
165
113
  return 'latest';
166
114
  }
167
115
  }
168
- function withTimeout(ms, promise) {
116
+ export function withTimeout(ms, promise) {
169
117
  return new Promise((resolve, reject) => {
170
118
  const timer = setTimeout(() => {
171
119
  reject(new Error(`Operation timed out after ${ms}ms`));
@@ -188,88 +136,84 @@ function checkDependencyValidity(dependencyData, versionRange) {
188
136
  // 使用 semver 检查是否有满足版本范围的有效版本
189
137
  const versions = Object.keys(dependencyData.versions);
190
138
  for (const version of versions) {
191
- if (semver_1.default.satisfies(version, versionRange)) {
139
+ if (semver.satisfies(version, versionRange)) {
192
140
  return true;
193
141
  }
194
142
  }
195
143
  return false;
196
144
  }
197
145
  // 通用依赖项检查函数
198
- function checkDependencies(dependencies) {
199
- return __awaiter(this, void 0, void 0, function* () {
200
- const dependencyCache = {};
201
- const checkSingleDependency = (depName, depVersionRange) => __awaiter(this, void 0, void 0, function* () {
202
- const cacheKey = `${depName}@${depVersionRange}`;
203
- if (dependencyCache[cacheKey] !== undefined) {
204
- return dependencyCache[cacheKey];
205
- }
206
- try {
207
- const depResponse = yield axios_1.default.get(`https://registry.npmjs.org/${depName}`, {
208
- timeout: 5000,
209
- headers: {
210
- 'User-Agent': 'MyToolManager/1.0',
211
- },
212
- });
213
- if (depResponse.status !== 200 || !depResponse.data.versions) {
214
- console.error(`Failed to fetch ${depName}`);
215
- dependencyCache[cacheKey] = false;
216
- return false;
217
- }
218
- const isValid = checkDependencyValidity(depResponse.data, depVersionRange);
219
- dependencyCache[cacheKey] = isValid;
220
- if (!isValid) {
221
- console.error(`Invalid or missing: ${depName}`);
222
- }
223
- return isValid;
224
- }
225
- catch (error) {
226
- console.error(`Error fetching ${depName}: ${error.message}`);
227
- dependencyCache[cacheKey] = false;
228
- return false;
229
- }
230
- });
231
- const promises = Object.entries(dependencies).map(([depName, depVersionRange]) => checkSingleDependency(depName, depVersionRange));
232
- const results = yield Promise.all(promises);
233
- return results.every((result) => result);
234
- });
235
- }
236
- // 判断 npm 包及其依赖是否有效
237
- function isValidNpmPackage(packageName) {
238
- return __awaiter(this, void 0, void 0, function* () {
239
- var _a, _b, _c, _d;
146
+ async function checkDependencies(dependencies) {
147
+ const dependencyCache = {};
148
+ const checkSingleDependency = async (depName, depVersionRange) => {
149
+ const cacheKey = `${depName}@${depVersionRange}`;
150
+ if (dependencyCache[cacheKey] !== undefined) {
151
+ return dependencyCache[cacheKey];
152
+ }
240
153
  try {
241
- // 检查主包是否存在
242
- console.log('checking package:', packageName);
243
- const response = yield axios_1.default.get(`https://registry.npmjs.org/${packageName}`, {
154
+ const depResponse = await axios.get(`https://registry.npmjs.org/${depName}`, {
244
155
  timeout: 5000,
245
156
  headers: {
246
157
  'User-Agent': 'MyToolManager/1.0',
247
158
  },
248
159
  });
249
- // 检查主包是否被标记为 unpublished
250
- 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)) {
251
- console.error(`Package marked as unpublished: ${packageName}`);
252
- return false;
253
- }
254
- // 获取主包的最新版本信息
255
- const latestVersion = response.data['dist-tags'].latest;
256
- const versionData = (_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.versions) === null || _d === void 0 ? void 0 : _d[latestVersion];
257
- if (!versionData) {
258
- console.error(`Invalid package: ${packageName} - No version data found`);
160
+ if (depResponse.status !== 200 || !depResponse.data.versions) {
161
+ console.error(`Failed to fetch ${depName}`);
162
+ dependencyCache[cacheKey] = false;
259
163
  return false;
260
164
  }
261
- // 检查 dependencies devDependencies
262
- console.log(`Checking dependencies for ${packageName}`);
263
- const dependencies = Object.assign(Object.assign({}, versionData.dependencies), versionData.devDependencies);
264
- if (!(yield checkDependencies(dependencies))) {
265
- return false;
165
+ const isValid = checkDependencyValidity(depResponse.data, depVersionRange);
166
+ dependencyCache[cacheKey] = isValid;
167
+ if (!isValid) {
168
+ console.error(`Invalid or missing: ${depName}`);
266
169
  }
267
- console.log(`Valid package: ${packageName}`);
268
- return true;
170
+ return isValid;
269
171
  }
270
172
  catch (error) {
271
- console.error(`Error validating package ${packageName}:`, error.message);
173
+ console.error(`Error fetching ${depName}: ${error.message}`);
174
+ dependencyCache[cacheKey] = false;
272
175
  return false;
273
176
  }
274
- });
177
+ };
178
+ const promises = Object.entries(dependencies).map(([depName, depVersionRange]) => checkSingleDependency(depName, depVersionRange));
179
+ const results = await Promise.all(promises);
180
+ return results.every((result) => result);
181
+ }
182
+ // 判断 npm 包及其依赖是否有效
183
+ export async function isValidNpmPackage(packageName) {
184
+ var _a, _b, _c, _d;
185
+ try {
186
+ // 检查主包是否存在
187
+ console.log('checking package:', packageName);
188
+ const response = await axios.get(`https://registry.npmjs.org/${packageName}`, {
189
+ timeout: 5000,
190
+ headers: {
191
+ 'User-Agent': 'MyToolManager/1.0',
192
+ },
193
+ });
194
+ // 检查主包是否被标记为 unpublished
195
+ 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)) {
196
+ console.error(`Package marked as unpublished: ${packageName}`);
197
+ return false;
198
+ }
199
+ // 获取主包的最新版本信息
200
+ const latestVersion = response.data['dist-tags'].latest;
201
+ const versionData = (_d = (_c = response.data) === null || _c === void 0 ? void 0 : _c.versions) === null || _d === void 0 ? void 0 : _d[latestVersion];
202
+ if (!versionData) {
203
+ console.error(`Invalid package: ${packageName} - No version data found`);
204
+ return false;
205
+ }
206
+ // 检查 dependencies 和 devDependencies
207
+ console.log(`Checking dependencies for ${packageName}`);
208
+ const dependencies = Object.assign(Object.assign({}, versionData.dependencies), versionData.devDependencies);
209
+ if (!(await checkDependencies(dependencies))) {
210
+ return false;
211
+ }
212
+ console.log(`Valid package: ${packageName}`);
213
+ return true;
214
+ }
215
+ catch (error) {
216
+ console.error(`Error validating package ${packageName}:`, error.message);
217
+ return false;
218
+ }
275
219
  }
package/dist/schema.d.ts CHANGED
@@ -2,6 +2,22 @@ import { z } from 'zod';
2
2
  export declare const PackageKeySchema: z.ZodString;
3
3
  export declare const HostingBlackListSchema: z.ZodArray<z.ZodString, "many">;
4
4
  export declare const FeaturedListSchema: z.ZodArray<z.ZodString, "many">;
5
+ export declare const ToolExecuteSchema: z.ZodObject<{
6
+ packageName: z.ZodString;
7
+ toolKey: z.ZodString;
8
+ inputData: z.ZodRecord<z.ZodString, z.ZodUnknown>;
9
+ envs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ packageName: string;
12
+ toolKey: string;
13
+ inputData: Record<string, unknown>;
14
+ envs?: Record<string, string> | undefined;
15
+ }, {
16
+ packageName: string;
17
+ toolKey: string;
18
+ inputData: Record<string, unknown>;
19
+ envs?: Record<string, string> | undefined;
20
+ }>;
5
21
  export declare const CategoryConfigSchema: z.ZodObject<{
6
22
  key: z.ZodString;
7
23
  name: z.ZodString;
@@ -42,8 +58,8 @@ export declare const MCPServerPackageConfigSchema: z.ZodObject<{
42
58
  }>>>;
43
59
  }, "strip", z.ZodTypeAny, {
44
60
  type: "mcp-server";
45
- runtime: "node" | "python" | "java" | "go";
46
61
  packageName: string;
62
+ runtime: "node" | "python" | "java" | "go";
47
63
  key?: string | undefined;
48
64
  name?: string | undefined;
49
65
  description?: string | undefined;
@@ -61,8 +77,8 @@ export declare const MCPServerPackageConfigSchema: z.ZodObject<{
61
77
  }> | undefined;
62
78
  }, {
63
79
  type: "mcp-server";
64
- runtime: "node" | "python" | "java" | "go";
65
80
  packageName: string;
81
+ runtime: "node" | "python" | "java" | "go";
66
82
  key?: string | undefined;
67
83
  name?: string | undefined;
68
84
  description?: string | undefined;
@@ -106,8 +122,8 @@ export declare const PackageConfigSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
106
122
  }>>>;
107
123
  }, "strip", z.ZodTypeAny, {
108
124
  type: "mcp-server";
109
- runtime: "node" | "python" | "java" | "go";
110
125
  packageName: string;
126
+ runtime: "node" | "python" | "java" | "go";
111
127
  key?: string | undefined;
112
128
  name?: string | undefined;
113
129
  description?: string | undefined;
@@ -125,8 +141,8 @@ export declare const PackageConfigSchema: z.ZodDiscriminatedUnion<"type", [z.Zod
125
141
  }> | undefined;
126
142
  }, {
127
143
  type: "mcp-server";
128
- runtime: "node" | "python" | "java" | "go";
129
144
  packageName: string;
145
+ runtime: "node" | "python" | "java" | "go";
130
146
  key?: string | undefined;
131
147
  name?: string | undefined;
132
148
  description?: string | undefined;
package/dist/schema.js CHANGED
@@ -1,52 +1,55 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PackagesListSchema = exports.PackageConfigSchema = exports.MCPServerPackageConfigSchema = exports.CategoryConfigSchema = exports.FeaturedListSchema = exports.HostingBlackListSchema = exports.PackageKeySchema = void 0;
4
- const zod_1 = require("zod");
5
- exports.PackageKeySchema = zod_1.z.string();
6
- exports.HostingBlackListSchema = zod_1.z.array(exports.PackageKeySchema);
7
- exports.FeaturedListSchema = zod_1.z.array(exports.PackageKeySchema);
8
- exports.CategoryConfigSchema = zod_1.z.object({
9
- key: zod_1.z.string(),
10
- name: zod_1.z.string(),
11
- description: zod_1.z.string().optional(),
1
+ import { z } from 'zod';
2
+ export const PackageKeySchema = z.string();
3
+ export const HostingBlackListSchema = z.array(PackageKeySchema);
4
+ export const FeaturedListSchema = z.array(PackageKeySchema);
5
+ export const ToolExecuteSchema = z.object({
6
+ packageName: z.string(),
7
+ toolKey: z.string(),
8
+ inputData: z.record(z.unknown()),
9
+ envs: z.record(z.string()).optional(),
12
10
  });
13
- exports.MCPServerPackageConfigSchema = zod_1.z.object({
14
- type: zod_1.z.literal('mcp-server'),
15
- runtime: zod_1.z.enum(['node', 'python', 'java', 'go']),
16
- packageName: zod_1.z.string().describe('Name of the node, python, java package '),
17
- packageVersion: zod_1.z.string().optional().describe('Version of the package, if not provided then it will use latest version'),
18
- bin: zod_1.z.string().optional().describe('Binary Command to run the MCP server, if not provided then it will use the package name'),
19
- binArgs: zod_1.z.array(zod_1.z.string()).optional().describe('Binary Arguments to pass to the command, if not provided then it will use an empty array'),
11
+ export const CategoryConfigSchema = z.object({
12
+ key: z.string(),
13
+ name: z.string(),
14
+ description: z.string().optional(),
15
+ });
16
+ export const MCPServerPackageConfigSchema = z.object({
17
+ type: z.literal('mcp-server'),
18
+ runtime: z.enum(['node', 'python', 'java', 'go']),
19
+ packageName: z.string().describe('Name of the node, python, java package '),
20
+ packageVersion: z.string().optional().describe('Version of the package, if not provided then it will use latest version'),
21
+ bin: z.string().optional().describe('Binary Command to run the MCP server, if not provided then it will use the package name'),
22
+ binArgs: z.array(z.string()).optional().describe('Binary Arguments to pass to the command, if not provided then it will use an empty array'),
20
23
  // if no custom key then would use name
21
- key: zod_1.z.string().optional().describe('Unique key for url and slug'),
22
- name: zod_1.z.string().optional().describe('Custom name for display, if empty then it will use the package name'),
23
- description: zod_1.z.string().optional(),
24
- readme: zod_1.z.string().optional().describe('URL to the README file, if not provided then it will use the package URL'),
25
- url: zod_1.z.string().optional(),
26
- license: zod_1.z.string().optional().describe('Open source license lie MIT, AGPL, GPL, etc'),
27
- logo: zod_1.z.string().optional().describe('URL to custom logo image, if undefined and the URL is Github, then it will use the Github logo'),
28
- author: zod_1.z.string().optional().describe('Author name of the ToolSDK.ai\'s developer ID'),
29
- env: zod_1.z
30
- .record(zod_1.z.object({
31
- description: zod_1.z.string(),
32
- required: zod_1.z.boolean(),
24
+ key: z.string().optional().describe('Unique key for url and slug'),
25
+ name: z.string().optional().describe('Custom name for display, if empty then it will use the package name'),
26
+ description: z.string().optional(),
27
+ readme: z.string().optional().describe('URL to the README file, if not provided then it will use the package URL'),
28
+ url: z.string().optional(),
29
+ license: z.string().optional().describe('Open source license lie MIT, AGPL, GPL, etc'),
30
+ logo: z.string().optional().describe('URL to custom logo image, if undefined and the URL is Github, then it will use the Github logo'),
31
+ author: z.string().optional().describe('Author name of the ToolSDK.ai\'s developer ID'),
32
+ env: z
33
+ .record(z.object({
34
+ description: z.string(),
35
+ required: z.boolean(),
33
36
  }))
34
37
  .optional(),
35
38
  });
36
- exports.PackageConfigSchema = zod_1.z.discriminatedUnion('type', [
37
- exports.MCPServerPackageConfigSchema,
38
- zod_1.z.object({
39
- type: zod_1.z.literal('toolapp'),
40
- packageName: zod_1.z.string(),
41
- url: zod_1.z.string().optional(),
39
+ export const PackageConfigSchema = z.discriminatedUnion('type', [
40
+ MCPServerPackageConfigSchema,
41
+ z.object({
42
+ type: z.literal('toolapp'),
43
+ packageName: z.string(),
44
+ url: z.string().optional(),
42
45
  }),
43
46
  ]);
44
- exports.PackagesListSchema = zod_1.z.record(zod_1.z.object({
45
- category: zod_1.z.string().optional(),
46
- path: zod_1.z.string(),
47
- validated: zod_1.z.boolean().optional(),
48
- tools: zod_1.z.record(zod_1.z.object({
49
- name: zod_1.z.string().optional(),
50
- description: zod_1.z.string().optional(),
47
+ export const PackagesListSchema = z.record(z.object({
48
+ category: z.string().optional(),
49
+ path: z.string(),
50
+ validated: z.boolean().optional(),
51
+ tools: z.record(z.object({
52
+ name: z.string().optional(),
53
+ description: z.string().optional(),
51
54
  })).optional(),
52
55
  }));
package/dist/types.d.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  import { z } from 'zod';
2
- import type { CategoryConfigSchema, PackageConfigSchema, MCPServerPackageConfigSchema, PackagesListSchema } from './schema';
2
+ import type { CategoryConfigSchema, PackageConfigSchema, MCPServerPackageConfigSchema, PackagesListSchema, ToolExecuteSchema } from './schema';
3
3
  export type MCPServerPackageConfig = z.infer<typeof MCPServerPackageConfigSchema>;
4
4
  export type PackageConfig = z.infer<typeof PackageConfigSchema>;
5
5
  export type CategoryConfig = z.infer<typeof CategoryConfigSchema>;
6
6
  export type PackagesList = z.infer<typeof PackagesListSchema>;
7
+ export type ToolExecute = z.infer<typeof ToolExecuteSchema>;
8
+ export interface Response<T> {
9
+ success: boolean;
10
+ code: number;
11
+ message: string;
12
+ data?: T;
13
+ }
package/dist/types.js CHANGED
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolsdk.ai/registry",
3
- "version": "1.0.92",
3
+ "version": "1.0.94",
4
4
  "description": "An Open, Structured, and Standard Registry for MCP Servers and Packages.",
5
5
  "exports": {
6
6
  "./config/*": "./config/*",
@@ -21,16 +21,19 @@
21
21
  "scripts": {
22
22
  "build": "tsc",
23
23
  "lint": "eslint . --ext .ts,.tsx --ignore-pattern \"api/\"",
24
- "server": "node api/cli-generator.js"
24
+ "dev": "tsx watch src/api/index.ts",
25
+ "start": "NODE_ENV=production tsx src/api/index.ts"
25
26
  },
26
27
  "keywords": [],
27
28
  "author": "",
28
29
  "license": "MIT",
29
30
  "dependencies": {
30
31
  "@modelcontextprotocol/sdk": "^1.12.0",
32
+ "@hono/node-server": "1.15.0",
31
33
  "lodash": "^4.17.21",
32
34
  "zod": "^3.23.30",
33
35
  "axios": "^1.9.0",
36
+ "hono": "4.8.3",
34
37
  "semver": "^7.5.4",
35
38
  "@toolsdk.ai/aws-ses-mcp": "1.0.1",
36
39
  "@toolsdk.ai/mcp-send-email": "1.0.0",
@@ -156,7 +159,7 @@
156
159
  "qasphere-mcp": "0.2.1",
157
160
  "mcp-developer-name": "1.0.2",
158
161
  "@nextdrive/github-action-trigger-mcp": "0.1.2",
159
- "@ahdev/dokploy-mcp": "1.3.4",
162
+ "@ahdev/dokploy-mcp": "1.4.0",
160
163
  "@jsonresume/mcp": "3.0.3",
161
164
  "@growthbook/mcp": "0.1.1",
162
165
  "deepsource-mcp-server": "1.2.1",
@@ -223,7 +226,7 @@
223
226
  "hermes-search-mcp": "1.0.1",
224
227
  "agentql-mcp": "1.0.0",
225
228
  "pickapicon-mcp": "1.0.3",
226
- "@adenot/mcp-google-search": "0.2.0",
229
+ "@adenot/mcp-google-search": "0.2.1",
227
230
  "octagon-deep-research-mcp": "1.0.18",
228
231
  "@humansean/mcp-bocha": "1.0.1",
229
232
  "@cyanheads/pubmed-mcp-server": "1.2.3",
@@ -482,7 +485,7 @@
482
485
  "mcp-lighthouse": "0.1.4",
483
486
  "bitcoin-mcp": "0.0.6",
484
487
  "@mcpfun/mcp-server-ccxt": "1.2.1",
485
- "@agentek/mcp-server": "0.1.20",
488
+ "@agentek/mcp-server": "0.1.22",
486
489
  "binance-mcp-server": "1.1.0",
487
490
  "coincap-mcp": "0.9.3",
488
491
  "@mcp-dockmaster/mcp-cryptowallet-evm": "1.0.6",
@@ -555,7 +558,7 @@
555
558
  "mcp-nmap-server": "1.0.1",
556
559
  "mcp-cisco-support": "1.9.8",
557
560
  "@winterjung/mcp-korean-spell": "1.0.1",
558
- "12306-mcp": "0.3.3",
561
+ "12306-mcp": "0.3.4",
559
562
  "@openbnb/mcp-server-airbnb": "0.1.1",
560
563
  "mcp-server-diff-typescript": "1.0.5",
561
564
  "git-commands-mcp": "0.1.4",
@@ -624,10 +627,13 @@
624
627
  "@types/lodash": "^4.17.17",
625
628
  "@types/node": "^22.15.21",
626
629
  "@types/semver": "^7.5.8",
630
+ "dotenv": "^17.2.1",
627
631
  "eslint": "^9.27.0",
628
632
  "eslint-plugin-react": "^7.37.5",
629
633
  "globals": "^16.2.0",
634
+ "tsx": "^4.20.3",
630
635
  "typescript": "^5.8.3",
631
- "typescript-eslint": "^8.33.0"
636
+ "typescript-eslint": "^8.33.0",
637
+ "vitest": "^3.2.4"
632
638
  }
633
639
  }