@loop_ouroboros/mcp-hub-lite 1.2.4 → 1.2.5
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 +19 -0
- package/dist/server/src/api/web/hub-tools.d.ts.map +1 -1
- package/dist/server/src/api/web/hub-tools.js +15 -0
- package/dist/server/src/api/web/mcp-status.d.ts.map +1 -1
- package/dist/server/src/api/web/mcp-status.js +4 -0
- package/dist/server/src/cli/commands/status.js +13 -3
- package/dist/server/src/cli/commands/tool-use.d.ts +5 -1
- package/dist/server/src/cli/commands/tool-use.d.ts.map +1 -1
- package/dist/server/src/cli/commands/tool-use.js +27 -4
- package/dist/server/src/cli/server.d.ts +2 -0
- package/dist/server/src/cli/server.d.ts.map +1 -1
- package/dist/server/src/cli/server.js +2 -0
- package/dist/server/src/models/system-tools.constants.d.ts +6 -2
- package/dist/server/src/models/system-tools.constants.d.ts.map +1 -1
- package/dist/server/src/models/system-tools.constants.js +3 -1
- package/dist/server/src/services/gateway/request-handlers/system-tools-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/system-tools-handler.js +28 -1
- package/dist/server/src/services/gateway/tool-list-generator.js +1 -1
- package/dist/server/src/services/hub-tools/instance-selector.js +1 -1
- package/dist/server/src/services/hub-tools/resource-generator.d.ts.map +1 -1
- package/dist/server/src/services/hub-tools/resource-generator.js +32 -13
- package/dist/server/src/services/hub-tools/server-selector.d.ts +2 -2
- package/dist/server/src/services/hub-tools/server-selector.d.ts.map +1 -1
- package/dist/server/src/services/hub-tools/server-selector.js +4 -3
- 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 +23 -3
- package/dist/server/src/services/hub-tools.service.d.ts +29 -7
- package/dist/server/src/services/hub-tools.service.d.ts.map +1 -1
- package/dist/server/src/services/hub-tools.service.js +76 -33
- package/dist/server/src/services/system-tool-handler.d.ts.map +1 -1
- package/dist/server/src/services/system-tool-handler.js +21 -8
- package/dist/server/src/utils/name-converter.d.ts.map +1 -1
- package/dist/server/src/utils/name-converter.js +2 -0
- package/dist/server/tests/unit/services/hub-tools.service.test.js +6 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.2.5] - 2026-04-28
|
|
6
|
+
|
|
7
|
+
### Hub Tools
|
|
8
|
+
|
|
9
|
+
- enhance hub-tools system with improved tool handling
|
|
10
|
+
- add list_tags tool constants and update CLAUDE.md docs
|
|
11
|
+
- add comprehensive use guide documentation
|
|
12
|
+
- improve default server description text
|
|
13
|
+
- remove stale cache in listResources
|
|
14
|
+
- clarify instance filtering comment
|
|
15
|
+
- fix listMcpResources returning incomplete server resources by using two-pass approach to check all instances connection status
|
|
16
|
+
- align resource generation logic with /web/mcp/status API behavior
|
|
17
|
+
|
|
18
|
+
### Utils
|
|
19
|
+
|
|
20
|
+
- add null check to normalizeToolName
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
5
24
|
## [1.2.4] - 2026-04-25
|
|
6
25
|
|
|
7
26
|
### Frontend
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hub-tools.d.ts","sourceRoot":"","sources":["../../../../../src/api/web/hub-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"hub-tools.d.ts","sourceRoot":"","sources":["../../../../../src/api/web/hub-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAqB1C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,eAAe,iBAuK/D"}
|
|
@@ -77,6 +77,21 @@ export async function webHubToolsRoutes(fastify) {
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
});
|
|
80
|
+
// GET /web/hub-tools/servers/:serverName/tags - List all instance tags for a specific server
|
|
81
|
+
fastify.get('/web/hub-tools/servers/:serverName/tags', async (request, reply) => {
|
|
82
|
+
try {
|
|
83
|
+
const { serverName } = request.params;
|
|
84
|
+
const params = { serverName };
|
|
85
|
+
const result = await hubToolsService.listTags(params);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
return reply.code(404).send({
|
|
90
|
+
error: 'Server not found',
|
|
91
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
80
95
|
// GET /web/hub-tools/servers/:serverName/tools/:toolName - Get specific tool details
|
|
81
96
|
fastify.get('/web/hub-tools/servers/:serverName/tools/:toolName', async (request, reply) => {
|
|
82
97
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-status.d.ts","sourceRoot":"","sources":["../../../../../src/api/web/mcp-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ1C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"mcp-status.d.ts","sourceRoot":"","sources":["../../../../../src/api/web/mcp-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ1C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,eAAe,iBA6KhE"}
|
|
@@ -43,6 +43,8 @@ export async function webMcpStatusRoutes(fastify) {
|
|
|
43
43
|
id: server.name,
|
|
44
44
|
name: server.name,
|
|
45
45
|
type: server.config.template.type,
|
|
46
|
+
displayName: undefined,
|
|
47
|
+
tags: {},
|
|
46
48
|
status: {
|
|
47
49
|
connected: false,
|
|
48
50
|
lastCheck: Date.now(),
|
|
@@ -60,6 +62,8 @@ export async function webMcpStatusRoutes(fastify) {
|
|
|
60
62
|
id: instance.id || '',
|
|
61
63
|
name: server.name,
|
|
62
64
|
type: resolvedConfig?.type || server.config.template.type,
|
|
65
|
+
displayName: instance.displayName,
|
|
66
|
+
tags: instance.tags,
|
|
63
67
|
status: mcpConnectionManager.getStatus(server.name, instance.index ?? 0) || {
|
|
64
68
|
connected: false,
|
|
65
69
|
lastCheck: Date.now(),
|
|
@@ -97,16 +97,24 @@ function printFormattedStatus(status) {
|
|
|
97
97
|
let maxNameLen = 'Server Name'.length;
|
|
98
98
|
let maxTypeLen = 'Type'.length;
|
|
99
99
|
const maxStatusLen = 'Disconnected'.length;
|
|
100
|
+
let maxDisplayNameLen = 'DisplayName'.length;
|
|
101
|
+
let maxTagsLen = 'Tags'.length;
|
|
100
102
|
for (const server of servers) {
|
|
101
103
|
maxNameLen = Math.max(maxNameLen, (server.name || '').length);
|
|
102
104
|
maxTypeLen = Math.max(maxTypeLen, (server.type || '').length);
|
|
105
|
+
const displayName = server.displayName || '';
|
|
106
|
+
const tags = JSON.stringify(server.tags || {});
|
|
107
|
+
maxDisplayNameLen = Math.max(maxDisplayNameLen, displayName.length);
|
|
108
|
+
maxTagsLen = Math.max(maxTagsLen, tags.length);
|
|
103
109
|
}
|
|
104
110
|
// Simple table without complex borders
|
|
105
111
|
const headerName = 'Server Name'.padEnd(maxNameLen);
|
|
106
112
|
const headerType = 'Type'.padEnd(maxTypeLen);
|
|
107
113
|
const headerStatus = 'Status'.padEnd(maxStatusLen);
|
|
108
|
-
|
|
109
|
-
|
|
114
|
+
const headerDisplayName = 'DisplayName'.padEnd(maxDisplayNameLen);
|
|
115
|
+
const headerTags = 'Tags'.padEnd(maxTagsLen);
|
|
116
|
+
console.log(`${cyan}${headerName} ${headerType} ${headerStatus} Tools Resources ${headerDisplayName} ${headerTags}${reset}`);
|
|
117
|
+
console.log(`${dim}${'─'.repeat(maxNameLen + maxTypeLen + maxStatusLen + 26 + maxDisplayNameLen + maxTagsLen)}${reset}`);
|
|
110
118
|
for (const server of servers) {
|
|
111
119
|
const name = (server.name || '').padEnd(maxNameLen);
|
|
112
120
|
const type = (server.type || '').padEnd(maxTypeLen);
|
|
@@ -115,7 +123,9 @@ function printFormattedStatus(status) {
|
|
|
115
123
|
: `${red}Disconnected${reset}`.padEnd(maxStatusLen + 9);
|
|
116
124
|
const tools = server.toolsCount.toString().padStart(5);
|
|
117
125
|
const resources = server.resourcesCount.toString().padStart(9);
|
|
118
|
-
|
|
126
|
+
const displayName = (server.displayName || '').padEnd(maxDisplayNameLen);
|
|
127
|
+
const tags = JSON.stringify(server.tags || {}).padEnd(maxTagsLen);
|
|
128
|
+
console.log(`${name} ${type} ${statusText} ${tools} ${resources} ${displayName} ${tags}`);
|
|
119
129
|
if (server.error) {
|
|
120
130
|
console.log(` ${red}Error: ${server.error}${reset}`);
|
|
121
131
|
}
|
|
@@ -3,7 +3,7 @@ import { Command } from 'commander';
|
|
|
3
3
|
* CLI command for dynamic MCP server tool operations via API.
|
|
4
4
|
*
|
|
5
5
|
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
6
|
-
* supporting
|
|
6
|
+
* supporting five actions: list-servers, list-tools, list-tags, get-tool, and call-tool. It wraps
|
|
7
7
|
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
8
8
|
*
|
|
9
9
|
* ## Command Format
|
|
@@ -21,6 +21,7 @@ import { Command } from 'commander';
|
|
|
21
21
|
*
|
|
22
22
|
* - `list-servers` - List all connected MCP servers
|
|
23
23
|
* - `list-tools` - List all tools from the specified server
|
|
24
|
+
* - `list-tags` - List all instance tags for a specific MCP server
|
|
24
25
|
* - `get-tool` - Get complete schema for a specific tool (requires --tool)
|
|
25
26
|
* - `call-tool` - Call a tool on the specified server (requires --tool)
|
|
26
27
|
*
|
|
@@ -55,6 +56,9 @@ import { Command } from 'commander';
|
|
|
55
56
|
* # List third-party server tools
|
|
56
57
|
* mcp-hub-lite tool-use list-tools --server baidu-search
|
|
57
58
|
*
|
|
59
|
+
* # List instance tags for a server
|
|
60
|
+
* mcp-hub-lite tool-use list-tags --server chrome-devtools
|
|
61
|
+
*
|
|
58
62
|
* # Get system tool schema
|
|
59
63
|
* mcp-hub-lite tool-use get-tool --tool list_tools --server mcp-hub-lite
|
|
60
64
|
*
|
|
@@ -1 +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
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,eAAO,MAAM,cAAc,SAkNvB,CAAC"}
|
|
@@ -4,7 +4,7 @@ import { getServerStatus } from '../server.js';
|
|
|
4
4
|
* CLI command for dynamic MCP server tool operations via API.
|
|
5
5
|
*
|
|
6
6
|
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
7
|
-
* supporting
|
|
7
|
+
* supporting five actions: list-servers, list-tools, list-tags, get-tool, and call-tool. It wraps
|
|
8
8
|
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
9
9
|
*
|
|
10
10
|
* ## Command Format
|
|
@@ -22,6 +22,7 @@ import { getServerStatus } from '../server.js';
|
|
|
22
22
|
*
|
|
23
23
|
* - `list-servers` - List all connected MCP servers
|
|
24
24
|
* - `list-tools` - List all tools from the specified server
|
|
25
|
+
* - `list-tags` - List all instance tags for a specific MCP server
|
|
25
26
|
* - `get-tool` - Get complete schema for a specific tool (requires --tool)
|
|
26
27
|
* - `call-tool` - Call a tool on the specified server (requires --tool)
|
|
27
28
|
*
|
|
@@ -56,6 +57,9 @@ import { getServerStatus } from '../server.js';
|
|
|
56
57
|
* # List third-party server tools
|
|
57
58
|
* mcp-hub-lite tool-use list-tools --server baidu-search
|
|
58
59
|
*
|
|
60
|
+
* # List instance tags for a server
|
|
61
|
+
* mcp-hub-lite tool-use list-tags --server chrome-devtools
|
|
62
|
+
*
|
|
59
63
|
* # Get system tool schema
|
|
60
64
|
* mcp-hub-lite tool-use get-tool --tool list_tools --server mcp-hub-lite
|
|
61
65
|
*
|
|
@@ -93,8 +97,8 @@ import { getServerStatus } from '../server.js';
|
|
|
93
97
|
* @returns {Command} The configured mcp-tool-use command instance for registration with Commander.js
|
|
94
98
|
*/
|
|
95
99
|
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')
|
|
100
|
+
.description('Manage MCP server tools via API (list-servers, list-tools, list-tags, get-tool, call-tool)')
|
|
101
|
+
.argument('<action>', 'Action: list-servers, list-tools, list-tags, get-tool, call-tool')
|
|
98
102
|
.option('--server <serverName>', 'Server name to target (omit or empty for system tools)')
|
|
99
103
|
.option('--tool <toolName>', 'Tool name (required for get-tool and call-tool actions)')
|
|
100
104
|
.option('--args <json>', 'JSON string of tool arguments, or combined JSON with server/tool/args fields')
|
|
@@ -111,6 +115,9 @@ Examples:
|
|
|
111
115
|
# List third-party server tools
|
|
112
116
|
mcp-hub-lite tool-use list-tools --server baidu-search
|
|
113
117
|
|
|
118
|
+
# List instance tags for a server
|
|
119
|
+
mcp-hub-lite tool-use list-tags --server chrome-devtools
|
|
120
|
+
|
|
114
121
|
# Get system tool schema
|
|
115
122
|
mcp-hub-lite tool-use get-tool --tool list_tools
|
|
116
123
|
|
|
@@ -208,6 +215,22 @@ Examples:
|
|
|
208
215
|
console.log(JSON.stringify(result, null, 2));
|
|
209
216
|
break;
|
|
210
217
|
}
|
|
218
|
+
case 'list-tags': {
|
|
219
|
+
if (!effectiveServer || effectiveServer === defaultServer) {
|
|
220
|
+
effectiveServer = 'mcp-hub-lite';
|
|
221
|
+
}
|
|
222
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
223
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${effectiveServer}/tags${tagsParam}`, {
|
|
224
|
+
headers: { Accept: 'application/json' }
|
|
225
|
+
});
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
228
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
229
|
+
}
|
|
230
|
+
const result = await response.json();
|
|
231
|
+
console.log(JSON.stringify(result, null, 2));
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
211
234
|
case 'call-tool': {
|
|
212
235
|
if (!effectiveTool) {
|
|
213
236
|
console.error('Error: toolName is required for call-tool action');
|
|
@@ -242,7 +265,7 @@ Examples:
|
|
|
242
265
|
}
|
|
243
266
|
default: {
|
|
244
267
|
console.error(`Unknown action: ${action}`);
|
|
245
|
-
console.error('Valid actions: list-servers, list-tools, get-tool, call-tool');
|
|
268
|
+
console.error('Valid actions: list-servers, list-tools, list-tags, get-tool, call-tool');
|
|
246
269
|
process.exit(1);
|
|
247
270
|
}
|
|
248
271
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../src/cli/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,iBAO5C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0CjF;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../src/cli/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,iBAO5C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0CjF;AAoED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW;;;;;;;;;;;;;;;;;;;KAUhC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,GAAG,KAAK,GAAG,iBAAiB,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,yBAAyB,EAAE,QAAQ,GAAG,aAAa,GAAG,kBAAkB,CAAC;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CA0Df;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkB1E"}
|
|
@@ -173,6 +173,8 @@ async function fetchRuntimeStatus(host, port) {
|
|
|
173
173
|
const result = statusData.map((item) => ({
|
|
174
174
|
name: item.name,
|
|
175
175
|
type: item.type,
|
|
176
|
+
displayName: item.displayName,
|
|
177
|
+
tags: item.tags,
|
|
176
178
|
connected: item.status.connected,
|
|
177
179
|
toolsCount: item.status.toolsCount,
|
|
178
180
|
resourcesCount: item.status.resourcesCount,
|
|
@@ -32,17 +32,21 @@ export interface UpdateServerDescriptionParams {
|
|
|
32
32
|
serverName: string;
|
|
33
33
|
description: string;
|
|
34
34
|
}
|
|
35
|
-
export
|
|
35
|
+
export interface ListTagsParams {
|
|
36
|
+
serverName: string;
|
|
37
|
+
}
|
|
38
|
+
export type SystemToolArgs = ListServersParams | ListToolsInServerParams | GetToolParams | CallToolParams | UpdateServerDescriptionParams | ListTagsParams;
|
|
36
39
|
export declare const LIST_SERVERS_TOOL = "list_servers";
|
|
37
40
|
export declare const LIST_TOOLS_TOOL = "list_tools";
|
|
38
41
|
export declare const GET_TOOL_TOOL = "get_tool";
|
|
39
42
|
export declare const CALL_TOOL_TOOL = "call_tool";
|
|
40
43
|
export declare const UPDATE_SERVER_DESCRIPTION_TOOL = "update_server_description";
|
|
44
|
+
export declare const LIST_TAGS_TOOL = "list_tags";
|
|
41
45
|
/**
|
|
42
46
|
* List of all system tool names
|
|
43
47
|
* This array is used to identify system tools across the application
|
|
44
48
|
*/
|
|
45
|
-
export declare const SYSTEM_TOOL_NAMES: readonly ["list_servers", "list_tools", "get_tool", "call_tool", "update_server_description"];
|
|
49
|
+
export declare const SYSTEM_TOOL_NAMES: readonly ["list_servers", "list_tools", "get_tool", "call_tool", "update_server_description", "list_tags"];
|
|
46
50
|
/**
|
|
47
51
|
* Type definition for system tool names
|
|
48
52
|
* 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;
|
|
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;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,MAAM,cAAc,GACtB,iBAAiB,GACjB,uBAAuB,GACvB,aAAa,GACb,cAAc,GACd,6BAA6B,GAC7B,cAAc,CAAC;AAGnB,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;AAC1E,eAAO,MAAM,cAAc,cAAc,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,iBAAiB,4GAOpB,CAAC;AAEX;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGhE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAC"}
|
|
@@ -8,6 +8,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';
|
|
11
|
+
export const LIST_TAGS_TOOL = 'list_tags';
|
|
11
12
|
/**
|
|
12
13
|
* List of all system tool names
|
|
13
14
|
* This array is used to identify system tools across the application
|
|
@@ -17,7 +18,8 @@ export const SYSTEM_TOOL_NAMES = [
|
|
|
17
18
|
LIST_TOOLS_TOOL,
|
|
18
19
|
GET_TOOL_TOOL,
|
|
19
20
|
CALL_TOOL_TOOL,
|
|
20
|
-
UPDATE_SERVER_DESCRIPTION_TOOL
|
|
21
|
+
UPDATE_SERVER_DESCRIPTION_TOOL,
|
|
22
|
+
LIST_TAGS_TOOL
|
|
21
23
|
];
|
|
22
24
|
// Individual gateway server name constant
|
|
23
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-tools-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/system-tools-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"system-tools-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/system-tools-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmNnE"}
|
|
@@ -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_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, LIST_TAGS_TOOL } from '../../../models/system-tools.constants.js';
|
|
10
10
|
/**
|
|
11
11
|
* Register system tools handlers on the MCP server.
|
|
12
12
|
*
|
|
@@ -192,4 +192,31 @@ export function registerSystemToolsHandlers(server) {
|
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
});
|
|
195
|
+
// List tags
|
|
196
|
+
const ListTagsRequestSchema = z.object({
|
|
197
|
+
method: z.literal(LIST_TAGS_TOOL),
|
|
198
|
+
params: z.object({
|
|
199
|
+
serverName: z.string()
|
|
200
|
+
}),
|
|
201
|
+
id: z.union([z.string(), z.number()]),
|
|
202
|
+
jsonrpc: z.literal('2.0')
|
|
203
|
+
});
|
|
204
|
+
server.server.setRequestHandler(ListTagsRequestSchema, async (request) => {
|
|
205
|
+
try {
|
|
206
|
+
const result = await hubToolsService.listTags(request.params);
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
logger.error(`List tags error:`, error, LOG_MODULES.SYSTEM_TOOLS_HANDLER);
|
|
211
|
+
if (error instanceof McpError) {
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
else if (error instanceof Error) {
|
|
215
|
+
throw new McpError(-32802, error.message);
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
throw new McpError(-32802, String(error));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
195
222
|
}
|
|
@@ -43,7 +43,7 @@ export class InstanceSelector {
|
|
|
43
43
|
static selectInstance(serverName, serverConfig, requestOptions) {
|
|
44
44
|
const { instances } = serverConfig;
|
|
45
45
|
const instanceSelectionStrategy = serverConfig.template.instanceSelectionStrategy || InstanceSelectionStrategy.RANDOM;
|
|
46
|
-
// Filter enabled instances
|
|
46
|
+
// Filter instances - only use enabled instances
|
|
47
47
|
const enabledInstances = instances.filter((instance) => instance.enabled !== false);
|
|
48
48
|
if (enabledInstances.length === 0) {
|
|
49
49
|
return undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-generator.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/resource-generator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAUlE;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AA6ID;;GAEG;AACH,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,qBAAqB,uEACoC,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,IAAI,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"resource-generator.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/resource-generator.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAUlE;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AA6ID;;GAEG;AACH,eAAO,MAAM,aAAa,oBAAoB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,cAAc,2BAA2B,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,qBAAqB,uEACoC,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,IAAI,QAAQ,EAAE,CAuFrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,GAAG,QAAQ,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC,CAyGzD"}
|
|
@@ -178,36 +178,55 @@ export function generateDynamicResources() {
|
|
|
178
178
|
if (!hasValidId(server)) {
|
|
179
179
|
continue;
|
|
180
180
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
let hasAnyConnectedInstance = false;
|
|
182
|
+
let firstConnectedInstanceIndex;
|
|
183
|
+
// First pass: check which instances are connected (consistent with /web/mcp/status API)
|
|
184
|
+
for (const instance of server.config.instances) {
|
|
185
|
+
const idx = instance.index;
|
|
186
|
+
if (idx === undefined) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const instanceStatus = mcpConnectionManager.getStatus(server.name, idx);
|
|
190
|
+
if (instanceStatus?.connected) {
|
|
191
|
+
hasAnyConnectedInstance = true;
|
|
192
|
+
if (firstConnectedInstanceIndex === undefined) {
|
|
193
|
+
firstConnectedInstanceIndex = idx;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Skip server if no instances are connected
|
|
198
|
+
if (!hasAnyConnectedInstance) {
|
|
184
199
|
continue;
|
|
185
200
|
}
|
|
186
|
-
//
|
|
201
|
+
// Second pass: generate resources for each connected instance
|
|
187
202
|
for (const instance of server.config.instances) {
|
|
188
|
-
|
|
203
|
+
const idx = instance.index;
|
|
204
|
+
if (idx === undefined) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const instanceStatus = mcpConnectionManager.getStatus(server.name, idx);
|
|
208
|
+
if (!instanceStatus?.connected) {
|
|
189
209
|
continue;
|
|
190
210
|
}
|
|
191
|
-
|
|
192
|
-
//
|
|
193
|
-
if (
|
|
211
|
+
// Server metadata resource (one per server, using first connected instance's index)
|
|
212
|
+
// Only generate once when we hit the first connected instance
|
|
213
|
+
if (idx === firstConnectedInstanceIndex) {
|
|
194
214
|
resources.push({
|
|
195
215
|
uri: `hub://servers/${server.name}`,
|
|
196
216
|
name: `Server: ${server.name}`,
|
|
197
217
|
description: getServerDescription(server.config, server.name),
|
|
198
218
|
mimeType: 'application/json',
|
|
199
219
|
serverName: server.name,
|
|
200
|
-
serverIndex:
|
|
220
|
+
serverIndex: idx
|
|
201
221
|
});
|
|
202
222
|
}
|
|
203
223
|
// Get MCP native resources and map to hub format
|
|
204
|
-
const
|
|
205
|
-
const mcpResources = mcpConnectionManager.getResources(server.name, instanceIdx);
|
|
224
|
+
const mcpResources = mcpConnectionManager.getResources(server.name, idx);
|
|
206
225
|
for (const res of mcpResources) {
|
|
207
226
|
// Format: Resource: {ServerName} - {Index}: {Native Name}
|
|
208
|
-
const displayName = `Resource:${server.name} - ${
|
|
227
|
+
const displayName = `Resource:${server.name} - ${idx}:${res.name}`;
|
|
209
228
|
resources.push({
|
|
210
|
-
uri: mapMcpUriToHub(server.name,
|
|
229
|
+
uri: mapMcpUriToHub(server.name, idx, res.uri),
|
|
211
230
|
name: displayName,
|
|
212
231
|
description: res.description,
|
|
213
232
|
mimeType: res.mimeType
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { RequestOptions, ServerInstanceInfo, ValidServer } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Gets the description for a server, using
|
|
3
|
+
* Gets the description for a server, using the server name as default if none is provided.
|
|
4
4
|
*
|
|
5
5
|
* @param serverConfig - Server configuration object (may contain description in template)
|
|
6
6
|
* @param serverName - Name of the server
|
|
7
|
-
* @returns The server description or
|
|
7
|
+
* @returns The server description or the server name with usage note if no description is configured
|
|
8
8
|
*/
|
|
9
9
|
export declare function getServerDescription(serverConfig: {
|
|
10
10
|
template?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-selector.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/server-selector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,EACjE,UAAU,EAAE,MAAM,GACjB,MAAM,
|
|
1
|
+
{"version":3,"file":"server-selector.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/server-selector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,EACjE,UAAU,EAAE,MAAM,GACjB,MAAM,CAKR;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,WAAW,CAMjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,cAAc,EAC/B,UAAU,GAAE,OAAc,GACzB,kBAAkB,GAAG,SAAS,CA8ChC"}
|
|
@@ -3,14 +3,15 @@ import { InstanceSelector, TagMatchUniqueError } from './instance-selector.js';
|
|
|
3
3
|
import { logger } from '../../utils/logger.js';
|
|
4
4
|
import { LOG_MODULES } from '../../utils/logger/log-modules.js';
|
|
5
5
|
/**
|
|
6
|
-
* Gets the description for a server, using
|
|
6
|
+
* Gets the description for a server, using the server name as default if none is provided.
|
|
7
7
|
*
|
|
8
8
|
* @param serverConfig - Server configuration object (may contain description in template)
|
|
9
9
|
* @param serverName - Name of the server
|
|
10
|
-
* @returns The server description or
|
|
10
|
+
* @returns The server description or the server name with usage note if no description is configured
|
|
11
11
|
*/
|
|
12
12
|
export function getServerDescription(serverConfig, serverName) {
|
|
13
|
-
return serverConfig?.template?.description ||
|
|
13
|
+
return (serverConfig?.template?.description ||
|
|
14
|
+
`${serverName} (You can check the tool list to understand its capabilities and update the description.)`);
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
17
|
* Type guard to validate that a server object has valid name and configuration.
|
|
@@ -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;
|
|
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;AAW/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,CAiKvD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
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';
|
|
1
|
+
import { SYSTEM_TOOL_NAMES, LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL, LIST_TAGS_TOOL } from '../../models/system-tools.constants.js';
|
|
2
2
|
/**
|
|
3
3
|
* Retrieves the complete list of system tools provided by this service.
|
|
4
4
|
*
|
|
@@ -91,7 +91,7 @@ export function getSystemTools() {
|
|
|
91
91
|
required: ['serverName', 'toolName']
|
|
92
92
|
},
|
|
93
93
|
annotations: {
|
|
94
|
-
title: 'Get Tool
|
|
94
|
+
title: 'Get Tool Schema',
|
|
95
95
|
readOnlyHint: true,
|
|
96
96
|
destructiveHint: false,
|
|
97
97
|
idempotentHint: true,
|
|
@@ -103,7 +103,7 @@ export function getSystemTools() {
|
|
|
103
103
|
systemTools.push({
|
|
104
104
|
name: toolName,
|
|
105
105
|
description: 'Call a specific tool from an external MCP server. ' +
|
|
106
|
-
'System tools (list_servers, list_tools, get_tool, update_server_description) ' +
|
|
106
|
+
'System tools (list_servers, list_tools, get_tool, list_tags, update_server_description) ' +
|
|
107
107
|
'must be called directly via tools/call, not through this tool.',
|
|
108
108
|
inputSchema: {
|
|
109
109
|
type: 'object',
|
|
@@ -154,6 +154,26 @@ export function getSystemTools() {
|
|
|
154
154
|
}
|
|
155
155
|
});
|
|
156
156
|
break;
|
|
157
|
+
case LIST_TAGS_TOOL:
|
|
158
|
+
systemTools.push({
|
|
159
|
+
name: toolName,
|
|
160
|
+
description: 'List all instance tags for a specific MCP server',
|
|
161
|
+
inputSchema: {
|
|
162
|
+
type: 'object',
|
|
163
|
+
properties: {
|
|
164
|
+
serverName: { type: 'string', description: 'Name of the MCP server' }
|
|
165
|
+
},
|
|
166
|
+
required: ['serverName']
|
|
167
|
+
},
|
|
168
|
+
annotations: {
|
|
169
|
+
title: 'List Instance Tags',
|
|
170
|
+
readOnlyHint: true,
|
|
171
|
+
destructiveHint: false,
|
|
172
|
+
idempotentHint: true,
|
|
173
|
+
openWorldHint: false
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
break;
|
|
157
177
|
default:
|
|
158
178
|
// This should never happen due to TypeScript type checking
|
|
159
179
|
throw new Error(`Unknown system tool: ${toolName}`);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Tool, ToolSummary } from '../../shared/models/tool.model.js';
|
|
2
2
|
import type { Resource } from '../../shared/models/resource.model.js';
|
|
3
|
-
import { LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL } from '../models/system-tools.constants.js';
|
|
4
|
-
import type { SystemToolName, ListServersParams, ListToolsInServerParams, GetToolParams, CallToolParams, UpdateServerDescriptionParams } from '../models/system-tools.constants.js';
|
|
3
|
+
import { LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL, LIST_TAGS_TOOL } from '../models/system-tools.constants.js';
|
|
4
|
+
import type { SystemToolName, ListServersParams, ListToolsInServerParams, GetToolParams, CallToolParams, UpdateServerDescriptionParams, ListTagsParams } from '../models/system-tools.constants.js';
|
|
5
5
|
/**
|
|
6
6
|
* Central service for managing system tools and MCP server interactions in the MCP Hub Lite gateway.
|
|
7
7
|
*
|
|
@@ -51,10 +51,6 @@ import type { SystemToolName, ListServersParams, ListToolsInServerParams, GetToo
|
|
|
51
51
|
* ```
|
|
52
52
|
*/
|
|
53
53
|
export declare class HubToolsService {
|
|
54
|
-
/**
|
|
55
|
-
* Cached dynamic resource list to avoid regenerating on every request
|
|
56
|
-
*/
|
|
57
|
-
private generatedResourcesCache;
|
|
58
54
|
constructor();
|
|
59
55
|
/**
|
|
60
56
|
* Retrieves the complete list of system tools provided by this service.
|
|
@@ -122,6 +118,25 @@ export declare class HubToolsService {
|
|
|
122
118
|
serverName: string;
|
|
123
119
|
description: string;
|
|
124
120
|
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Lists all instance tags for a specific MCP server.
|
|
123
|
+
*
|
|
124
|
+
* This method retrieves all instances of the specified server and returns their tags,
|
|
125
|
+
* useful for understanding which instances are available and how to select them
|
|
126
|
+
* when using tag-match-unique instance selection strategy.
|
|
127
|
+
*
|
|
128
|
+
* @param {ListTagsParams} args - Server name
|
|
129
|
+
* @returns {Promise<{ serverName: string; instances: Array<{ index: number; id: string; tags: Record<string, string> }> }>} Instance tags information
|
|
130
|
+
* @throws {Error} If the specified server is not found
|
|
131
|
+
*/
|
|
132
|
+
listTags(args: ListTagsParams): Promise<{
|
|
133
|
+
serverName: string;
|
|
134
|
+
instances: Array<{
|
|
135
|
+
index: number;
|
|
136
|
+
id: string;
|
|
137
|
+
tags: Record<string, string>;
|
|
138
|
+
}>;
|
|
139
|
+
}>;
|
|
125
140
|
/**
|
|
126
141
|
* Calls a specific system tool directly with type-safe conditional return types.
|
|
127
142
|
*
|
|
@@ -134,13 +149,20 @@ export declare class HubToolsService {
|
|
|
134
149
|
* @returns {Promise<ConditionalReturnType>} Tool execution result with accurate type safety matching actual method return types
|
|
135
150
|
* @throws {Error} If the system tool is not found or execution fails
|
|
136
151
|
*/
|
|
137
|
-
callSystemTool<T extends SystemToolName>(toolName: T, toolArgs: T extends typeof LIST_SERVERS_TOOL ? ListServersParams : T extends typeof LIST_TOOLS_TOOL ? ListToolsInServerParams : T extends typeof GET_TOOL_TOOL ? GetToolParams : T extends typeof CALL_TOOL_TOOL ? CallToolParams : T extends typeof UPDATE_SERVER_DESCRIPTION_TOOL ? UpdateServerDescriptionParams : never): Promise<T extends typeof LIST_SERVERS_TOOL ? Record<string, string> : T extends typeof LIST_TOOLS_TOOL ? {
|
|
152
|
+
callSystemTool<T extends SystemToolName>(toolName: T, toolArgs: T extends typeof LIST_SERVERS_TOOL ? ListServersParams : T extends typeof LIST_TOOLS_TOOL ? ListToolsInServerParams : T extends typeof GET_TOOL_TOOL ? GetToolParams : T extends typeof CALL_TOOL_TOOL ? CallToolParams : T extends typeof UPDATE_SERVER_DESCRIPTION_TOOL ? UpdateServerDescriptionParams : T extends typeof LIST_TAGS_TOOL ? ListTagsParams : never): Promise<T extends typeof LIST_SERVERS_TOOL ? Record<string, string> : T extends typeof LIST_TOOLS_TOOL ? {
|
|
138
153
|
serverName: string;
|
|
139
154
|
tools: ToolSummary[];
|
|
140
155
|
} : T extends typeof GET_TOOL_TOOL ? Tool | undefined : T extends typeof CALL_TOOL_TOOL ? unknown : T extends typeof UPDATE_SERVER_DESCRIPTION_TOOL ? {
|
|
141
156
|
success: boolean;
|
|
142
157
|
serverName: string;
|
|
143
158
|
description: string;
|
|
159
|
+
} : T extends typeof LIST_TAGS_TOOL ? {
|
|
160
|
+
serverName: string;
|
|
161
|
+
instances: Array<{
|
|
162
|
+
index: number;
|
|
163
|
+
id: string;
|
|
164
|
+
tags: Record<string, string>;
|
|
165
|
+
}>;
|
|
144
166
|
} : never>;
|
|
145
167
|
/**
|
|
146
168
|
* Calls a specific tool from a specific MCP server with comprehensive event tracking.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hub-tools.service.d.ts","sourceRoot":"","sources":["../../../../src/services/hub-tools.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAOjE,OAAO,EAEL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,cAAc,EACd,8BAA8B,
|
|
1
|
+
{"version":3,"file":"hub-tools.service.d.ts","sourceRoot":"","sources":["../../../../src/services/hub-tools.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,9 +6,11 @@ import { logger, LOG_MODULES } from '../utils/logger.js';
|
|
|
6
6
|
import { stringifyForLogging } from '../utils/json-utils.js';
|
|
7
7
|
import { normalizeToolName } from '../utils/name-converter.js';
|
|
8
8
|
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
-
import { MCP_HUB_LITE_SERVER, LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL, SYSTEM_TOOL_NAMES } from '../models/system-tools.constants.js';
|
|
9
|
+
import { MCP_HUB_LITE_SERVER, LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL, LIST_TAGS_TOOL, SYSTEM_TOOL_NAMES } from '../models/system-tools.constants.js';
|
|
10
10
|
import { ToolArgsParser } from '../utils/tool-args-parser.js';
|
|
11
11
|
import { hasValidId, selectBestInstance, getServerDescription, getSystemTools, generateDynamicResources, readResource as readResourceUtil } from './hub-tools/index.js';
|
|
12
|
+
import { InstanceSelector } from './hub-tools/instance-selector.js';
|
|
13
|
+
import { InstanceSelectionStrategy } from '../models/server.model.js';
|
|
12
14
|
/**
|
|
13
15
|
* Central service for managing system tools and MCP server interactions in the MCP Hub Lite gateway.
|
|
14
16
|
*
|
|
@@ -58,27 +60,9 @@ import { hasValidId, selectBestInstance, getServerDescription, getSystemTools, g
|
|
|
58
60
|
* ```
|
|
59
61
|
*/
|
|
60
62
|
export class HubToolsService {
|
|
61
|
-
|
|
62
|
-
* Cached dynamic resource list to avoid regenerating on every request
|
|
63
|
-
*/
|
|
64
|
-
generatedResourcesCache = null;
|
|
63
|
+
// Cache removed - listResources() now calls generateDynamicResources() directly
|
|
65
64
|
constructor() {
|
|
66
|
-
//
|
|
67
|
-
eventBus.subscribe(EventTypes.SERVER_STATUS_CHANGE, () => {
|
|
68
|
-
this.generatedResourcesCache = null;
|
|
69
|
-
});
|
|
70
|
-
eventBus.subscribe(EventTypes.SERVER_CONNECTED, () => {
|
|
71
|
-
this.generatedResourcesCache = null;
|
|
72
|
-
});
|
|
73
|
-
eventBus.subscribe(EventTypes.SERVER_DISCONNECTED, () => {
|
|
74
|
-
this.generatedResourcesCache = null;
|
|
75
|
-
});
|
|
76
|
-
eventBus.subscribe(EventTypes.RESOURCES_UPDATED, () => {
|
|
77
|
-
this.generatedResourcesCache = null;
|
|
78
|
-
});
|
|
79
|
-
eventBus.subscribe(EventTypes.TOOLS_UPDATED, () => {
|
|
80
|
-
this.generatedResourcesCache = null;
|
|
81
|
-
});
|
|
65
|
+
// No cache-related initialization needed
|
|
82
66
|
}
|
|
83
67
|
/**
|
|
84
68
|
* Retrieves the complete list of system tools provided by this service.
|
|
@@ -136,6 +120,9 @@ export class HubToolsService {
|
|
|
136
120
|
* @throws {Error} If the specified server is not found or not connected
|
|
137
121
|
*/
|
|
138
122
|
async listToolsInServer(args) {
|
|
123
|
+
if (!args.serverName) {
|
|
124
|
+
throw new Error('serverName is required');
|
|
125
|
+
}
|
|
139
126
|
// Handle MCP Hub Lite server (return system tools list)
|
|
140
127
|
if (typeof args.serverName === 'string' && args.serverName === MCP_HUB_LITE_SERVER) {
|
|
141
128
|
// Generate tool list using the same logic as tools/list
|
|
@@ -237,6 +224,33 @@ export class HubToolsService {
|
|
|
237
224
|
description
|
|
238
225
|
};
|
|
239
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Lists all instance tags for a specific MCP server.
|
|
229
|
+
*
|
|
230
|
+
* This method retrieves all instances of the specified server and returns their tags,
|
|
231
|
+
* useful for understanding which instances are available and how to select them
|
|
232
|
+
* when using tag-match-unique instance selection strategy.
|
|
233
|
+
*
|
|
234
|
+
* @param {ListTagsParams} args - Server name
|
|
235
|
+
* @returns {Promise<{ serverName: string; instances: Array<{ index: number; id: string; tags: Record<string, string> }> }>} Instance tags information
|
|
236
|
+
* @throws {Error} If the specified server is not found
|
|
237
|
+
*/
|
|
238
|
+
async listTags(args) {
|
|
239
|
+
const serverConfig = hubManager.getServerByName(args.serverName);
|
|
240
|
+
if (!serverConfig) {
|
|
241
|
+
throw new Error(`Server not found: ${args.serverName}`);
|
|
242
|
+
}
|
|
243
|
+
const instances = hubManager.getServerInstancesByName(args.serverName);
|
|
244
|
+
const instanceTags = instances.map((instance) => ({
|
|
245
|
+
index: instance.index ?? 0,
|
|
246
|
+
id: instance.id || '',
|
|
247
|
+
tags: instance.tags || {}
|
|
248
|
+
}));
|
|
249
|
+
return {
|
|
250
|
+
serverName: args.serverName,
|
|
251
|
+
instances: instanceTags
|
|
252
|
+
};
|
|
253
|
+
}
|
|
240
254
|
/**
|
|
241
255
|
* Calls a specific system tool directly with type-safe conditional return types.
|
|
242
256
|
*
|
|
@@ -281,6 +295,10 @@ export class HubToolsService {
|
|
|
281
295
|
result = await this.updateServerDescription(toolArgs);
|
|
282
296
|
break;
|
|
283
297
|
}
|
|
298
|
+
case LIST_TAGS_TOOL: {
|
|
299
|
+
result = await this.listTags(toolArgs);
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
284
302
|
default:
|
|
285
303
|
throw new Error(`System tool "${toolName}" not found`);
|
|
286
304
|
}
|
|
@@ -317,14 +335,17 @@ export class HubToolsService {
|
|
|
317
335
|
serverName = parsedTool.serverName;
|
|
318
336
|
toolName = parsedTool.toolName;
|
|
319
337
|
}
|
|
320
|
-
//
|
|
321
|
-
if (!serverName
|
|
322
|
-
serverName
|
|
338
|
+
// Validate serverName is required
|
|
339
|
+
if (!serverName) {
|
|
340
|
+
throw new Error('serverName is required');
|
|
323
341
|
}
|
|
342
|
+
// Handle MCP Hub Lite server (system tool call or find tool in all servers)
|
|
324
343
|
if (typeof serverName === 'string' && serverName === MCP_HUB_LITE_SERVER) {
|
|
325
|
-
// System tools cannot be called via call_tool - they must be called directly
|
|
344
|
+
// System tools (except call_tool) cannot be called via call_tool - they must be called directly
|
|
345
|
+
// call_tool is the gateway tool for calling external tools, so it should be allowed
|
|
326
346
|
if (Array.isArray(SYSTEM_TOOL_NAMES) &&
|
|
327
|
-
SYSTEM_TOOL_NAMES.includes(toolName)
|
|
347
|
+
SYSTEM_TOOL_NAMES.includes(toolName) &&
|
|
348
|
+
toolName !== CALL_TOOL_TOOL) {
|
|
328
349
|
throw new McpError(-32801, `System tools cannot be called via 'call_tool'. Use 'tools/call' with the system tool name directly. ` +
|
|
329
350
|
`Example: use 'list_servers' directly instead of call_tool(serverName: "mcp-hub-lite", toolName: "list_servers").`);
|
|
330
351
|
}
|
|
@@ -377,7 +398,33 @@ export class HubToolsService {
|
|
|
377
398
|
// Server not found in hubManager, try direct call by name through mcpConnectionManager
|
|
378
399
|
logger.debug(`Server not found in hubManager, trying direct call by name: ${serverName}`, LOG_MODULES.HUB_TOOLS);
|
|
379
400
|
// Use selectBestInstance with non-strict mode to find an available instance
|
|
380
|
-
|
|
401
|
+
let fallbackServerInfo = selectBestInstance(serverName, undefined, false);
|
|
402
|
+
// If selectBestInstance returns undefined (e.g., TAG_MATCH_UNIQUE strategy without tags),
|
|
403
|
+
// fall back to directly selecting an enabled instance with RANDOM strategy
|
|
404
|
+
if (!fallbackServerInfo) {
|
|
405
|
+
logger.debug(`selectBestInstance returned undefined for ${serverName}, trying direct instance selection with RANDOM strategy`, LOG_MODULES.HUB_TOOLS);
|
|
406
|
+
const serverConfig = hubManager.getServerByName(serverName);
|
|
407
|
+
if (serverConfig && serverConfig.instances.length > 0) {
|
|
408
|
+
const enabledInstances = serverConfig.instances.filter((instance) => instance.enabled !== false);
|
|
409
|
+
if (enabledInstances.length > 0) {
|
|
410
|
+
// Use RANDOM strategy regardless of server's configured strategy
|
|
411
|
+
const selectedInstance = InstanceSelector.selectInstance(serverName, {
|
|
412
|
+
...serverConfig,
|
|
413
|
+
template: {
|
|
414
|
+
...serverConfig.template,
|
|
415
|
+
instanceSelectionStrategy: InstanceSelectionStrategy.RANDOM
|
|
416
|
+
}
|
|
417
|
+
}, undefined);
|
|
418
|
+
if (selectedInstance) {
|
|
419
|
+
fallbackServerInfo = {
|
|
420
|
+
name: serverName,
|
|
421
|
+
config: serverConfig,
|
|
422
|
+
instance: selectedInstance
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
381
428
|
if (!fallbackServerInfo) {
|
|
382
429
|
logger.error(`Server not found: ${serverName}`, LOG_MODULES.HUB_TOOLS);
|
|
383
430
|
throw new Error(`Server not found: ${serverName}`);
|
|
@@ -525,12 +572,8 @@ export class HubToolsService {
|
|
|
525
572
|
* @returns {Promise<Resource[]>} Array of MCP resource objects representing Hub resources
|
|
526
573
|
*/
|
|
527
574
|
async listResources() {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
const resources = generateDynamicResources();
|
|
532
|
-
this.generatedResourcesCache = resources;
|
|
533
|
-
return resources;
|
|
575
|
+
// Always regenerate to ensure fresh data based on runtime status
|
|
576
|
+
return generateDynamicResources();
|
|
534
577
|
}
|
|
535
578
|
/**
|
|
536
579
|
* Reads content from a specific Hub resource URI.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-tool-handler.d.ts","sourceRoot":"","sources":["../../../../src/services/system-tool-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"system-tool-handler.d.ts","sourceRoot":"","sources":["../../../../src/services/system-tool-handler.ts"],"names":[],"mappings":"AAqBA;;GAEG;AACH,qBAAa,iBAAiB;IAC5B;;OAEG;WACU,oBAAoB,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC;CA2EpB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { hubToolsService } from './hub-tools.service.js';
|
|
2
2
|
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
3
3
|
import { logger, LOG_MODULES } from '../utils/logger.js';
|
|
4
|
-
import { LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL,
|
|
4
|
+
import { LIST_SERVERS_TOOL, LIST_TOOLS_TOOL, GET_TOOL_TOOL, CALL_TOOL_TOOL, UPDATE_SERVER_DESCRIPTION_TOOL, LIST_TAGS_TOOL } from '../models/system-tools.constants.js';
|
|
5
5
|
import { stringifyForLogging } from '../utils/json-utils.js';
|
|
6
6
|
/**
|
|
7
7
|
* Unified system tool call handler
|
|
@@ -20,31 +20,44 @@ export class SystemToolHandler {
|
|
|
20
20
|
break;
|
|
21
21
|
case LIST_TOOLS_TOOL: {
|
|
22
22
|
const listToolsArgs = toolArgs;
|
|
23
|
+
if (!listToolsArgs.serverName) {
|
|
24
|
+
throw new McpError(-32802, 'serverName is required');
|
|
25
|
+
}
|
|
23
26
|
result = await hubToolsService.listToolsInServer(listToolsArgs);
|
|
24
27
|
break;
|
|
25
28
|
}
|
|
26
29
|
case GET_TOOL_TOOL: {
|
|
27
30
|
const getToolArgs = toolArgs;
|
|
31
|
+
if (!getToolArgs.serverName) {
|
|
32
|
+
throw new McpError(-32802, 'serverName is required');
|
|
33
|
+
}
|
|
28
34
|
result = await hubToolsService.getTool(getToolArgs);
|
|
29
35
|
break;
|
|
30
36
|
}
|
|
31
37
|
case CALL_TOOL_TOOL: {
|
|
32
38
|
const callToolArgs = toolArgs;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
serverName = MCP_HUB_LITE_SERVER;
|
|
39
|
+
if (!callToolArgs.serverName) {
|
|
40
|
+
throw new McpError(-32802, 'serverName is required');
|
|
36
41
|
}
|
|
37
|
-
result = await hubToolsService.callTool(
|
|
38
|
-
...callToolArgs,
|
|
39
|
-
serverName
|
|
40
|
-
});
|
|
42
|
+
result = await hubToolsService.callTool(callToolArgs);
|
|
41
43
|
break;
|
|
42
44
|
}
|
|
43
45
|
case UPDATE_SERVER_DESCRIPTION_TOOL: {
|
|
44
46
|
const updateDescArgs = toolArgs;
|
|
47
|
+
if (!updateDescArgs.serverName) {
|
|
48
|
+
throw new McpError(-32802, 'serverName is required');
|
|
49
|
+
}
|
|
45
50
|
result = await hubToolsService.updateServerDescription(updateDescArgs);
|
|
46
51
|
break;
|
|
47
52
|
}
|
|
53
|
+
case LIST_TAGS_TOOL: {
|
|
54
|
+
const listTagsArgs = toolArgs;
|
|
55
|
+
if (!listTagsArgs.serverName) {
|
|
56
|
+
throw new McpError(-32802, 'serverName is required');
|
|
57
|
+
}
|
|
58
|
+
result = await hubToolsService.listTags(listTagsArgs);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
48
61
|
default:
|
|
49
62
|
throw new McpError(-32801, `Unknown system tool: ${toolName}`);
|
|
50
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"name-converter.d.ts","sourceRoot":"","sources":["../../../../src/utils/name-converter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"name-converter.d.ts","sourceRoot":"","sources":["../../../../src/utils/name-converter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAe1D"}
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* normalizeToolName('chat_completions') // returns 'chat_completions'
|
|
15
15
|
*/
|
|
16
16
|
export function normalizeToolName(toolName) {
|
|
17
|
+
if (!toolName)
|
|
18
|
+
return '';
|
|
17
19
|
return (toolName
|
|
18
20
|
// Insert underscore before uppercase letters (for camelCase handling)
|
|
19
21
|
// e.g., 'chatCompletions' -> 'chat_Completions'
|
|
@@ -95,7 +95,7 @@ describe('HubToolsService', () => {
|
|
|
95
95
|
// Assert
|
|
96
96
|
expect(servers).toEqual({
|
|
97
97
|
'Test Server 1': 'File system operations',
|
|
98
|
-
'Test Server 2': '
|
|
98
|
+
'Test Server 2': 'Test Server 2 (You can check the tool list to understand its capabilities and update the description.)'
|
|
99
99
|
});
|
|
100
100
|
expect(hubManager.getAllServers).toHaveBeenCalledTimes(1);
|
|
101
101
|
});
|
|
@@ -150,7 +150,7 @@ describe('HubToolsService', () => {
|
|
|
150
150
|
const servers = await hubToolsService.listServers();
|
|
151
151
|
// Assert
|
|
152
152
|
expect(servers).toEqual({
|
|
153
|
-
server1: '
|
|
153
|
+
server1: 'server1 (You can check the tool list to understand its capabilities and update the description.)'
|
|
154
154
|
});
|
|
155
155
|
});
|
|
156
156
|
it('should use provided description when available', async () => {
|
|
@@ -610,14 +610,15 @@ describe('HubToolsService', () => {
|
|
|
610
610
|
// Assert - System tools under mcp-hub-lite
|
|
611
611
|
expect(allTools).toHaveProperty('mcp-hub-lite');
|
|
612
612
|
expect(Array.isArray(allTools['mcp-hub-lite'].tools)).toBe(true);
|
|
613
|
-
// Assert system tools - should have
|
|
613
|
+
// Assert system tools - should have 6 tools now
|
|
614
614
|
const systemToolNames = allTools['mcp-hub-lite'].tools.map((t) => t.name);
|
|
615
615
|
expect(systemToolNames).toContain('list_servers');
|
|
616
616
|
expect(systemToolNames).toContain('list_tools');
|
|
617
617
|
expect(systemToolNames).toContain('get_tool');
|
|
618
618
|
expect(systemToolNames).toContain('call_tool');
|
|
619
619
|
expect(systemToolNames).toContain('update_server_description');
|
|
620
|
-
expect(systemToolNames).
|
|
620
|
+
expect(systemToolNames).toContain('list_tags');
|
|
621
|
+
expect(systemToolNames).toHaveLength(6);
|
|
621
622
|
// Assert server tools - should have only name and description
|
|
622
623
|
expect(allTools['Server 1'].tools).toEqual(expectedToolSummariesServer1);
|
|
623
624
|
expect(allTools['Server 2'].tools).toEqual(expectedToolSummariesServer2);
|
|
@@ -783,7 +784,7 @@ describe('HubToolsService', () => {
|
|
|
783
784
|
lastHeartbeat: mockInstance.lastHeartbeat,
|
|
784
785
|
// @ts-expect-error - Accessing extra fields on mock
|
|
785
786
|
uptime: mockInstance.uptime,
|
|
786
|
-
description:
|
|
787
|
+
description: `${serverName} (You can check the tool list to understand its capabilities and update the description.)`
|
|
787
788
|
});
|
|
788
789
|
});
|
|
789
790
|
it('should return tools list for tools URI', async () => {
|