@loop_ouroboros/mcp-hub-lite 1.1.1 → 1.2.1

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 (37) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/README.md +73 -115
  3. package/dist/server/src/cli/commands/mcp-tool-use.d.ts +62 -0
  4. package/dist/server/src/cli/commands/mcp-tool-use.d.ts.map +1 -0
  5. package/dist/server/src/cli/commands/mcp-tool-use.js +174 -0
  6. package/dist/server/src/cli/commands/tool-use.d.ts +95 -0
  7. package/dist/server/src/cli/commands/tool-use.d.ts.map +1 -0
  8. package/dist/server/src/cli/commands/tool-use.js +255 -0
  9. package/dist/server/src/cli/index.d.ts +4 -2
  10. package/dist/server/src/cli/index.d.ts.map +1 -1
  11. package/dist/server/src/cli/index.js +35 -3
  12. package/dist/server/src/config/config-loader.js +1 -1
  13. package/dist/server/src/config/config-manager.js +1 -1
  14. package/dist/server/src/models/system-tools.constants.d.ts +2 -2
  15. package/dist/server/src/models/system-tools.constants.d.ts.map +1 -1
  16. package/dist/server/src/models/system-tools.constants.js +2 -2
  17. package/dist/server/src/services/connection/tool-cache.d.ts.map +1 -1
  18. package/dist/server/src/services/connection/tool-cache.js +3 -1
  19. package/dist/server/src/services/gateway/request-handlers/system-tools-handler.js +2 -2
  20. package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts +1 -0
  21. package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts.map +1 -1
  22. package/dist/server/src/services/hub-tools/system-tool-definitions.js +4 -3
  23. package/dist/server/src/services/hub-tools.service.d.ts +3 -2
  24. package/dist/server/src/services/hub-tools.service.d.ts.map +1 -1
  25. package/dist/server/src/services/hub-tools.service.js +36 -19
  26. package/dist/server/src/services/system-tool-handler.js +2 -2
  27. package/dist/server/src/utils/index.d.ts +1 -0
  28. package/dist/server/src/utils/index.d.ts.map +1 -1
  29. package/dist/server/src/utils/index.js +1 -0
  30. package/dist/server/src/utils/name-converter.d.ts +17 -0
  31. package/dist/server/src/utils/name-converter.d.ts.map +1 -0
  32. package/dist/server/src/utils/name-converter.js +27 -0
  33. package/dist/server/tests/unit/services/hub-tools.service.test.js +1 -1
  34. package/dist/server/tests/unit/utils/name-converter.test.d.ts +2 -0
  35. package/dist/server/tests/unit/utils/name-converter.test.d.ts.map +1 -0
  36. package/dist/server/tests/unit/utils/name-converter.test.js +69 -0
  37. package/package.json +2 -2
@@ -0,0 +1,95 @@
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-hub-lite tool-use <action> [--server <serverName>] [--tool <toolName>] [--args <json>] [--tags <json>]
13
+ * ```
14
+ *
15
+ * Or via npm:
16
+ * ```
17
+ * npm run tool-use -- <action> [--server <serverName>] [--tool <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` - Get complete schema for a specific tool (requires --tool)
25
+ * - `call-tool` - Call a tool on the specified server (requires --tool)
26
+ *
27
+ * ## Options
28
+ *
29
+ * - `--server <serverName>` - Server name to target (use "mcp-hub-lite" for system tools)
30
+ * - `--tool <toolName>` - Tool name (required for get-tool and call-tool actions)
31
+ * - `--args <json>` - JSON string of tool arguments, or combined JSON with server/tool/args fields
32
+ * - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
33
+ *
34
+ * ## JSON Merge Logic
35
+ *
36
+ * When `--args` contains `server`, `tool`, or `args` fields, they are extracted and merged:
37
+ * - `server` field → effective server name
38
+ * - `tool` field → effective tool name
39
+ * - `args` field → tool arguments
40
+ * - Other fields → treated as tool arguments
41
+ *
42
+ * This allows passing all parameters in a single JSON object via --args.
43
+ *
44
+ * ## Usage Examples
45
+ *
46
+ * ###分散参数形式 (Separate Arguments):
47
+ *
48
+ * ```bash
49
+ * # List all connected servers
50
+ * mcp-hub-lite tool-use list-servers
51
+ *
52
+ * # List system tools
53
+ * mcp-hub-lite tool-use list-tools --server mcp-hub-lite
54
+ *
55
+ * # List third-party server tools
56
+ * mcp-hub-lite tool-use list-tools --server baidu-search
57
+ *
58
+ * # Get system tool schema
59
+ * mcp-hub-lite tool-use get-tool --tool list_tools --server mcp-hub-lite
60
+ *
61
+ * # Call system tool
62
+ * mcp-hub-lite tool-use call-tool --tool list_tools --server mcp-hub-lite --args '{}'
63
+ *
64
+ * # Call third-party server tool
65
+ * mcp-hub-lite tool-use call-tool --tool search --server baidu-search --args '{"query":"天气"}'
66
+ *
67
+ * # Multi-instance server with tags
68
+ * mcp-hub-lite tool-use call-tool --tool search --server baidu-search --args '{"query":"test"}' --tags '{"env":"prod"}'
69
+ * ```
70
+ *
71
+ * ### JSON 合并形式 (JSON Merge):
72
+ *
73
+ * ```bash
74
+ * # All parameters in one JSON
75
+ * mcp-hub-lite tool-use call-tool --args '{"server":"baidu-search","tool":"search","query":"天气"}'
76
+ *
77
+ * # System tool example
78
+ * mcp-hub-lite tool-use call-tool --args '{"server":"mcp-hub-lite","tool":"list_tools"}'
79
+ *
80
+ * # Equivalent to
81
+ * mcp-hub-lite tool-use call-tool --server baidu-search --tool search --args '{"query":"天气"}'
82
+ * ```
83
+ *
84
+ * ## Error Handling
85
+ *
86
+ * - Exits with code 1 if the server is not running
87
+ * - Exits with code 1 if action is unknown
88
+ * - Exits with code 1 if toolName is required but not provided
89
+ * - Exits with code 1 if JSON parsing fails for --args or --tags
90
+ * - Exits with code 1 if the underlying API call fails
91
+ *
92
+ * @returns {Command} The configured mcp-tool-use command instance for registration with Commander.js
93
+ */
94
+ export declare const toolUseCommand: Command;
95
+ //# sourceMappingURL=tool-use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-use.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/tool-use.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2FG;AACH,eAAO,MAAM,cAAc,SAwLvB,CAAC"}
@@ -0,0 +1,255 @@
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-hub-lite tool-use <action> [--server <serverName>] [--tool <toolName>] [--args <json>] [--tags <json>]
14
+ * ```
15
+ *
16
+ * Or via npm:
17
+ * ```
18
+ * npm run tool-use -- <action> [--server <serverName>] [--tool <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` - Get complete schema for a specific tool (requires --tool)
26
+ * - `call-tool` - Call a tool on the specified server (requires --tool)
27
+ *
28
+ * ## Options
29
+ *
30
+ * - `--server <serverName>` - Server name to target (use "mcp-hub-lite" for system tools)
31
+ * - `--tool <toolName>` - Tool name (required for get-tool and call-tool actions)
32
+ * - `--args <json>` - JSON string of tool arguments, or combined JSON with server/tool/args fields
33
+ * - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
34
+ *
35
+ * ## JSON Merge Logic
36
+ *
37
+ * When `--args` contains `server`, `tool`, or `args` fields, they are extracted and merged:
38
+ * - `server` field → effective server name
39
+ * - `tool` field → effective tool name
40
+ * - `args` field → tool arguments
41
+ * - Other fields → treated as tool arguments
42
+ *
43
+ * This allows passing all parameters in a single JSON object via --args.
44
+ *
45
+ * ## Usage Examples
46
+ *
47
+ * ###分散参数形式 (Separate Arguments):
48
+ *
49
+ * ```bash
50
+ * # List all connected servers
51
+ * mcp-hub-lite tool-use list-servers
52
+ *
53
+ * # List system tools
54
+ * mcp-hub-lite tool-use list-tools --server mcp-hub-lite
55
+ *
56
+ * # List third-party server tools
57
+ * mcp-hub-lite tool-use list-tools --server baidu-search
58
+ *
59
+ * # Get system tool schema
60
+ * mcp-hub-lite tool-use get-tool --tool list_tools --server mcp-hub-lite
61
+ *
62
+ * # Call system tool
63
+ * mcp-hub-lite tool-use call-tool --tool list_tools --server mcp-hub-lite --args '{}'
64
+ *
65
+ * # Call third-party server tool
66
+ * mcp-hub-lite tool-use call-tool --tool search --server baidu-search --args '{"query":"天气"}'
67
+ *
68
+ * # Multi-instance server with tags
69
+ * mcp-hub-lite tool-use call-tool --tool search --server baidu-search --args '{"query":"test"}' --tags '{"env":"prod"}'
70
+ * ```
71
+ *
72
+ * ### JSON 合并形式 (JSON Merge):
73
+ *
74
+ * ```bash
75
+ * # All parameters in one JSON
76
+ * mcp-hub-lite tool-use call-tool --args '{"server":"baidu-search","tool":"search","query":"天气"}'
77
+ *
78
+ * # System tool example
79
+ * mcp-hub-lite tool-use call-tool --args '{"server":"mcp-hub-lite","tool":"list_tools"}'
80
+ *
81
+ * # Equivalent to
82
+ * mcp-hub-lite tool-use call-tool --server baidu-search --tool search --args '{"query":"天气"}'
83
+ * ```
84
+ *
85
+ * ## Error Handling
86
+ *
87
+ * - Exits with code 1 if the server is not running
88
+ * - Exits with code 1 if action is unknown
89
+ * - Exits with code 1 if toolName is required but not provided
90
+ * - Exits with code 1 if JSON parsing fails for --args or --tags
91
+ * - Exits with code 1 if the underlying API call fails
92
+ *
93
+ * @returns {Command} The configured mcp-tool-use command instance for registration with Commander.js
94
+ */
95
+ export const toolUseCommand = new Command('tool-use')
96
+ .description('Manage MCP server tools via API (list-servers, list-tools, get-tool, call-tool)')
97
+ .argument('<action>', 'Action: list-servers, list-tools, get-tool, call-tool')
98
+ .option('--server <serverName>', 'Server name to target (omit or empty for system tools)')
99
+ .option('--tool <toolName>', 'Tool name (required for get-tool and call-tool actions)')
100
+ .option('--args <json>', 'JSON string of tool arguments, or combined JSON with server/tool/args fields')
101
+ .option('--tags <json>', 'JSON object of instance selection tags (call-tool only, for multi-instance servers)')
102
+ .addHelpText('after', `
103
+
104
+ Examples:
105
+ # List all connected servers
106
+ mcp-hub-lite tool-use list-servers
107
+
108
+ # List mcp-hub-lite system tools (default)
109
+ mcp-hub-lite tool-use list-tools
110
+
111
+ # List third-party server tools
112
+ mcp-hub-lite tool-use list-tools --server baidu-search
113
+
114
+ # Get system tool schema
115
+ mcp-hub-lite tool-use get-tool --tool list_tools
116
+
117
+ # Call third-party server tool
118
+ mcp-hub-lite tool-use call-tool --tool search --server baidu-search --args '{"query":"天气"}'
119
+
120
+ # JSON merge form (all params in one JSON)
121
+ mcp-hub-lite tool-use call-tool --args '{"server":"baidu-search","tool":"search","query":"天气"}'
122
+ `)
123
+ .action(async (action, options) => {
124
+ try {
125
+ // Check if server is running and get connection info
126
+ const status = await getServerStatus();
127
+ if (!status.running) {
128
+ console.error('Error: MCP Hub Lite server is not running.');
129
+ console.error('Start the server with: mcp-hub-lite start');
130
+ process.exit(1);
131
+ }
132
+ // Parse JSON merge logic: extract server, tool, and args from --args if present
133
+ let toolArgs = {};
134
+ // When --server is not provided, default to mcp-hub-lite (system tools)
135
+ const defaultServer = 'mcp-hub-lite';
136
+ let effectiveServer = options.server || defaultServer;
137
+ let effectiveTool = options.tool ?? '';
138
+ if (options.args) {
139
+ try {
140
+ const parsedArgs = JSON.parse(options.args);
141
+ // Extract server and tool from JSON if present
142
+ if (parsedArgs.server !== undefined) {
143
+ effectiveServer = parsedArgs.server;
144
+ }
145
+ if (parsedArgs.tool !== undefined) {
146
+ effectiveTool = parsedArgs.tool;
147
+ }
148
+ // Extract args if present, otherwise treat other fields as tool args
149
+ if (parsedArgs.args !== undefined) {
150
+ toolArgs = parsedArgs.args;
151
+ }
152
+ else {
153
+ // Other fields (excluding server and tool) are treated as tool args
154
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
155
+ const { server: _server, tool: _tool, ...rest } = parsedArgs;
156
+ toolArgs = rest;
157
+ }
158
+ }
159
+ catch {
160
+ // If JSON parsing fails, treat the entire content as tool args
161
+ try {
162
+ toolArgs = JSON.parse(options.args);
163
+ }
164
+ catch {
165
+ console.error('Error: Invalid JSON in --args option');
166
+ process.exit(1);
167
+ }
168
+ }
169
+ }
170
+ const baseUrl = `http://${status.host}:${status.port}`;
171
+ switch (action) {
172
+ case 'list-servers': {
173
+ const response = await fetch(`${baseUrl}/web/hub-tools/servers`, {
174
+ headers: { Accept: 'application/json' }
175
+ });
176
+ if (!response.ok) {
177
+ throw new Error(`API error: ${response.status} ${response.statusText}`);
178
+ }
179
+ const result = await response.json();
180
+ console.log(JSON.stringify(result, null, 2));
181
+ break;
182
+ }
183
+ case 'list-tools': {
184
+ const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
185
+ const response = await fetch(`${baseUrl}/web/hub-tools/servers/${effectiveServer}/tools${tagsParam}`, {
186
+ headers: { Accept: 'application/json' }
187
+ });
188
+ if (!response.ok) {
189
+ const error = await response.json().catch(() => ({ message: response.statusText }));
190
+ throw new Error(error.message || `API error: ${response.status}`);
191
+ }
192
+ const result = await response.json();
193
+ console.log(JSON.stringify(result, null, 2));
194
+ break;
195
+ }
196
+ case 'get-tool': {
197
+ if (!effectiveTool) {
198
+ console.error('Error: toolName is required for get-tool action');
199
+ process.exit(1);
200
+ }
201
+ const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
202
+ const response = await fetch(`${baseUrl}/web/hub-tools/servers/${effectiveServer}/tools/${effectiveTool}${tagsParam}`, { headers: { Accept: 'application/json' } });
203
+ if (!response.ok) {
204
+ const error = await response.json().catch(() => ({ message: response.statusText }));
205
+ throw new Error(error.message || `API error: ${response.status}`);
206
+ }
207
+ const result = await response.json();
208
+ console.log(JSON.stringify(result, null, 2));
209
+ break;
210
+ }
211
+ case 'call-tool': {
212
+ if (!effectiveTool) {
213
+ console.error('Error: toolName is required for call-tool action');
214
+ process.exit(1);
215
+ }
216
+ // Parse tags for instance selection (call-tool only)
217
+ let requestOptions;
218
+ if (options.tags) {
219
+ try {
220
+ requestOptions = { tags: JSON.parse(options.tags) };
221
+ }
222
+ catch {
223
+ console.error('Error: Invalid JSON in --tags option');
224
+ process.exit(1);
225
+ }
226
+ }
227
+ const response = await fetch(`${baseUrl}/web/hub-tools/servers/${effectiveServer}/tools/${effectiveTool}/call`, {
228
+ method: 'POST',
229
+ headers: {
230
+ 'Content-Type': 'application/json',
231
+ Accept: 'application/json'
232
+ },
233
+ body: JSON.stringify({ toolArgs, requestOptions })
234
+ });
235
+ if (!response.ok) {
236
+ const error = await response.json().catch(() => ({ message: response.statusText }));
237
+ throw new Error(error.message || `API error: ${response.status}`);
238
+ }
239
+ const result = await response.json();
240
+ console.log(JSON.stringify(result, null, 2));
241
+ break;
242
+ }
243
+ default: {
244
+ console.error(`Unknown action: ${action}`);
245
+ console.error('Valid actions: list-servers, list-tools, get-tool, call-tool');
246
+ process.exit(1);
247
+ }
248
+ }
249
+ process.exit(0);
250
+ }
251
+ catch (error) {
252
+ console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
253
+ process.exit(1);
254
+ }
255
+ });
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * MCP Hub Lite CLI Entry Point
4
- * Implements 6 core commands: start, stop, status, ui, list, restart
4
+ * Implements 7 core commands: start, stop, status, ui, list, restart, tool-use
5
5
  */
6
6
  import { Command } from 'commander';
7
7
  /**
@@ -11,13 +11,14 @@ import { Command } from 'commander';
11
11
  * then registers all available commands to provide a complete command-line interface
12
12
  * for managing the MCP Hub Lite service.
13
13
  *
14
- * The CLI provides six core commands:
14
+ * The CLI provides seven core commands:
15
15
  * - start: Launches the MCP Hub Lite service in daemon or foreground mode
16
16
  * - stop: Gracefully terminates the running service instance
17
17
  * - status: Displays current service status including PID, port, host, and server count
18
18
  * - ui: Opens the web-based user interface in the default browser
19
19
  * - list: Shows all configured MCP servers in a tabular format
20
20
  * - restart: Stops and restarts the service with the same configuration
21
+ * - tool-use: Manage MCP server tools via API (list-servers, list-tools, get-tool, call-tool)
21
22
  *
22
23
  * Usage examples:
23
24
  * ```bash
@@ -57,6 +58,7 @@ import { Command } from 'commander';
57
58
  * @see {@link uiCommand} - Implementation of the ui command
58
59
  * @see {@link listCommand} - Implementation of the list command
59
60
  * @see {@link restartCommand} - Implementation of the restart command
61
+ * @see {@link toolUseCommand} - Implementation of the tool-use command
60
62
  */
61
63
  export declare function createCli(): Command;
62
64
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAiBnC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cli/index.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8CpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAkBnC"}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * MCP Hub Lite CLI Entry Point
4
- * Implements 6 core commands: start, stop, status, ui, list, restart
4
+ * Implements 7 core commands: start, stop, status, ui, list, restart, tool-use
5
5
  */
6
6
  import { Command } from 'commander';
7
7
  import { argv } from 'node:process';
@@ -13,6 +13,35 @@ import { statusCommand } from './commands/status.js';
13
13
  import { uiCommand } from './commands/ui.js';
14
14
  import { listCommand } from './commands/list.js';
15
15
  import { restartCommand } from './commands/restart.js';
16
+ import { toolUseCommand } from './commands/tool-use.js';
17
+ /**
18
+ * Check if the CLI is being executed directly (vs imported as module)
19
+ * Handles Windows/npm symlink path resolution issues by comparing package paths
20
+ */
21
+ function isCliEntry() {
22
+ if (!argv[1]) {
23
+ return false;
24
+ }
25
+ const currentUrl = import.meta.url;
26
+ const argvUrl = pathToFileURL(argv[1]).href;
27
+ // Extract pathname and normalize for comparison
28
+ const normalizePath = (url) => {
29
+ // Convert file:// URL to pathname and normalize separators
30
+ const urlObj = new URL(url);
31
+ return urlObj.pathname.replace(/\//g, '/');
32
+ };
33
+ const currentPath = normalizePath(currentUrl);
34
+ const argvPath = normalizePath(argvUrl);
35
+ // Extract package path suffix for comparison
36
+ // Both paths contain mcp-hub-lite/dist, extract that common suffix
37
+ const getPackagePath = (path) => {
38
+ const match = path.match(/mcp-hub-lite[/\\]dist/);
39
+ return match ? match[0] : null;
40
+ };
41
+ const currentPackagePath = getPackagePath(currentPath);
42
+ const argvPackagePath = getPackagePath(argvPath);
43
+ return currentPackagePath !== null && currentPackagePath === argvPackagePath;
44
+ }
16
45
  /**
17
46
  * Creates and configures the CLI application using Commander.js
18
47
  *
@@ -20,13 +49,14 @@ import { restartCommand } from './commands/restart.js';
20
49
  * then registers all available commands to provide a complete command-line interface
21
50
  * for managing the MCP Hub Lite service.
22
51
  *
23
- * The CLI provides six core commands:
52
+ * The CLI provides seven core commands:
24
53
  * - start: Launches the MCP Hub Lite service in daemon or foreground mode
25
54
  * - stop: Gracefully terminates the running service instance
26
55
  * - status: Displays current service status including PID, port, host, and server count
27
56
  * - ui: Opens the web-based user interface in the default browser
28
57
  * - list: Shows all configured MCP servers in a tabular format
29
58
  * - restart: Stops and restarts the service with the same configuration
59
+ * - tool-use: Manage MCP server tools via API (list-servers, list-tools, get-tool, call-tool)
30
60
  *
31
61
  * Usage examples:
32
62
  * ```bash
@@ -66,6 +96,7 @@ import { restartCommand } from './commands/restart.js';
66
96
  * @see {@link uiCommand} - Implementation of the ui command
67
97
  * @see {@link listCommand} - Implementation of the list command
68
98
  * @see {@link restartCommand} - Implementation of the restart command
99
+ * @see {@link toolUseCommand} - Implementation of the tool-use command
69
100
  */
70
101
  export function createCli() {
71
102
  const program = new Command();
@@ -80,10 +111,11 @@ export function createCli() {
80
111
  program.addCommand(uiCommand);
81
112
  program.addCommand(listCommand);
82
113
  program.addCommand(restartCommand);
114
+ program.addCommand(toolUseCommand);
83
115
  return program;
84
116
  }
85
117
  // Execute the CLI if this file is run directly
86
- if (argv[1] && pathToFileURL(argv[1]).href === import.meta.url) {
118
+ if (isCliEntry()) {
87
119
  const cli = createCli();
88
120
  cli.parse();
89
121
  }
@@ -27,7 +27,7 @@ import { reassignServerInstanceIndexes } from './server-config-manager.js';
27
27
  export function loadConfig(configPath, autoMigrate = true) {
28
28
  try {
29
29
  if (fs.existsSync(configPath)) {
30
- logger.info(`Loading configuration from: ${configPath}`, LOG_MODULES.CONFIG_MANAGER);
30
+ logger.debug(`Loading configuration from: ${configPath}`, LOG_MODULES.CONFIG_MANAGER);
31
31
  const content = fs.readFileSync(configPath, 'utf-8');
32
32
  let config = JSON.parse(content);
33
33
  // Check if automatic migration is enabled and config is legacy v1.0
@@ -46,7 +46,7 @@ export class ConfigManager {
46
46
  configPath ||
47
47
  process.env.MCP_HUB_CONFIG_PATH ||
48
48
  path.join(os.homedir(), '.mcp-hub-lite', 'config', '.mcp-hub.json');
49
- logger.info(`Using config file: ${this.configPath}`, LOG_MODULES.CONFIG_MANAGER);
49
+ logger.debug(`Using config file: ${this.configPath}`, LOG_MODULES.CONFIG_MANAGER);
50
50
  this.config = loadConfig(this.configPath, true);
51
51
  }
52
52
  /**
@@ -34,7 +34,7 @@ export interface UpdateServerDescriptionParams {
34
34
  }
35
35
  export type SystemToolArgs = ListServersParams | ListToolsInServerParams | GetToolParams | CallToolParams | UpdateServerDescriptionParams;
36
36
  export declare const LIST_SERVERS_TOOL = "list_servers";
37
- export declare const LIST_TOOLS_IN_SERVER_TOOL = "list_tools_in_server";
37
+ export declare const LIST_TOOLS_TOOL = "list_tools";
38
38
  export declare const GET_TOOL_TOOL = "get_tool";
39
39
  export declare const CALL_TOOL_TOOL = "call_tool";
40
40
  export declare const UPDATE_SERVER_DESCRIPTION_TOOL = "update_server_description";
@@ -42,7 +42,7 @@ export declare const UPDATE_SERVER_DESCRIPTION_TOOL = "update_server_description
42
42
  * List of all system tool names
43
43
  * This array is used to identify system tools across the application
44
44
  */
45
- export declare const SYSTEM_TOOL_NAMES: readonly ["list_servers", "list_tools_in_server", "get_tool", "call_tool", "update_server_description"];
45
+ export declare const SYSTEM_TOOL_NAMES: readonly ["list_servers", "list_tools", "get_tool", "call_tool", "update_server_description"];
46
46
  /**
47
47
  * Type definition for system tool names
48
48
  * Provides type safety when working with system tool names
@@ -1 +1 @@
1
- {"version":3,"file":"system-tools.constants.d.ts","sourceRoot":"","sources":["../../../../src/models/system-tools.constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,uBAAuB,GACvB,aAAa,GACb,cAAc,GACd,6BAA6B,CAAC;AAGlC,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAChE,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,iBAAiB,yGAMpB,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGhE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC"}
1
+ {"version":3,"file":"system-tools.constants.d.ts","sourceRoot":"","sources":["../../../../src/models/system-tools.constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC/B,CAAC;CACH;AAED,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,uBAAuB,GACvB,aAAa,GACb,cAAc,GACd,6BAA6B,CAAC;AAGlC,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,eAAe,eAAe,CAAC;AAC5C,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,iBAAiB,+FAMpB,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGhE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC"}
@@ -4,7 +4,7 @@
4
4
  */
5
5
  // Individual system tool name constants
6
6
  export const LIST_SERVERS_TOOL = 'list_servers';
7
- export const LIST_TOOLS_IN_SERVER_TOOL = 'list_tools_in_server';
7
+ export const LIST_TOOLS_TOOL = 'list_tools';
8
8
  export const GET_TOOL_TOOL = 'get_tool';
9
9
  export const CALL_TOOL_TOOL = 'call_tool';
10
10
  export const UPDATE_SERVER_DESCRIPTION_TOOL = 'update_server_description';
@@ -14,7 +14,7 @@ export const UPDATE_SERVER_DESCRIPTION_TOOL = 'update_server_description';
14
14
  */
15
15
  export const SYSTEM_TOOL_NAMES = [
16
16
  LIST_SERVERS_TOOL,
17
- LIST_TOOLS_IN_SERVER_TOOL,
17
+ LIST_TOOLS_TOOL,
18
18
  GET_TOOL_TOOL,
19
19
  CALL_TOOL_TOOL,
20
20
  UPDATE_SERVER_DESCRIPTION_TOOL
@@ -1 +1 @@
1
- {"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../../../../src/services/connection/tool-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGzD;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,qBAAqB,CAAkC;IAE/D;;;;;OAKG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAI9D;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI3C;;;;OAIG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IASjD;;;;;OAKG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvD;;;;;OAKG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAS/C;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAWtE;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE;IAWzD;;;;;OAKG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE;IAIhD;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAK/D;;;;OAIG;IACH,WAAW,IAAI,IAAI,EAAE;IAQrB;;;;OAIG;IACH,uBAAuB,IAAI,IAAI,EAAE;IAQjC;;;;OAIG;IACH,mBAAmB,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE;IAIzC;;;;;;OAMG;IACH,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAI7C;;;;;OAKG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAWzD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;;;OAIG;IACH,IAAI,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAE3C;CACF"}
1
+ {"version":3,"file":"tool-cache.d.ts","sourceRoot":"","sources":["../../../../../src/services/connection/tool-cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAIzD;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,mBAAmB,CAAkC;IAC7D,OAAO,CAAC,qBAAqB,CAAkC;IAE/D;;;;;OAKG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAI9D;;;;OAIG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI3C;;;;OAIG;IACH,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IASjD;;;;;OAKG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvD;;;;;OAKG;IACH,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAS/C;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI;IAWtE;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE;IAWzD;;;;;OAKG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE;IAIhD;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAM/D;;;;OAIG;IACH,WAAW,IAAI,IAAI,EAAE;IAQrB;;;;OAIG;IACH,uBAAuB,IAAI,IAAI,EAAE;IAQjC;;;;OAIG;IACH,mBAAmB,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE;IAIzC;;;;;;OAMG;IACH,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAI7C;;;;;OAKG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAWzD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;;;OAIG;IACH,IAAI,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAE3C;CACF"}
@@ -1,5 +1,6 @@
1
1
  import { logger, LOG_MODULES } from '../../utils/logger.js';
2
2
  import { getCompositeKey } from '../../utils/composite-key.js';
3
+ import { normalizeToolName } from '../../utils/name-converter.js';
3
4
  /**
4
5
  * Manages tool caching for MCP connections at both composite key and server name levels.
5
6
  *
@@ -109,7 +110,8 @@ export class ToolCache {
109
110
  */
110
111
  getTool(serverName, toolName) {
111
112
  const tools = this.serverNameToolCache.get(serverName);
112
- return tools?.find((t) => t.name === toolName);
113
+ const normalized = normalizeToolName(toolName);
114
+ return tools?.find((t) => normalizeToolName(t.name) === normalized);
113
115
  }
114
116
  /**
115
117
  * Gets all tools from all connected server instances.
@@ -6,7 +6,7 @@ import { McpError } from '@modelcontextprotocol/sdk/types.js';
6
6
  import { logger } from '../../../utils/index.js';
7
7
  import { LOG_MODULES } from '../../../utils/logger/log-modules.js';
8
8
  import { hubToolsService } from '../../hub-tools.service.js';
9
- import { LIST_SERVERS_TOOL, LIST_TOOLS_IN_SERVER_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL } from '../../../models/system-tools.constants.js';
9
+ import { LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL } from '../../../models/system-tools.constants.js';
10
10
  /**
11
11
  * Register system tools handlers on the MCP server.
12
12
  *
@@ -26,7 +26,7 @@ export function registerSystemToolsHandlers(server) {
26
26
  });
27
27
  // List all tools in a specific server
28
28
  const ListToolsInServerRequestSchema = z.object({
29
- method: z.literal(LIST_TOOLS_IN_SERVER_TOOL),
29
+ method: z.literal(LIST_TOOLS_TOOL),
30
30
  params: z.object({
31
31
  serverName: z.string(),
32
32
  requestOptions: z
@@ -30,6 +30,7 @@ export interface SystemToolDefinition {
30
30
  * - list-tools-in-server: List tools from a specific server
31
31
  * - get-tool: Get complete tool schema
32
32
  * - call-tool: Call a specific tool from a specific server
33
+ * - update-server-description: Update the description of a specific MCP server
33
34
  *
34
35
  * @returns {Array<{ name: string; description: string; inputSchema: JsonSchema; annotations?: ToolAnnotations }>}
35
36
  * Array of system tool configurations
@@ -1 +1 @@
1
- {"version":3,"file":"system-tool-definitions.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/system-tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAU/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,EAAE,CA6IvD"}
1
+ {"version":3,"file":"system-tool-definitions.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/system-tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAU/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,EAAE,CA6IvD"}
@@ -1,4 +1,4 @@
1
- import { SYSTEM_TOOL_NAMES, LIST_SERVERS_TOOL, LIST_TOOLS_IN_SERVER_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL } from '../../models/system-tools.constants.js';
1
+ import { SYSTEM_TOOL_NAMES, LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL } from '../../models/system-tools.constants.js';
2
2
  /**
3
3
  * Retrieves the complete list of system tools provided by this service.
4
4
  *
@@ -11,6 +11,7 @@ import { SYSTEM_TOOL_NAMES, LIST_SERVERS_TOOL, LIST_TOOLS_IN_SERVER_TOOL, GET_TO
11
11
  * - list-tools-in-server: List tools from a specific server
12
12
  * - get-tool: Get complete tool schema
13
13
  * - call-tool: Call a specific tool from a specific server
14
+ * - update-server-description: Update the description of a specific MCP server
14
15
  *
15
16
  * @returns {Array<{ name: string; description: string; inputSchema: JsonSchema; annotations?: ToolAnnotations }>}
16
17
  * Array of system tool configurations
@@ -43,7 +44,7 @@ export function getSystemTools() {
43
44
  }
44
45
  });
45
46
  break;
46
- case LIST_TOOLS_IN_SERVER_TOOL:
47
+ case LIST_TOOLS_TOOL:
47
48
  systemTools.push({
48
49
  name: toolName,
49
50
  description: 'List all tools from a specific server',
@@ -102,7 +103,7 @@ export function getSystemTools() {
102
103
  systemTools.push({
103
104
  name: toolName,
104
105
  description: 'Call a specific tool from an external MCP server. ' +
105
- 'System tools (list_servers, list_tools_in_server, get_tool, update_server_description) ' +
106
+ 'System tools (list_servers, list_tools, get_tool, update_server_description) ' +
106
107
  'must be called directly via tools/call, not through this tool.',
107
108
  inputSchema: {
108
109
  type: 'object',