@loop_ouroboros/mcp-hub-lite 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -0
- package/README.md +74 -116
- package/dist/client/assets/{HomeView-Bu2joUvW.js → HomeView-BBwvy1oj.js} +1 -1
- package/dist/client/assets/{ResourceDetailView-BvrhDCD1.js → ResourceDetailView-CZ2aB73w.js} +1 -1
- package/dist/client/assets/{ResourcesView-LjqioF_s.js → ResourcesView-CN1NlhWs.js} +1 -1
- package/dist/client/assets/{ServerDashboard-FhHJFvUi.js → ServerDashboard-k652Vw4Z.js} +1 -1
- package/dist/client/assets/{ServerDetail-BKV-M4qT.js → ServerDetail-BLQ-a4cO.js} +1 -1
- package/dist/client/assets/{ServerListView-BXgtDyt3.js → ServerListView-BHrsFD5i.js} +4 -4
- package/dist/client/assets/{ServerStatusTags.vue_vue_type_script_setup_true_lang-D-ooYNdN.js → ServerStatusTags.vue_vue_type_script_setup_true_lang-BHhwEuGe.js} +1 -1
- package/dist/client/assets/{SettingsView-CMFG91Z4.js → SettingsView-CUOFNXrz.js} +1 -1
- package/dist/client/assets/{ToolCallDialog-Bf4Xe4gH.js → ToolCallDialog-BfPjLxfV.js} +1 -1
- package/dist/client/assets/ToolsView-BxgXvPC3.css +1 -0
- package/dist/client/assets/ToolsView-CyuhYAE2.js +1 -0
- package/dist/client/assets/{_baseClone-Bp9Rjwd7.js → _baseClone-DO5qfalW.js} +1 -1
- package/dist/client/assets/{el-form-item-DdSUWYsl.js → el-form-item-CcGsD2K_.js} +2 -2
- package/dist/client/assets/{el-input-99gMrutP.js → el-input-tYgeiaCT.js} +1 -1
- package/dist/client/assets/{el-loading-CIQ5pD5u.js → el-loading-Dwl9E_Vr.js} +1 -1
- package/dist/client/assets/{el-overlay-BVM6msGX.js → el-overlay-kqX_BABo.js} +1 -1
- package/dist/client/assets/{el-radio-group-DhXWy7ry.js → el-radio-group-D8aWBVOT.js} +1 -1
- package/dist/client/assets/el-skeleton-item-BRwIFspE.js +1 -0
- package/dist/client/assets/{el-switch-Bu8AQ5uM.js → el-switch-BF8c-xeU.js} +1 -1
- package/dist/client/assets/{el-tab-pane-BnGMaV56.js → el-tab-pane-C4Ep94cd.js} +1 -1
- package/dist/client/assets/{el-table-column-BMWOaLS_.js → el-table-column-Cog6uCh-.js} +1 -1
- package/dist/client/assets/{index-C2V-ZGji.js → index-ByNBhPAR.js} +1 -1
- package/dist/client/assets/index-CTB6oe-9.js +2 -0
- package/dist/client/assets/omit-CUnDT6sS.js +1 -0
- package/dist/client/assets/{raf-C2wXzaVU.js → raf-CmzeRPMd.js} +1 -1
- package/dist/client/assets/{vue-vendor-BLHLXXJK.js → vue-vendor-CbgVSHIh.js} +3 -3
- package/dist/client/index.html +2 -2
- package/dist/server/src/api/mcp/debug-response-wrapper.js +2 -2
- package/dist/server/src/api/mcp/gateway.d.ts.map +1 -1
- package/dist/server/src/api/mcp/gateway.js +17 -3
- package/dist/server/src/api/mcp/session-context-extractor.d.ts.map +1 -1
- package/dist/server/src/api/mcp/session-context-extractor.js +14 -5
- package/dist/server/src/cli/commands/mcp-tool-use.d.ts +62 -0
- package/dist/server/src/cli/commands/mcp-tool-use.d.ts.map +1 -0
- package/dist/server/src/cli/commands/mcp-tool-use.js +174 -0
- package/dist/server/src/cli/commands/server.d.ts +57 -0
- package/dist/server/src/cli/commands/server.d.ts.map +1 -0
- package/dist/server/src/cli/commands/server.js +169 -0
- package/dist/server/src/cli/commands/tool-use.d.ts +95 -0
- package/dist/server/src/cli/commands/tool-use.d.ts.map +1 -0
- package/dist/server/src/cli/commands/tool-use.js +255 -0
- package/dist/server/src/cli/index.d.ts +4 -2
- package/dist/server/src/cli/index.d.ts.map +1 -1
- package/dist/server/src/cli/index.js +35 -3
- package/dist/server/src/config/config-loader.js +1 -1
- package/dist/server/src/config/config-manager.js +1 -1
- package/dist/server/src/models/system-tools.constants.d.ts +2 -2
- package/dist/server/src/models/system-tools.constants.d.ts.map +1 -1
- package/dist/server/src/models/system-tools.constants.js +2 -2
- package/dist/server/src/services/connection/tool-cache.d.ts.map +1 -1
- package/dist/server/src/services/connection/tool-cache.js +3 -1
- package/dist/server/src/services/gateway/gateway.service.d.ts.map +1 -1
- package/dist/server/src/services/gateway/gateway.service.js +38 -4
- package/dist/server/src/services/gateway/global-transport.d.ts +14 -5
- package/dist/server/src/services/gateway/global-transport.d.ts.map +1 -1
- package/dist/server/src/services/gateway/global-transport.js +54 -30
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.js +12 -1
- package/dist/server/src/services/gateway/request-handlers/system-tools-handler.js +2 -2
- package/dist/server/src/services/gateway/request-handlers/tools-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/tools-handler.js +3 -4
- package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts +1 -0
- package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts.map +1 -1
- package/dist/server/src/services/hub-tools/system-tool-definitions.js +4 -3
- package/dist/server/src/services/hub-tools.service.d.ts +3 -2
- package/dist/server/src/services/hub-tools.service.d.ts.map +1 -1
- package/dist/server/src/services/hub-tools.service.js +36 -19
- package/dist/server/src/services/search/search-core.service.d.ts +5 -5
- package/dist/server/src/services/search/search-core.service.js +11 -11
- package/dist/server/src/services/session/session-manager.d.ts +256 -12
- package/dist/server/src/services/session/session-manager.d.ts.map +1 -1
- package/dist/server/src/services/session/session-manager.js +585 -23
- package/dist/server/src/services/session-tracker.service.d.ts +10 -2
- package/dist/server/src/services/session-tracker.service.d.ts.map +1 -1
- package/dist/server/src/services/session-tracker.service.js +53 -2
- package/dist/server/src/services/system-tool-handler.js +2 -2
- package/dist/server/src/utils/index.d.ts +1 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/src/utils/index.js +1 -0
- package/dist/server/src/utils/name-converter.d.ts +17 -0
- package/dist/server/src/utils/name-converter.d.ts.map +1 -0
- package/dist/server/src/utils/name-converter.js +27 -0
- package/dist/server/src/utils/request-context.d.ts +18 -0
- package/dist/server/src/utils/request-context.d.ts.map +1 -1
- package/dist/server/src/utils/request-context.js +20 -0
- package/dist/server/tests/evaluation/evaluation.test.js +9 -10
- package/dist/server/tests/integration/api/gateway.test.js +2 -2
- package/dist/server/tests/unit/services/hub-tools.service.test.js +1 -1
- package/dist/server/tests/unit/utils/name-converter.test.d.ts +2 -0
- package/dist/server/tests/unit/utils/name-converter.test.d.ts.map +1 -0
- package/dist/server/tests/unit/utils/name-converter.test.js +69 -0
- package/dist/server/tests/unit/utils/request-context.test.js +24 -5
- package/package.json +3 -1
- package/dist/client/assets/ToolsView-DFpha1z0.js +0 -1
- package/dist/client/assets/ToolsView-E3Ps9c7i.css +0 -1
- package/dist/client/assets/el-skeleton-item-DJz-Us12.js +0 -1
- package/dist/client/assets/index-vhkqgpmN.js +0 -2
- package/dist/client/assets/omit-CqPQN3XP.js +0 -1
package/dist/client/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" href="/favicon.ico" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>MCP Server Manager</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CTB6oe-9.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-CbgVSHIh.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-DpH6ZSbs.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -269,10 +269,10 @@ export function wrapReplyForDebug(reply, sessionId) {
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
if (headers) {
|
|
272
|
-
logger.debug(`
|
|
272
|
+
logger.debug(`Full error response context - statusCode: ${statusCode}, statusMessage: ${statusMessage || 'none'}, headers: ${stringifyForLogging(headers)}`, LOG_MODULES.COMMUNICATION);
|
|
273
273
|
}
|
|
274
274
|
else {
|
|
275
|
-
logger.debug(`
|
|
275
|
+
logger.debug(`Full error response context - statusCode: ${statusCode}, statusMessage: ${statusMessage || 'none'}`, LOG_MODULES.COMMUNICATION);
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/gateway.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAM7E;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/gateway.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAM7E;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,iBAqH9D"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { logger, LOG_MODULES } from '../../utils/logger/index.js';
|
|
6
6
|
import { stringifyForLogging, getMcpCommDebugSetting } from '../../utils/json-utils.js';
|
|
7
7
|
import { wrapReplyForDebug } from './debug-response-wrapper.js';
|
|
8
|
-
import {
|
|
8
|
+
import { createSessionTransport } from '../../services/gateway/global-transport.js';
|
|
9
9
|
/**
|
|
10
10
|
* MCP Gateway routes registration.
|
|
11
11
|
*
|
|
@@ -44,11 +44,25 @@ export async function mcpGatewayRoutes(fastify) {
|
|
|
44
44
|
wrapReplyForDebug(reply, '');
|
|
45
45
|
reply.hijack();
|
|
46
46
|
try {
|
|
47
|
-
|
|
47
|
+
logger.debug(`About to create session transport for MCP request`, LOG_MODULES.GATEWAY);
|
|
48
|
+
const { transport, server } = await createSessionTransport();
|
|
49
|
+
logger.debug(`Created session transport successfully, handling MCP request`, LOG_MODULES.GATEWAY);
|
|
50
|
+
try {
|
|
51
|
+
await transport.handleRequest(request.raw, reply.raw, request.body);
|
|
52
|
+
logger.debug(`Successfully handled MCP request with server: ${server.constructor.name}`, LOG_MODULES.GATEWAY);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
// Resources will be automatically cleaned up by garbage collection
|
|
56
|
+
// since transport and server are local to this request scope
|
|
57
|
+
logger.debug(`Session transport request completed, resources will be GC'd`, LOG_MODULES.GATEWAY);
|
|
58
|
+
}
|
|
48
59
|
}
|
|
49
60
|
catch (error) {
|
|
50
61
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
51
|
-
|
|
62
|
+
const errorStack = error instanceof Error ? error.stack : 'No stack available';
|
|
63
|
+
logger.error(`Error handling MCP request: ${errorMessage}`, LOG_MODULES.GATEWAY);
|
|
64
|
+
logger.error(`Full error stack: ${errorStack}`, LOG_MODULES.GATEWAY);
|
|
65
|
+
logger.error(`Request body that caused error: ${JSON.stringify(request.body)}`, LOG_MODULES.GATEWAY);
|
|
52
66
|
if (!reply.raw.headersSent) {
|
|
53
67
|
reply.raw.writeHead(500, { 'Content-Type': 'application/json' });
|
|
54
68
|
reply.raw.end(JSON.stringify({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-context-extractor.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/session-context-extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAI7E,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE;YACX,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC;IAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAC,GAAG;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;CAChC,
|
|
1
|
+
{"version":3,"file":"session-context-extractor.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/session-context-extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAI7E,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE;YACX,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC;IAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAC,GAAG;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;CAChC,CAsGA"}
|
|
@@ -49,14 +49,14 @@ export function extractSessionContext(request) {
|
|
|
49
49
|
logger.debug(`Extracted sessionId from URL: ${sessionId}`, LOG_MODULES.CONTEXT);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
// If sessionId was extracted, check if it exists in
|
|
52
|
+
// If sessionId was extracted, check if it exists in persisted sessions (for debugging)
|
|
53
53
|
if (sessionId) {
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
logger.debug(`Session ${sessionId} found in
|
|
54
|
+
const persistedSession = mcpSessionManager.getSessionState(sessionId);
|
|
55
|
+
if (persistedSession) {
|
|
56
|
+
logger.debug(`Session ${sessionId} found in persisted sessions`, LOG_MODULES.CONTEXT);
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
logger.debug(`Session ${sessionId} not found in
|
|
59
|
+
logger.debug(`Session ${sessionId} not found in persisted sessions (will create new)`, LOG_MODULES.CONTEXT);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
// Extract client info from headers and request body
|
|
@@ -90,11 +90,20 @@ export function extractSessionContext(request) {
|
|
|
90
90
|
logger.debug(`Generated new sessionId: ${sessionId}`, LOG_MODULES.CONTEXT);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
+
// Add consistency check before returning session information
|
|
94
|
+
if (sessionId && mcpSessionManager.getSessionState(sessionId)) {
|
|
95
|
+
const hasSessionObject = mcpSessionManager.hasSession(sessionId);
|
|
96
|
+
if (!hasSessionObject) {
|
|
97
|
+
logger.warn(`Session state exists but session object missing for ${sessionId}`, LOG_MODULES.CONTEXT);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
93
100
|
const sessionContext = {
|
|
94
101
|
sessionId,
|
|
95
102
|
clientName,
|
|
96
103
|
clientVersion,
|
|
97
104
|
protocolVersion,
|
|
105
|
+
cwd: undefined, // Will be populated from roots/list response later
|
|
106
|
+
project: undefined, // Will be populated from roots/list response later
|
|
98
107
|
ip: request.ip,
|
|
99
108
|
userAgent: headers['user-agent'],
|
|
100
109
|
timestamp: Date.now()
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* CLI command for dynamic MCP server tool operations via API.
|
|
4
|
+
*
|
|
5
|
+
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
6
|
+
* supporting four actions: list-servers, list-tools, get-tool, and call-tool. It wraps
|
|
7
|
+
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
8
|
+
*
|
|
9
|
+
* ## Command Format
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* mcp-tool-use <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Or via npm:
|
|
16
|
+
* ```
|
|
17
|
+
* npm run tool-use <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* ## Supported Actions
|
|
21
|
+
*
|
|
22
|
+
* - `list-servers` - List all connected MCP servers
|
|
23
|
+
* - `list-tools` - List all tools from the specified server
|
|
24
|
+
* - `get-tool <toolName>` - Get complete schema for a specific tool
|
|
25
|
+
* - `call-tool <toolName>` - Call a tool on the specified server
|
|
26
|
+
*
|
|
27
|
+
* ## Options
|
|
28
|
+
*
|
|
29
|
+
* - `--args <json>` - JSON string of tool arguments (for call-tool action)
|
|
30
|
+
* - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
|
|
31
|
+
*
|
|
32
|
+
* ## Usage Examples
|
|
33
|
+
*
|
|
34
|
+
* ```bash
|
|
35
|
+
* # List all connected servers
|
|
36
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite list-servers
|
|
37
|
+
*
|
|
38
|
+
* # List all tools from a specific server
|
|
39
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite list-tools
|
|
40
|
+
*
|
|
41
|
+
* # Get tool schema
|
|
42
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite get-tool list_tools
|
|
43
|
+
*
|
|
44
|
+
* # Call a tool with arguments
|
|
45
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite call-tool list_tools --args '{"serverName":"mcp-hub-lite"}'
|
|
46
|
+
*
|
|
47
|
+
* # Call a tool with tags for multi-instance selection
|
|
48
|
+
* mcp-hub-lite mcp-tool-use baidu-search call-tool search --args '{"query":"天气"}' --tags '{"env":"prod"}'
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* ## Error Handling
|
|
52
|
+
*
|
|
53
|
+
* - Exits with code 1 if the server is not running
|
|
54
|
+
* - Exits with code 1 if action is unknown
|
|
55
|
+
* - Exits with code 1 if toolName is required but not provided
|
|
56
|
+
* - Exits with code 1 if JSON parsing fails for --args or --tags
|
|
57
|
+
* - Exits with code 1 if the underlying API call fails
|
|
58
|
+
*
|
|
59
|
+
* @returns {Command} The configured mcp-tool-use command instance for registration with Commander.js
|
|
60
|
+
*/
|
|
61
|
+
export declare const mcpToolUseCommand: Command;
|
|
62
|
+
//# sourceMappingURL=mcp-tool-use.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tool-use.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/mcp-tool-use.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,eAAO,MAAM,iBAAiB,SAkI1B,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getServerStatus } from '../server.js';
|
|
3
|
+
/**
|
|
4
|
+
* CLI command for dynamic MCP server tool operations via API.
|
|
5
|
+
*
|
|
6
|
+
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
7
|
+
* supporting four actions: list-servers, list-tools, get-tool, and call-tool. It wraps
|
|
8
|
+
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
9
|
+
*
|
|
10
|
+
* ## Command Format
|
|
11
|
+
*
|
|
12
|
+
* ```
|
|
13
|
+
* mcp-tool-use <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Or via npm:
|
|
17
|
+
* ```
|
|
18
|
+
* npm run tool-use <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ## Supported Actions
|
|
22
|
+
*
|
|
23
|
+
* - `list-servers` - List all connected MCP servers
|
|
24
|
+
* - `list-tools` - List all tools from the specified server
|
|
25
|
+
* - `get-tool <toolName>` - Get complete schema for a specific tool
|
|
26
|
+
* - `call-tool <toolName>` - Call a tool on the specified server
|
|
27
|
+
*
|
|
28
|
+
* ## Options
|
|
29
|
+
*
|
|
30
|
+
* - `--args <json>` - JSON string of tool arguments (for call-tool action)
|
|
31
|
+
* - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
|
|
32
|
+
*
|
|
33
|
+
* ## Usage Examples
|
|
34
|
+
*
|
|
35
|
+
* ```bash
|
|
36
|
+
* # List all connected servers
|
|
37
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite list-servers
|
|
38
|
+
*
|
|
39
|
+
* # List all tools from a specific server
|
|
40
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite list-tools
|
|
41
|
+
*
|
|
42
|
+
* # Get tool schema
|
|
43
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite get-tool list_tools
|
|
44
|
+
*
|
|
45
|
+
* # Call a tool with arguments
|
|
46
|
+
* mcp-hub-lite mcp-tool-use mcp-hub-lite call-tool list_tools --args '{"serverName":"mcp-hub-lite"}'
|
|
47
|
+
*
|
|
48
|
+
* # Call a tool with tags for multi-instance selection
|
|
49
|
+
* mcp-hub-lite mcp-tool-use baidu-search call-tool search --args '{"query":"天气"}' --tags '{"env":"prod"}'
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* ## Error Handling
|
|
53
|
+
*
|
|
54
|
+
* - Exits with code 1 if the server is not running
|
|
55
|
+
* - Exits with code 1 if action is unknown
|
|
56
|
+
* - Exits with code 1 if toolName is required but not provided
|
|
57
|
+
* - Exits with code 1 if JSON parsing fails for --args or --tags
|
|
58
|
+
* - Exits with code 1 if the underlying API call fails
|
|
59
|
+
*
|
|
60
|
+
* @returns {Command} The configured mcp-tool-use command instance for registration with Commander.js
|
|
61
|
+
*/
|
|
62
|
+
export const mcpToolUseCommand = new Command('tool-use')
|
|
63
|
+
.description('Manage MCP server tools via API (list-servers, list-tools, get-tool, call-tool)')
|
|
64
|
+
.argument('<serverName>', 'Server name to target (use "mcp-hub-lite" for system tools)')
|
|
65
|
+
.argument('<action>', 'Action: list-servers, list-tools, get-tool, call-tool')
|
|
66
|
+
.argument('[toolName]', 'Tool name (required for get-tool and call-tool actions)')
|
|
67
|
+
.option('--args <json>', 'JSON string of tool arguments (call-tool only)')
|
|
68
|
+
.option('--tags <json>', 'JSON object of instance selection tags (call-tool only, for multi-instance servers)')
|
|
69
|
+
.action(async (serverName, action, toolName, options) => {
|
|
70
|
+
try {
|
|
71
|
+
// Check if server is running and get connection info
|
|
72
|
+
const status = await getServerStatus();
|
|
73
|
+
if (!status.running) {
|
|
74
|
+
console.error('Error: MCP Hub Lite server is not running.');
|
|
75
|
+
console.error('Start the server with: mcp-hub-lite start');
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const baseUrl = `http://${status.host}:${status.port}`;
|
|
79
|
+
switch (action) {
|
|
80
|
+
case 'list-servers': {
|
|
81
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers`, {
|
|
82
|
+
headers: { Accept: 'application/json' }
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
throw new Error(`API error: ${response.status} ${response.statusText}`);
|
|
86
|
+
}
|
|
87
|
+
const result = await response.json();
|
|
88
|
+
console.log(JSON.stringify(result, null, 2));
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'list-tools': {
|
|
92
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
93
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools${tagsParam}`, {
|
|
94
|
+
headers: { Accept: 'application/json' }
|
|
95
|
+
});
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
98
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
99
|
+
}
|
|
100
|
+
const result = await response.json();
|
|
101
|
+
console.log(JSON.stringify(result, null, 2));
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case 'get-tool': {
|
|
105
|
+
if (!toolName) {
|
|
106
|
+
console.error('Error: toolName is required for get-tool action');
|
|
107
|
+
process.exit(1);
|
|
108
|
+
}
|
|
109
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
110
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools/${toolName}${tagsParam}`, { headers: { Accept: 'application/json' } });
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
113
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
114
|
+
}
|
|
115
|
+
const result = await response.json();
|
|
116
|
+
console.log(JSON.stringify(result, null, 2));
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case 'call-tool': {
|
|
120
|
+
if (!toolName) {
|
|
121
|
+
console.error('Error: toolName is required for call-tool action');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
// Parse tool arguments
|
|
125
|
+
let toolArgs = {};
|
|
126
|
+
if (options.args) {
|
|
127
|
+
try {
|
|
128
|
+
toolArgs = JSON.parse(options.args);
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
console.error('Error: Invalid JSON in --args option');
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Parse tags for instance selection (call-tool only)
|
|
136
|
+
let requestOptions;
|
|
137
|
+
if (options.tags) {
|
|
138
|
+
try {
|
|
139
|
+
requestOptions = { tags: JSON.parse(options.tags) };
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
console.error('Error: Invalid JSON in --tags option');
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools/${toolName}/call`, {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
headers: {
|
|
149
|
+
'Content-Type': 'application/json',
|
|
150
|
+
Accept: 'application/json'
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify({ toolArgs, requestOptions })
|
|
153
|
+
});
|
|
154
|
+
if (!response.ok) {
|
|
155
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
156
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
157
|
+
}
|
|
158
|
+
const result = await response.json();
|
|
159
|
+
console.log(JSON.stringify(result, null, 2));
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
default: {
|
|
163
|
+
console.error(`Unknown action: ${action}`);
|
|
164
|
+
console.error('Valid actions: list-servers, list-tools, get-tool, call-tool');
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* CLI command for dynamic MCP server tool operations via API.
|
|
4
|
+
*
|
|
5
|
+
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
6
|
+
* supporting four actions: list-servers, list-tools, get-tool, and call-tool. It wraps
|
|
7
|
+
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
8
|
+
*
|
|
9
|
+
* ## Command Format
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* npm run server <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* ## Supported Actions
|
|
16
|
+
*
|
|
17
|
+
* - `list-servers` - List all connected MCP servers
|
|
18
|
+
* - `list-tools` - List all tools from the specified server
|
|
19
|
+
* - `get-tool <toolName>` - Get complete schema for a specific tool
|
|
20
|
+
* - `call-tool <toolName>` - Call a tool on the specified server
|
|
21
|
+
*
|
|
22
|
+
* ## Options
|
|
23
|
+
*
|
|
24
|
+
* - `--args <json>` - JSON string of tool arguments (for call-tool action)
|
|
25
|
+
* - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
|
|
26
|
+
*
|
|
27
|
+
* ## Usage Examples
|
|
28
|
+
*
|
|
29
|
+
* ```bash
|
|
30
|
+
* # List all connected servers
|
|
31
|
+
* npm run server mcp-hub-lite list-servers
|
|
32
|
+
*
|
|
33
|
+
* # List all tools from a specific server
|
|
34
|
+
* npm run server mcp-hub-lite list-tools
|
|
35
|
+
*
|
|
36
|
+
* # Get tool schema
|
|
37
|
+
* npm run server mcp-hub-lite get-tool list_tools
|
|
38
|
+
*
|
|
39
|
+
* # Call a tool with arguments
|
|
40
|
+
* npm run server mcp-hub-lite call-tool list_tools --args '{"serverName":"mcp-hub-lite"}'
|
|
41
|
+
*
|
|
42
|
+
* # Call a tool with tags for multi-instance selection
|
|
43
|
+
* npm run server baidu-search call-tool search --args '{"query":"天气"}' --tags '{"env":"prod"}'
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* ## Error Handling
|
|
47
|
+
*
|
|
48
|
+
* - Exits with code 1 if the server is not running
|
|
49
|
+
* - Exits with code 1 if action is unknown
|
|
50
|
+
* - Exits with code 1 if toolName is required but not provided
|
|
51
|
+
* - Exits with code 1 if JSON parsing fails for --args or --tags
|
|
52
|
+
* - Exits with code 1 if the underlying API call fails
|
|
53
|
+
*
|
|
54
|
+
* @returns {Command} The configured server command instance for registration with Commander.js
|
|
55
|
+
*/
|
|
56
|
+
export declare const serverCommand: Command;
|
|
57
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,aAAa,SAkItB,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getServerStatus } from '../server.js';
|
|
3
|
+
/**
|
|
4
|
+
* CLI command for dynamic MCP server tool operations via API.
|
|
5
|
+
*
|
|
6
|
+
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
7
|
+
* supporting four actions: list-servers, list-tools, get-tool, and call-tool. It wraps
|
|
8
|
+
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
9
|
+
*
|
|
10
|
+
* ## Command Format
|
|
11
|
+
*
|
|
12
|
+
* ```
|
|
13
|
+
* npm run server <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* ## Supported Actions
|
|
17
|
+
*
|
|
18
|
+
* - `list-servers` - List all connected MCP servers
|
|
19
|
+
* - `list-tools` - List all tools from the specified server
|
|
20
|
+
* - `get-tool <toolName>` - Get complete schema for a specific tool
|
|
21
|
+
* - `call-tool <toolName>` - Call a tool on the specified server
|
|
22
|
+
*
|
|
23
|
+
* ## Options
|
|
24
|
+
*
|
|
25
|
+
* - `--args <json>` - JSON string of tool arguments (for call-tool action)
|
|
26
|
+
* - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
|
|
27
|
+
*
|
|
28
|
+
* ## Usage Examples
|
|
29
|
+
*
|
|
30
|
+
* ```bash
|
|
31
|
+
* # List all connected servers
|
|
32
|
+
* npm run server mcp-hub-lite list-servers
|
|
33
|
+
*
|
|
34
|
+
* # List all tools from a specific server
|
|
35
|
+
* npm run server mcp-hub-lite list-tools
|
|
36
|
+
*
|
|
37
|
+
* # Get tool schema
|
|
38
|
+
* npm run server mcp-hub-lite get-tool list_tools
|
|
39
|
+
*
|
|
40
|
+
* # Call a tool with arguments
|
|
41
|
+
* npm run server mcp-hub-lite call-tool list_tools --args '{"serverName":"mcp-hub-lite"}'
|
|
42
|
+
*
|
|
43
|
+
* # Call a tool with tags for multi-instance selection
|
|
44
|
+
* npm run server baidu-search call-tool search --args '{"query":"天气"}' --tags '{"env":"prod"}'
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* ## Error Handling
|
|
48
|
+
*
|
|
49
|
+
* - Exits with code 1 if the server is not running
|
|
50
|
+
* - Exits with code 1 if action is unknown
|
|
51
|
+
* - Exits with code 1 if toolName is required but not provided
|
|
52
|
+
* - Exits with code 1 if JSON parsing fails for --args or --tags
|
|
53
|
+
* - Exits with code 1 if the underlying API call fails
|
|
54
|
+
*
|
|
55
|
+
* @returns {Command} The configured server command instance for registration with Commander.js
|
|
56
|
+
*/
|
|
57
|
+
export const serverCommand = new Command('server')
|
|
58
|
+
.description('Manage MCP server tools via API (list-servers, list-tools, get-tool, call-tool)')
|
|
59
|
+
.argument('<serverName>', 'Server name to target (use "mcp-hub-lite" for system tools)')
|
|
60
|
+
.argument('<action>', 'Action: list-servers, list-tools, get-tool, call-tool')
|
|
61
|
+
.argument('[toolName]', 'Tool name (required for get-tool and call-tool actions)')
|
|
62
|
+
.option('--args <json>', 'JSON string of tool arguments (call-tool only)')
|
|
63
|
+
.option('--tags <json>', 'JSON object of instance selection tags (call-tool only, for multi-instance servers)')
|
|
64
|
+
.action(async (serverName, action, toolName, options) => {
|
|
65
|
+
try {
|
|
66
|
+
// Check if server is running and get connection info
|
|
67
|
+
const status = await getServerStatus();
|
|
68
|
+
if (!status.running) {
|
|
69
|
+
console.error('Error: MCP Hub Lite server is not running.');
|
|
70
|
+
console.error('Start the server with: mcp-hub-lite start');
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const baseUrl = `http://${status.host}:${status.port}`;
|
|
74
|
+
switch (action) {
|
|
75
|
+
case 'list-servers': {
|
|
76
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers`, {
|
|
77
|
+
headers: { Accept: 'application/json' }
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(`API error: ${response.status} ${response.statusText}`);
|
|
81
|
+
}
|
|
82
|
+
const result = await response.json();
|
|
83
|
+
console.log(JSON.stringify(result, null, 2));
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'list-tools': {
|
|
87
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
88
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools${tagsParam}`, {
|
|
89
|
+
headers: { Accept: 'application/json' }
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
93
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
94
|
+
}
|
|
95
|
+
const result = await response.json();
|
|
96
|
+
console.log(JSON.stringify(result, null, 2));
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'get-tool': {
|
|
100
|
+
if (!toolName) {
|
|
101
|
+
console.error('Error: toolName is required for get-tool action');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
105
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools/${toolName}${tagsParam}`, { headers: { Accept: 'application/json' } });
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
108
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
109
|
+
}
|
|
110
|
+
const result = await response.json();
|
|
111
|
+
console.log(JSON.stringify(result, null, 2));
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 'call-tool': {
|
|
115
|
+
if (!toolName) {
|
|
116
|
+
console.error('Error: toolName is required for call-tool action');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
// Parse tool arguments
|
|
120
|
+
let toolArgs = {};
|
|
121
|
+
if (options.args) {
|
|
122
|
+
try {
|
|
123
|
+
toolArgs = JSON.parse(options.args);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
console.error('Error: Invalid JSON in --args option');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Parse tags for instance selection (call-tool only)
|
|
131
|
+
let requestOptions;
|
|
132
|
+
if (options.tags) {
|
|
133
|
+
try {
|
|
134
|
+
requestOptions = { tags: JSON.parse(options.tags) };
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
console.error('Error: Invalid JSON in --tags option');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools/${toolName}/call`, {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: {
|
|
144
|
+
'Content-Type': 'application/json',
|
|
145
|
+
Accept: 'application/json'
|
|
146
|
+
},
|
|
147
|
+
body: JSON.stringify({ toolArgs, requestOptions })
|
|
148
|
+
});
|
|
149
|
+
if (!response.ok) {
|
|
150
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
151
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
152
|
+
}
|
|
153
|
+
const result = await response.json();
|
|
154
|
+
console.log(JSON.stringify(result, null, 2));
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
default: {
|
|
158
|
+
console.error(`Unknown action: ${action}`);
|
|
159
|
+
console.error('Valid actions: list-servers, list-tools, get-tool, call-tool');
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
process.exit(0);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
});
|