@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.
Files changed (100) hide show
  1. package/CHANGELOG.md +141 -0
  2. package/README.md +74 -116
  3. package/dist/client/assets/{HomeView-Bu2joUvW.js → HomeView-BBwvy1oj.js} +1 -1
  4. package/dist/client/assets/{ResourceDetailView-BvrhDCD1.js → ResourceDetailView-CZ2aB73w.js} +1 -1
  5. package/dist/client/assets/{ResourcesView-LjqioF_s.js → ResourcesView-CN1NlhWs.js} +1 -1
  6. package/dist/client/assets/{ServerDashboard-FhHJFvUi.js → ServerDashboard-k652Vw4Z.js} +1 -1
  7. package/dist/client/assets/{ServerDetail-BKV-M4qT.js → ServerDetail-BLQ-a4cO.js} +1 -1
  8. package/dist/client/assets/{ServerListView-BXgtDyt3.js → ServerListView-BHrsFD5i.js} +4 -4
  9. 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
  10. package/dist/client/assets/{SettingsView-CMFG91Z4.js → SettingsView-CUOFNXrz.js} +1 -1
  11. package/dist/client/assets/{ToolCallDialog-Bf4Xe4gH.js → ToolCallDialog-BfPjLxfV.js} +1 -1
  12. package/dist/client/assets/ToolsView-BxgXvPC3.css +1 -0
  13. package/dist/client/assets/ToolsView-CyuhYAE2.js +1 -0
  14. package/dist/client/assets/{_baseClone-Bp9Rjwd7.js → _baseClone-DO5qfalW.js} +1 -1
  15. package/dist/client/assets/{el-form-item-DdSUWYsl.js → el-form-item-CcGsD2K_.js} +2 -2
  16. package/dist/client/assets/{el-input-99gMrutP.js → el-input-tYgeiaCT.js} +1 -1
  17. package/dist/client/assets/{el-loading-CIQ5pD5u.js → el-loading-Dwl9E_Vr.js} +1 -1
  18. package/dist/client/assets/{el-overlay-BVM6msGX.js → el-overlay-kqX_BABo.js} +1 -1
  19. package/dist/client/assets/{el-radio-group-DhXWy7ry.js → el-radio-group-D8aWBVOT.js} +1 -1
  20. package/dist/client/assets/el-skeleton-item-BRwIFspE.js +1 -0
  21. package/dist/client/assets/{el-switch-Bu8AQ5uM.js → el-switch-BF8c-xeU.js} +1 -1
  22. package/dist/client/assets/{el-tab-pane-BnGMaV56.js → el-tab-pane-C4Ep94cd.js} +1 -1
  23. package/dist/client/assets/{el-table-column-BMWOaLS_.js → el-table-column-Cog6uCh-.js} +1 -1
  24. package/dist/client/assets/{index-C2V-ZGji.js → index-ByNBhPAR.js} +1 -1
  25. package/dist/client/assets/index-CTB6oe-9.js +2 -0
  26. package/dist/client/assets/omit-CUnDT6sS.js +1 -0
  27. package/dist/client/assets/{raf-C2wXzaVU.js → raf-CmzeRPMd.js} +1 -1
  28. package/dist/client/assets/{vue-vendor-BLHLXXJK.js → vue-vendor-CbgVSHIh.js} +3 -3
  29. package/dist/client/index.html +2 -2
  30. package/dist/server/src/api/mcp/debug-response-wrapper.js +2 -2
  31. package/dist/server/src/api/mcp/gateway.d.ts.map +1 -1
  32. package/dist/server/src/api/mcp/gateway.js +17 -3
  33. package/dist/server/src/api/mcp/session-context-extractor.d.ts.map +1 -1
  34. package/dist/server/src/api/mcp/session-context-extractor.js +14 -5
  35. package/dist/server/src/cli/commands/mcp-tool-use.d.ts +62 -0
  36. package/dist/server/src/cli/commands/mcp-tool-use.d.ts.map +1 -0
  37. package/dist/server/src/cli/commands/mcp-tool-use.js +174 -0
  38. package/dist/server/src/cli/commands/server.d.ts +57 -0
  39. package/dist/server/src/cli/commands/server.d.ts.map +1 -0
  40. package/dist/server/src/cli/commands/server.js +169 -0
  41. package/dist/server/src/cli/commands/tool-use.d.ts +95 -0
  42. package/dist/server/src/cli/commands/tool-use.d.ts.map +1 -0
  43. package/dist/server/src/cli/commands/tool-use.js +255 -0
  44. package/dist/server/src/cli/index.d.ts +4 -2
  45. package/dist/server/src/cli/index.d.ts.map +1 -1
  46. package/dist/server/src/cli/index.js +35 -3
  47. package/dist/server/src/config/config-loader.js +1 -1
  48. package/dist/server/src/config/config-manager.js +1 -1
  49. package/dist/server/src/models/system-tools.constants.d.ts +2 -2
  50. package/dist/server/src/models/system-tools.constants.d.ts.map +1 -1
  51. package/dist/server/src/models/system-tools.constants.js +2 -2
  52. package/dist/server/src/services/connection/tool-cache.d.ts.map +1 -1
  53. package/dist/server/src/services/connection/tool-cache.js +3 -1
  54. package/dist/server/src/services/gateway/gateway.service.d.ts.map +1 -1
  55. package/dist/server/src/services/gateway/gateway.service.js +38 -4
  56. package/dist/server/src/services/gateway/global-transport.d.ts +14 -5
  57. package/dist/server/src/services/gateway/global-transport.d.ts.map +1 -1
  58. package/dist/server/src/services/gateway/global-transport.js +54 -30
  59. package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts.map +1 -1
  60. package/dist/server/src/services/gateway/request-handlers/initialize-handler.js +12 -1
  61. package/dist/server/src/services/gateway/request-handlers/system-tools-handler.js +2 -2
  62. package/dist/server/src/services/gateway/request-handlers/tools-handler.d.ts.map +1 -1
  63. package/dist/server/src/services/gateway/request-handlers/tools-handler.js +3 -4
  64. package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts +1 -0
  65. package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts.map +1 -1
  66. package/dist/server/src/services/hub-tools/system-tool-definitions.js +4 -3
  67. package/dist/server/src/services/hub-tools.service.d.ts +3 -2
  68. package/dist/server/src/services/hub-tools.service.d.ts.map +1 -1
  69. package/dist/server/src/services/hub-tools.service.js +36 -19
  70. package/dist/server/src/services/search/search-core.service.d.ts +5 -5
  71. package/dist/server/src/services/search/search-core.service.js +11 -11
  72. package/dist/server/src/services/session/session-manager.d.ts +256 -12
  73. package/dist/server/src/services/session/session-manager.d.ts.map +1 -1
  74. package/dist/server/src/services/session/session-manager.js +585 -23
  75. package/dist/server/src/services/session-tracker.service.d.ts +10 -2
  76. package/dist/server/src/services/session-tracker.service.d.ts.map +1 -1
  77. package/dist/server/src/services/session-tracker.service.js +53 -2
  78. package/dist/server/src/services/system-tool-handler.js +2 -2
  79. package/dist/server/src/utils/index.d.ts +1 -0
  80. package/dist/server/src/utils/index.d.ts.map +1 -1
  81. package/dist/server/src/utils/index.js +1 -0
  82. package/dist/server/src/utils/name-converter.d.ts +17 -0
  83. package/dist/server/src/utils/name-converter.d.ts.map +1 -0
  84. package/dist/server/src/utils/name-converter.js +27 -0
  85. package/dist/server/src/utils/request-context.d.ts +18 -0
  86. package/dist/server/src/utils/request-context.d.ts.map +1 -1
  87. package/dist/server/src/utils/request-context.js +20 -0
  88. package/dist/server/tests/evaluation/evaluation.test.js +9 -10
  89. package/dist/server/tests/integration/api/gateway.test.js +2 -2
  90. package/dist/server/tests/unit/services/hub-tools.service.test.js +1 -1
  91. package/dist/server/tests/unit/utils/name-converter.test.d.ts +2 -0
  92. package/dist/server/tests/unit/utils/name-converter.test.d.ts.map +1 -0
  93. package/dist/server/tests/unit/utils/name-converter.test.js +69 -0
  94. package/dist/server/tests/unit/utils/request-context.test.js +24 -5
  95. package/package.json +3 -1
  96. package/dist/client/assets/ToolsView-DFpha1z0.js +0 -1
  97. package/dist/client/assets/ToolsView-E3Ps9c7i.css +0 -1
  98. package/dist/client/assets/el-skeleton-item-DJz-Us12.js +0 -1
  99. package/dist/client/assets/index-vhkqgpmN.js +0 -2
  100. package/dist/client/assets/omit-CqPQN3XP.js +0 -1
@@ -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-vhkqgpmN.js"></script>
9
- <link rel="modulepreload" crossorigin href="/assets/vue-vendor-BLHLXXJK.js">
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(`MCP Gateway error response: ${statusCode} ${statusMessage || ''} Headers: ${stringifyForLogging(headers)}`, LOG_MODULES.COMMUNICATION);
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(`MCP Gateway error response: ${statusCode} ${statusMessage || ''}`, LOG_MODULES.COMMUNICATION);
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,iBA0F9D"}
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 { globalTransport } from '../../services/gateway/global-transport.js';
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
- await globalTransport.handleRequest(request.raw, reply.raw, request.body);
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
- logger.error(`Error handling MCP request: ${errorMessage}`, error, LOG_MODULES.GATEWAY);
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,CAyFA"}
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 memory (for debugging)
52
+ // If sessionId was extracted, check if it exists in persisted sessions (for debugging)
53
53
  if (sessionId) {
54
- const hasSession = mcpSessionManager.hasSession(sessionId);
55
- if (hasSession) {
56
- logger.debug(`Session ${sessionId} found in active sessions`, LOG_MODULES.CONTEXT);
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 active sessions (will create new)`, LOG_MODULES.CONTEXT);
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
+ });