@loop_ouroboros/mcp-hub-lite 1.1.1 → 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/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/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/request-handlers/system-tools-handler.js +2 -2
- 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/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/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/package.json +2 -2
|
@@ -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,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
|
|
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
|
|
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;
|
|
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
|
|
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
|
|
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 (
|
|
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.
|
|
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.
|
|
49
|
+
logger.debug(`Using config file: ${this.configPath}`, LOG_MODULES.CONFIG_MANAGER);
|
|
50
50
|
this.config = loadConfig(this.configPath, true);
|
|
51
51
|
}
|
|
52
52
|
/**
|