@loop_ouroboros/mcp-hub-lite 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/{HomeView-Bu2joUvW.js → HomeView-BBwvy1oj.js} +1 -1
- package/dist/client/assets/{ResourceDetailView-BvrhDCD1.js → ResourceDetailView-CZ2aB73w.js} +1 -1
- package/dist/client/assets/{ResourcesView-LjqioF_s.js → ResourcesView-CN1NlhWs.js} +1 -1
- package/dist/client/assets/{ServerDashboard-FhHJFvUi.js → ServerDashboard-k652Vw4Z.js} +1 -1
- package/dist/client/assets/{ServerDetail-BKV-M4qT.js → ServerDetail-BLQ-a4cO.js} +1 -1
- package/dist/client/assets/{ServerListView-BXgtDyt3.js → ServerListView-BHrsFD5i.js} +4 -4
- package/dist/client/assets/{ServerStatusTags.vue_vue_type_script_setup_true_lang-D-ooYNdN.js → ServerStatusTags.vue_vue_type_script_setup_true_lang-BHhwEuGe.js} +1 -1
- package/dist/client/assets/{SettingsView-CMFG91Z4.js → SettingsView-CUOFNXrz.js} +1 -1
- package/dist/client/assets/{ToolCallDialog-Bf4Xe4gH.js → ToolCallDialog-BfPjLxfV.js} +1 -1
- package/dist/client/assets/ToolsView-BxgXvPC3.css +1 -0
- package/dist/client/assets/ToolsView-CyuhYAE2.js +1 -0
- package/dist/client/assets/{_baseClone-Bp9Rjwd7.js → _baseClone-DO5qfalW.js} +1 -1
- package/dist/client/assets/{el-form-item-DdSUWYsl.js → el-form-item-CcGsD2K_.js} +2 -2
- package/dist/client/assets/{el-input-99gMrutP.js → el-input-tYgeiaCT.js} +1 -1
- package/dist/client/assets/{el-loading-CIQ5pD5u.js → el-loading-Dwl9E_Vr.js} +1 -1
- package/dist/client/assets/{el-overlay-BVM6msGX.js → el-overlay-kqX_BABo.js} +1 -1
- package/dist/client/assets/{el-radio-group-DhXWy7ry.js → el-radio-group-D8aWBVOT.js} +1 -1
- package/dist/client/assets/el-skeleton-item-BRwIFspE.js +1 -0
- package/dist/client/assets/{el-switch-Bu8AQ5uM.js → el-switch-BF8c-xeU.js} +1 -1
- package/dist/client/assets/{el-tab-pane-BnGMaV56.js → el-tab-pane-C4Ep94cd.js} +1 -1
- package/dist/client/assets/{el-table-column-BMWOaLS_.js → el-table-column-Cog6uCh-.js} +1 -1
- package/dist/client/assets/{index-C2V-ZGji.js → index-ByNBhPAR.js} +1 -1
- package/dist/client/assets/index-CTB6oe-9.js +2 -0
- package/dist/client/assets/omit-CUnDT6sS.js +1 -0
- package/dist/client/assets/{raf-C2wXzaVU.js → raf-CmzeRPMd.js} +1 -1
- package/dist/client/assets/{vue-vendor-BLHLXXJK.js → vue-vendor-CbgVSHIh.js} +3 -3
- package/dist/client/index.html +2 -2
- package/dist/server/src/api/mcp/debug-response-wrapper.js +2 -2
- package/dist/server/src/api/mcp/gateway.d.ts.map +1 -1
- package/dist/server/src/api/mcp/gateway.js +17 -3
- package/dist/server/src/api/mcp/session-context-extractor.d.ts.map +1 -1
- package/dist/server/src/api/mcp/session-context-extractor.js +14 -5
- package/dist/server/src/cli/commands/server.d.ts +57 -0
- package/dist/server/src/cli/commands/server.d.ts.map +1 -0
- package/dist/server/src/cli/commands/server.js +169 -0
- package/dist/server/src/services/gateway/gateway.service.d.ts.map +1 -1
- package/dist/server/src/services/gateway/gateway.service.js +38 -4
- package/dist/server/src/services/gateway/global-transport.d.ts +14 -5
- package/dist/server/src/services/gateway/global-transport.d.ts.map +1 -1
- package/dist/server/src/services/gateway/global-transport.js +54 -30
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/initialize-handler.js +12 -1
- package/dist/server/src/services/gateway/request-handlers/tools-handler.d.ts.map +1 -1
- package/dist/server/src/services/gateway/request-handlers/tools-handler.js +3 -4
- package/dist/server/src/services/search/search-core.service.d.ts +5 -5
- package/dist/server/src/services/search/search-core.service.js +11 -11
- package/dist/server/src/services/session/session-manager.d.ts +256 -12
- package/dist/server/src/services/session/session-manager.d.ts.map +1 -1
- package/dist/server/src/services/session/session-manager.js +585 -23
- package/dist/server/src/services/session-tracker.service.d.ts +10 -2
- package/dist/server/src/services/session-tracker.service.d.ts.map +1 -1
- package/dist/server/src/services/session-tracker.service.js +53 -2
- package/dist/server/src/utils/request-context.d.ts +18 -0
- package/dist/server/src/utils/request-context.d.ts.map +1 -1
- package/dist/server/src/utils/request-context.js +20 -0
- package/dist/server/tests/evaluation/evaluation.test.js +9 -10
- package/dist/server/tests/integration/api/gateway.test.js +2 -2
- package/dist/server/tests/unit/utils/request-context.test.js +24 -5
- package/package.json +3 -1
- package/dist/client/assets/ToolsView-DFpha1z0.js +0 -1
- package/dist/client/assets/ToolsView-E3Ps9c7i.css +0 -1
- package/dist/client/assets/el-skeleton-item-DJz-Us12.js +0 -1
- package/dist/client/assets/index-vhkqgpmN.js +0 -2
- package/dist/client/assets/omit-CqPQN3XP.js +0 -1
package/dist/client/index.html
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<link rel="icon" href="/favicon.ico" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>MCP Server Manager</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-CTB6oe-9.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-CbgVSHIh.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/index-DpH6ZSbs.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
@@ -269,10 +269,10 @@ export function wrapReplyForDebug(reply, sessionId) {
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
if (headers) {
|
|
272
|
-
logger.debug(`
|
|
272
|
+
logger.debug(`Full error response context - statusCode: ${statusCode}, statusMessage: ${statusMessage || 'none'}, headers: ${stringifyForLogging(headers)}`, LOG_MODULES.COMMUNICATION);
|
|
273
273
|
}
|
|
274
274
|
else {
|
|
275
|
-
logger.debug(`
|
|
275
|
+
logger.debug(`Full error response context - statusCode: ${statusCode}, statusMessage: ${statusMessage || 'none'}`, LOG_MODULES.COMMUNICATION);
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/gateway.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAM7E;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/gateway.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAM7E;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,eAAe,iBAqH9D"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { logger, LOG_MODULES } from '../../utils/logger/index.js';
|
|
6
6
|
import { stringifyForLogging, getMcpCommDebugSetting } from '../../utils/json-utils.js';
|
|
7
7
|
import { wrapReplyForDebug } from './debug-response-wrapper.js';
|
|
8
|
-
import {
|
|
8
|
+
import { createSessionTransport } from '../../services/gateway/global-transport.js';
|
|
9
9
|
/**
|
|
10
10
|
* MCP Gateway routes registration.
|
|
11
11
|
*
|
|
@@ -44,11 +44,25 @@ export async function mcpGatewayRoutes(fastify) {
|
|
|
44
44
|
wrapReplyForDebug(reply, '');
|
|
45
45
|
reply.hijack();
|
|
46
46
|
try {
|
|
47
|
-
|
|
47
|
+
logger.debug(`About to create session transport for MCP request`, LOG_MODULES.GATEWAY);
|
|
48
|
+
const { transport, server } = await createSessionTransport();
|
|
49
|
+
logger.debug(`Created session transport successfully, handling MCP request`, LOG_MODULES.GATEWAY);
|
|
50
|
+
try {
|
|
51
|
+
await transport.handleRequest(request.raw, reply.raw, request.body);
|
|
52
|
+
logger.debug(`Successfully handled MCP request with server: ${server.constructor.name}`, LOG_MODULES.GATEWAY);
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
// Resources will be automatically cleaned up by garbage collection
|
|
56
|
+
// since transport and server are local to this request scope
|
|
57
|
+
logger.debug(`Session transport request completed, resources will be GC'd`, LOG_MODULES.GATEWAY);
|
|
58
|
+
}
|
|
48
59
|
}
|
|
49
60
|
catch (error) {
|
|
50
61
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
51
|
-
|
|
62
|
+
const errorStack = error instanceof Error ? error.stack : 'No stack available';
|
|
63
|
+
logger.error(`Error handling MCP request: ${errorMessage}`, LOG_MODULES.GATEWAY);
|
|
64
|
+
logger.error(`Full error stack: ${errorStack}`, LOG_MODULES.GATEWAY);
|
|
65
|
+
logger.error(`Request body that caused error: ${JSON.stringify(request.body)}`, LOG_MODULES.GATEWAY);
|
|
52
66
|
if (!reply.raw.headersSent) {
|
|
53
67
|
reply.raw.writeHead(500, { 'Content-Type': 'application/json' });
|
|
54
68
|
reply.raw.end(JSON.stringify({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-context-extractor.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/session-context-extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAI7E,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE;YACX,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC;IAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAC,GAAG;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;CAChC,
|
|
1
|
+
{"version":3,"file":"session-context-extractor.d.ts","sourceRoot":"","sources":["../../../../../src/api/mcp/session-context-extractor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAI7E,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE;QACP,UAAU,CAAC,EAAE;YACX,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,CAAC;IAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAC,GAAG;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,cAAc,CAAC;CAChC,CAsGA"}
|
|
@@ -49,14 +49,14 @@ export function extractSessionContext(request) {
|
|
|
49
49
|
logger.debug(`Extracted sessionId from URL: ${sessionId}`, LOG_MODULES.CONTEXT);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
// If sessionId was extracted, check if it exists in
|
|
52
|
+
// If sessionId was extracted, check if it exists in persisted sessions (for debugging)
|
|
53
53
|
if (sessionId) {
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
logger.debug(`Session ${sessionId} found in
|
|
54
|
+
const persistedSession = mcpSessionManager.getSessionState(sessionId);
|
|
55
|
+
if (persistedSession) {
|
|
56
|
+
logger.debug(`Session ${sessionId} found in persisted sessions`, LOG_MODULES.CONTEXT);
|
|
57
57
|
}
|
|
58
58
|
else {
|
|
59
|
-
logger.debug(`Session ${sessionId} not found in
|
|
59
|
+
logger.debug(`Session ${sessionId} not found in persisted sessions (will create new)`, LOG_MODULES.CONTEXT);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
// Extract client info from headers and request body
|
|
@@ -90,11 +90,20 @@ export function extractSessionContext(request) {
|
|
|
90
90
|
logger.debug(`Generated new sessionId: ${sessionId}`, LOG_MODULES.CONTEXT);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
+
// Add consistency check before returning session information
|
|
94
|
+
if (sessionId && mcpSessionManager.getSessionState(sessionId)) {
|
|
95
|
+
const hasSessionObject = mcpSessionManager.hasSession(sessionId);
|
|
96
|
+
if (!hasSessionObject) {
|
|
97
|
+
logger.warn(`Session state exists but session object missing for ${sessionId}`, LOG_MODULES.CONTEXT);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
93
100
|
const sessionContext = {
|
|
94
101
|
sessionId,
|
|
95
102
|
clientName,
|
|
96
103
|
clientVersion,
|
|
97
104
|
protocolVersion,
|
|
105
|
+
cwd: undefined, // Will be populated from roots/list response later
|
|
106
|
+
project: undefined, // Will be populated from roots/list response later
|
|
98
107
|
ip: request.ip,
|
|
99
108
|
userAgent: headers['user-agent'],
|
|
100
109
|
timestamp: Date.now()
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* CLI command for dynamic MCP server tool operations via API.
|
|
4
|
+
*
|
|
5
|
+
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
6
|
+
* supporting four actions: list-servers, list-tools, get-tool, and call-tool. It wraps
|
|
7
|
+
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
8
|
+
*
|
|
9
|
+
* ## Command Format
|
|
10
|
+
*
|
|
11
|
+
* ```
|
|
12
|
+
* npm run server <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* ## Supported Actions
|
|
16
|
+
*
|
|
17
|
+
* - `list-servers` - List all connected MCP servers
|
|
18
|
+
* - `list-tools` - List all tools from the specified server
|
|
19
|
+
* - `get-tool <toolName>` - Get complete schema for a specific tool
|
|
20
|
+
* - `call-tool <toolName>` - Call a tool on the specified server
|
|
21
|
+
*
|
|
22
|
+
* ## Options
|
|
23
|
+
*
|
|
24
|
+
* - `--args <json>` - JSON string of tool arguments (for call-tool action)
|
|
25
|
+
* - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
|
|
26
|
+
*
|
|
27
|
+
* ## Usage Examples
|
|
28
|
+
*
|
|
29
|
+
* ```bash
|
|
30
|
+
* # List all connected servers
|
|
31
|
+
* npm run server mcp-hub-lite list-servers
|
|
32
|
+
*
|
|
33
|
+
* # List all tools from a specific server
|
|
34
|
+
* npm run server mcp-hub-lite list-tools
|
|
35
|
+
*
|
|
36
|
+
* # Get tool schema
|
|
37
|
+
* npm run server mcp-hub-lite get-tool list_tools
|
|
38
|
+
*
|
|
39
|
+
* # Call a tool with arguments
|
|
40
|
+
* npm run server mcp-hub-lite call-tool list_tools --args '{"serverName":"mcp-hub-lite"}'
|
|
41
|
+
*
|
|
42
|
+
* # Call a tool with tags for multi-instance selection
|
|
43
|
+
* npm run server baidu-search call-tool search --args '{"query":"天气"}' --tags '{"env":"prod"}'
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* ## Error Handling
|
|
47
|
+
*
|
|
48
|
+
* - Exits with code 1 if the server is not running
|
|
49
|
+
* - Exits with code 1 if action is unknown
|
|
50
|
+
* - Exits with code 1 if toolName is required but not provided
|
|
51
|
+
* - Exits with code 1 if JSON parsing fails for --args or --tags
|
|
52
|
+
* - Exits with code 1 if the underlying API call fails
|
|
53
|
+
*
|
|
54
|
+
* @returns {Command} The configured server command instance for registration with Commander.js
|
|
55
|
+
*/
|
|
56
|
+
export declare const serverCommand: Command;
|
|
57
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,eAAO,MAAM,aAAa,SAkItB,CAAC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { getServerStatus } from '../server.js';
|
|
3
|
+
/**
|
|
4
|
+
* CLI command for dynamic MCP server tool operations via API.
|
|
5
|
+
*
|
|
6
|
+
* This command provides a simplified CLI interface for interacting with MCP server tools,
|
|
7
|
+
* supporting four actions: list-servers, list-tools, get-tool, and call-tool. It wraps
|
|
8
|
+
* the HTTP API endpoints and requires the MCP Hub Lite server to be running.
|
|
9
|
+
*
|
|
10
|
+
* ## Command Format
|
|
11
|
+
*
|
|
12
|
+
* ```
|
|
13
|
+
* npm run server <serverName> <action> [toolName] [--args <json>] [--tags <json>]
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* ## Supported Actions
|
|
17
|
+
*
|
|
18
|
+
* - `list-servers` - List all connected MCP servers
|
|
19
|
+
* - `list-tools` - List all tools from the specified server
|
|
20
|
+
* - `get-tool <toolName>` - Get complete schema for a specific tool
|
|
21
|
+
* - `call-tool <toolName>` - Call a tool on the specified server
|
|
22
|
+
*
|
|
23
|
+
* ## Options
|
|
24
|
+
*
|
|
25
|
+
* - `--args <json>` - JSON string of tool arguments (for call-tool action)
|
|
26
|
+
* - `--tags <json>` - JSON object of instance selection tags (call-tool only, for multi-instance servers)
|
|
27
|
+
*
|
|
28
|
+
* ## Usage Examples
|
|
29
|
+
*
|
|
30
|
+
* ```bash
|
|
31
|
+
* # List all connected servers
|
|
32
|
+
* npm run server mcp-hub-lite list-servers
|
|
33
|
+
*
|
|
34
|
+
* # List all tools from a specific server
|
|
35
|
+
* npm run server mcp-hub-lite list-tools
|
|
36
|
+
*
|
|
37
|
+
* # Get tool schema
|
|
38
|
+
* npm run server mcp-hub-lite get-tool list_tools
|
|
39
|
+
*
|
|
40
|
+
* # Call a tool with arguments
|
|
41
|
+
* npm run server mcp-hub-lite call-tool list_tools --args '{"serverName":"mcp-hub-lite"}'
|
|
42
|
+
*
|
|
43
|
+
* # Call a tool with tags for multi-instance selection
|
|
44
|
+
* npm run server baidu-search call-tool search --args '{"query":"天气"}' --tags '{"env":"prod"}'
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* ## Error Handling
|
|
48
|
+
*
|
|
49
|
+
* - Exits with code 1 if the server is not running
|
|
50
|
+
* - Exits with code 1 if action is unknown
|
|
51
|
+
* - Exits with code 1 if toolName is required but not provided
|
|
52
|
+
* - Exits with code 1 if JSON parsing fails for --args or --tags
|
|
53
|
+
* - Exits with code 1 if the underlying API call fails
|
|
54
|
+
*
|
|
55
|
+
* @returns {Command} The configured server command instance for registration with Commander.js
|
|
56
|
+
*/
|
|
57
|
+
export const serverCommand = new Command('server')
|
|
58
|
+
.description('Manage MCP server tools via API (list-servers, list-tools, get-tool, call-tool)')
|
|
59
|
+
.argument('<serverName>', 'Server name to target (use "mcp-hub-lite" for system tools)')
|
|
60
|
+
.argument('<action>', 'Action: list-servers, list-tools, get-tool, call-tool')
|
|
61
|
+
.argument('[toolName]', 'Tool name (required for get-tool and call-tool actions)')
|
|
62
|
+
.option('--args <json>', 'JSON string of tool arguments (call-tool only)')
|
|
63
|
+
.option('--tags <json>', 'JSON object of instance selection tags (call-tool only, for multi-instance servers)')
|
|
64
|
+
.action(async (serverName, action, toolName, options) => {
|
|
65
|
+
try {
|
|
66
|
+
// Check if server is running and get connection info
|
|
67
|
+
const status = await getServerStatus();
|
|
68
|
+
if (!status.running) {
|
|
69
|
+
console.error('Error: MCP Hub Lite server is not running.');
|
|
70
|
+
console.error('Start the server with: mcp-hub-lite start');
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
const baseUrl = `http://${status.host}:${status.port}`;
|
|
74
|
+
switch (action) {
|
|
75
|
+
case 'list-servers': {
|
|
76
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers`, {
|
|
77
|
+
headers: { Accept: 'application/json' }
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(`API error: ${response.status} ${response.statusText}`);
|
|
81
|
+
}
|
|
82
|
+
const result = await response.json();
|
|
83
|
+
console.log(JSON.stringify(result, null, 2));
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case 'list-tools': {
|
|
87
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
88
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools${tagsParam}`, {
|
|
89
|
+
headers: { Accept: 'application/json' }
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
93
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
94
|
+
}
|
|
95
|
+
const result = await response.json();
|
|
96
|
+
console.log(JSON.stringify(result, null, 2));
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'get-tool': {
|
|
100
|
+
if (!toolName) {
|
|
101
|
+
console.error('Error: toolName is required for get-tool action');
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
const tagsParam = options.tags ? `?tags=${encodeURIComponent(options.tags)}` : '';
|
|
105
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools/${toolName}${tagsParam}`, { headers: { Accept: 'application/json' } });
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
108
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
109
|
+
}
|
|
110
|
+
const result = await response.json();
|
|
111
|
+
console.log(JSON.stringify(result, null, 2));
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
case 'call-tool': {
|
|
115
|
+
if (!toolName) {
|
|
116
|
+
console.error('Error: toolName is required for call-tool action');
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
// Parse tool arguments
|
|
120
|
+
let toolArgs = {};
|
|
121
|
+
if (options.args) {
|
|
122
|
+
try {
|
|
123
|
+
toolArgs = JSON.parse(options.args);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
console.error('Error: Invalid JSON in --args option');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Parse tags for instance selection (call-tool only)
|
|
131
|
+
let requestOptions;
|
|
132
|
+
if (options.tags) {
|
|
133
|
+
try {
|
|
134
|
+
requestOptions = { tags: JSON.parse(options.tags) };
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
console.error('Error: Invalid JSON in --tags option');
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const response = await fetch(`${baseUrl}/web/hub-tools/servers/${serverName}/tools/${toolName}/call`, {
|
|
142
|
+
method: 'POST',
|
|
143
|
+
headers: {
|
|
144
|
+
'Content-Type': 'application/json',
|
|
145
|
+
Accept: 'application/json'
|
|
146
|
+
},
|
|
147
|
+
body: JSON.stringify({ toolArgs, requestOptions })
|
|
148
|
+
});
|
|
149
|
+
if (!response.ok) {
|
|
150
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
151
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
152
|
+
}
|
|
153
|
+
const result = await response.json();
|
|
154
|
+
console.log(JSON.stringify(result, null, 2));
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
default: {
|
|
158
|
+
console.error(`Unknown action: ${action}`);
|
|
159
|
+
console.error('Valid actions: list-servers, list-tools, get-tool, call-tool');
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
process.exit(0);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error(`Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/gateway/gateway.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;;IAOpC,OAAO,CAAC,wBAAwB;
|
|
1
|
+
{"version":3,"file":"gateway.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/gateway/gateway.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;;IAOpC,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,gBAAgB;IAyCxB;;;;;OAKG;IACI,wBAAwB,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC;IAIvF;;;;;OAKG;IACI,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM;IAI5C;;;;;OAKG;IACI,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM;IAIpD;;;;OAIG;IACI,sBAAsB,IAAI,SAAS;IAI1C;;;;OAIG;IACU,KAAK;CAKnB;AAED,eAAO,MAAM,OAAO,gBAAuB,CAAC"}
|
|
@@ -34,6 +34,7 @@ export class GatewayService {
|
|
|
34
34
|
this.server = this.createServerWithHandlers();
|
|
35
35
|
}
|
|
36
36
|
createServerWithHandlers() {
|
|
37
|
+
logger.debug('Creating new MCP server with handlers', LOG_MODULES.GATEWAY_SERVICE);
|
|
37
38
|
const server = new McpServer({
|
|
38
39
|
name: MCP_HUB_LITE_SERVER,
|
|
39
40
|
version: this.appVersion
|
|
@@ -43,16 +44,49 @@ export class GatewayService {
|
|
|
43
44
|
resources: {}
|
|
44
45
|
}
|
|
45
46
|
});
|
|
47
|
+
logger.debug('MCP server created successfully', LOG_MODULES.GATEWAY_SERVICE);
|
|
46
48
|
this.registerHandlers(server);
|
|
49
|
+
logger.debug('Handlers registered successfully on MCP server', LOG_MODULES.GATEWAY_SERVICE);
|
|
47
50
|
return server;
|
|
48
51
|
}
|
|
49
52
|
registerHandlers(server) {
|
|
53
|
+
logger.debug('Registering handlers on MCP server', LOG_MODULES.GATEWAY_SERVICE);
|
|
50
54
|
// Local toolMap for this connection
|
|
51
55
|
const toolMap = new Map();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
logger.debug('Created local toolMap for connection', LOG_MODULES.GATEWAY_SERVICE);
|
|
57
|
+
try {
|
|
58
|
+
registerInitializeHandlers(server);
|
|
59
|
+
logger.debug('Initialize handlers registered successfully', LOG_MODULES.GATEWAY_SERVICE);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
logger.error('Failed to register initialize handlers:', error, LOG_MODULES.GATEWAY_SERVICE);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
registerResourcesHandlers(server);
|
|
67
|
+
logger.debug('Resources handlers registered successfully', LOG_MODULES.GATEWAY_SERVICE);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger.error('Failed to register resources handlers:', error, LOG_MODULES.GATEWAY_SERVICE);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
registerSystemToolsHandlers(server);
|
|
75
|
+
logger.debug('System tools handlers registered successfully', LOG_MODULES.GATEWAY_SERVICE);
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
logger.error('Failed to register system tools handlers:', error, LOG_MODULES.GATEWAY_SERVICE);
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
registerCallToolHandler(server, toolMap);
|
|
83
|
+
logger.debug('Call tool handler registered successfully', LOG_MODULES.GATEWAY_SERVICE);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
logger.error('Failed to register call tool handler:', error, LOG_MODULES.GATEWAY_SERVICE);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
logger.debug('All handlers registered successfully', LOG_MODULES.GATEWAY_SERVICE);
|
|
56
90
|
}
|
|
57
91
|
/**
|
|
58
92
|
* Generates a unified list of gateway tools with proper naming and collision resolution.
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* MCP transport factory for per-request transport instances.
|
|
3
3
|
*
|
|
4
|
-
* This module provides a
|
|
5
|
-
*
|
|
4
|
+
* This module provides a factory function to create isolated MCP transport and server instances
|
|
5
|
+
* for each HTTP request, ensuring proper state isolation between concurrent clients.
|
|
6
6
|
*/
|
|
7
7
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new MCP transport and server instance for a single request session.
|
|
10
|
+
* Each call returns isolated instances that should be cleaned up after the request completes.
|
|
11
|
+
*
|
|
12
|
+
* @returns {Promise<{ transport: StreamableHTTPServerTransport, server: import('@modelcontextprotocol/sdk/server/mcp.js').McpServer }>}
|
|
13
|
+
* Object containing the transport and server instances
|
|
14
|
+
*/
|
|
15
|
+
export declare function createSessionTransport(): Promise<{
|
|
16
|
+
transport: StreamableHTTPServerTransport;
|
|
17
|
+
server: import("@modelcontextprotocol/sdk/server/mcp").McpServer;
|
|
18
|
+
}>;
|
|
10
19
|
//# sourceMappingURL=global-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-transport.d.ts","sourceRoot":"","sources":["../../../../../src/services/gateway/global-transport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;
|
|
1
|
+
{"version":3,"file":"global-transport.d.ts","sourceRoot":"","sources":["../../../../../src/services/gateway/global-transport.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAMnG;;;;;;GAMG;AACH,wBAAsB,sBAAsB;;;GA+D3C"}
|
|
@@ -1,42 +1,66 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* MCP transport factory for per-request transport instances.
|
|
3
3
|
*
|
|
4
|
-
* This module provides a
|
|
5
|
-
*
|
|
4
|
+
* This module provides a factory function to create isolated MCP transport and server instances
|
|
5
|
+
* for each HTTP request, ensuring proper state isolation between concurrent clients.
|
|
6
6
|
*/
|
|
7
7
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
8
8
|
import { gateway } from './gateway.service.js';
|
|
9
9
|
import { logger, LOG_MODULES } from '../../utils/logger/index.js';
|
|
10
|
-
import { getMcpCommDebugSetting } from '../../utils/json-utils.js';
|
|
10
|
+
import { stringifyForLogging, getMcpCommDebugSetting } from '../../utils/json-utils.js';
|
|
11
11
|
import { formatMcpMessageForLogging, logNotificationMessage } from '../../utils/logger/log-output.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
transport
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (getMcpCommDebugSetting()) {
|
|
26
|
-
const originalSend = transport.send;
|
|
27
|
-
transport.send = async (message, options) => {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new MCP transport and server instance for a single request session.
|
|
14
|
+
* Each call returns isolated instances that should be cleaned up after the request completes.
|
|
15
|
+
*
|
|
16
|
+
* @returns {Promise<{ transport: StreamableHTTPServerTransport, server: import('@modelcontextprotocol/sdk/server/mcp.js').McpServer }>}
|
|
17
|
+
* Object containing the transport and server instances
|
|
18
|
+
*/
|
|
19
|
+
export async function createSessionTransport() {
|
|
20
|
+
const transport = new StreamableHTTPServerTransport();
|
|
21
|
+
const server = gateway.createConnectionServer();
|
|
22
|
+
// Set up message logging (use empty string for sessionId in per-request mode)
|
|
23
|
+
transport.onmessage = (message) => {
|
|
24
|
+
logger.debug(`Session transport onmessage called with: ${stringifyForLogging(message)}`, LOG_MODULES.GATEWAY);
|
|
28
25
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
if (getMcpCommDebugSetting()) {
|
|
27
|
+
const logMessage = formatMcpMessageForLogging(message);
|
|
28
|
+
logger.debug(`MCP message received: ${logMessage}`, LOG_MODULES.COMMUNICATION);
|
|
29
|
+
}
|
|
30
|
+
logNotificationMessage(message, ''); // Empty sessionId for per-request
|
|
31
|
+
logger.debug(`Session transport onmessage completed successfully`, LOG_MODULES.GATEWAY);
|
|
31
32
|
}
|
|
32
|
-
catch {
|
|
33
|
-
|
|
33
|
+
catch (error) {
|
|
34
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
35
|
+
logger.error(`Error in session transport onmessage handler: ${errorMessage}`, LOG_MODULES.GATEWAY);
|
|
36
|
+
logger.error(`Message that caused error: ${stringifyForLogging(message)}`, LOG_MODULES.GATEWAY);
|
|
34
37
|
}
|
|
35
|
-
return await originalSend.call(transport, message, options);
|
|
36
38
|
};
|
|
39
|
+
// Wrap send method for debug logging
|
|
40
|
+
if (getMcpCommDebugSetting()) {
|
|
41
|
+
const originalSend = transport.send;
|
|
42
|
+
transport.send = async (message, options) => {
|
|
43
|
+
try {
|
|
44
|
+
const logMessage = formatMcpMessageForLogging(message);
|
|
45
|
+
logger.debug(`MCP message sent: ${logMessage}`, LOG_MODULES.COMMUNICATION);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
logger.debug(`MCP message sent: [Error formatting response]`, LOG_MODULES.COMMUNICATION);
|
|
49
|
+
}
|
|
50
|
+
return await originalSend.call(transport, message, options);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Connect server to transport
|
|
54
|
+
logger.debug('About to connect session server to transport', LOG_MODULES.GATEWAY);
|
|
55
|
+
try {
|
|
56
|
+
await server.connect(transport);
|
|
57
|
+
logger.info('MCP session transport initialized (per-request mode)', LOG_MODULES.GATEWAY);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
61
|
+
logger.error(`Failed to connect session server to transport: ${errorMessage}`, LOG_MODULES.GATEWAY);
|
|
62
|
+
logger.error(`Transport connection error details: ${stringifyForLogging(error)}`, LOG_MODULES.GATEWAY);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
return { transport, server };
|
|
37
66
|
}
|
|
38
|
-
// Connect server to transport
|
|
39
|
-
await server.connect(transport);
|
|
40
|
-
logger.info('Global MCP transport initialized (stateless mode)', LOG_MODULES.GATEWAY);
|
|
41
|
-
export const globalTransport = transport;
|
|
42
|
-
export const globalServer = server;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initialize-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/initialize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWpE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"initialize-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/initialize-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWpE;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+DlE"}
|
|
@@ -40,7 +40,18 @@ export function registerInitializeHandlers(server) {
|
|
|
40
40
|
server.server.setRequestHandler(PingRequestSchema, async () => {
|
|
41
41
|
return { pong: true };
|
|
42
42
|
});
|
|
43
|
-
server.server.setNotificationHandler(InitializedNotificationSchema, async () => {
|
|
43
|
+
server.server.setNotificationHandler(InitializedNotificationSchema, async (notification) => {
|
|
44
44
|
logger.debug('Received initialized notification from client', LOG_MODULES.GATEWAY);
|
|
45
|
+
logger.debug(`Initialized notification details: ${JSON.stringify(notification)}`, LOG_MODULES.GATEWAY);
|
|
46
|
+
try {
|
|
47
|
+
// Process the notification
|
|
48
|
+
logger.debug('Successfully processed initialized notification', LOG_MODULES.GATEWAY);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
52
|
+
logger.error(`Error processing initialized notification: ${errorMessage}`, LOG_MODULES.GATEWAY);
|
|
53
|
+
logger.error(`Notification that caused error: ${JSON.stringify(notification)}`, LOG_MODULES.GATEWAY);
|
|
54
|
+
throw error; // Re-throw to see if this is the source of the problem
|
|
55
|
+
}
|
|
45
56
|
});
|
|
46
57
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/tools-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"tools-handler.d.ts","sourceRoot":"","sources":["../../../../../../src/services/gateway/request-handlers/tools-handler.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAMzE;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqE7D"}
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
6
6
|
import { logger } from '../../../utils/index.js';
|
|
7
|
-
import { LOG_MODULES } from '../../../utils/logger/log-modules.js';
|
|
8
7
|
import { searchCoreService } from '../../search/search-core.service.js';
|
|
9
8
|
import { hubManager } from '../../hub-manager.service.js';
|
|
10
9
|
/**
|
|
@@ -43,7 +42,7 @@ export function registerToolsHandlers(server) {
|
|
|
43
42
|
filters: {}
|
|
44
43
|
};
|
|
45
44
|
if (filters.serverName) {
|
|
46
|
-
const serverInstances = hubManager.
|
|
45
|
+
const serverInstances = hubManager.getServerInstanceByName(filters.serverName);
|
|
47
46
|
if (serverInstances.length > 0) {
|
|
48
47
|
// Use the first instance's ID as filter condition
|
|
49
48
|
searchOptions.filters.serverId = serverInstances[0].id;
|
|
@@ -68,11 +67,11 @@ export function registerToolsHandlers(server) {
|
|
|
68
67
|
}
|
|
69
68
|
catch (error) {
|
|
70
69
|
if (error instanceof Error) {
|
|
71
|
-
logger.error(`Search tools error:`, error
|
|
70
|
+
logger.error(`Search tools error:`, error);
|
|
72
71
|
throw new McpError(-32802, `Search failed: ${error.message}`);
|
|
73
72
|
}
|
|
74
73
|
else {
|
|
75
|
-
logger.error(`Search tools error:`, error
|
|
74
|
+
logger.error(`Search tools error:`, error);
|
|
76
75
|
throw new McpError(-32802, `Search failed: ${String(error)}`);
|
|
77
76
|
}
|
|
78
77
|
}
|
|
@@ -60,16 +60,16 @@ export declare class SearchCoreService {
|
|
|
60
60
|
*
|
|
61
61
|
* This method first checks if tools are available in the cache. If cached data exists,
|
|
62
62
|
* it returns the cached tools immediately. Otherwise, it fetches tools from all connected
|
|
63
|
-
* MCP servers, applies server-level filtering based on
|
|
63
|
+
* MCP servers, applies server-level filtering based on allowedTools configuration,
|
|
64
64
|
* caches the result, and returns the filtered tools.
|
|
65
65
|
*
|
|
66
66
|
* @returns A promise that resolves to an array of Tool objects from all connected servers.
|
|
67
67
|
*
|
|
68
68
|
* @remarks
|
|
69
|
-
* - Tools are filtered based on each server's
|
|
70
|
-
* - If
|
|
71
|
-
* - If
|
|
72
|
-
* - Tools are filtered using strict name matching against the
|
|
69
|
+
* - Tools are filtered based on each server's allowedTools configuration
|
|
70
|
+
* - If allowedTools is null or undefined, all tools from that server are included
|
|
71
|
+
* - If allowedTools is an empty array, no tools from that server are included
|
|
72
|
+
* - Tools are filtered using strict name matching against the allowedTools list
|
|
73
73
|
*/
|
|
74
74
|
private getToolsWithCache;
|
|
75
75
|
/**
|