@toolplex/client 0.1.4 → 0.1.6
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/mcp-server/toolHandlers/listServersHandler.js +21 -9
- package/dist/mcp-server/toolHandlers/listToolsHandler.js +48 -24
- package/dist/mcp-server/toolHandlers/lookupEntityHandler.js +26 -16
- package/dist/mcp-server/toolHandlers/searchHandler.js +25 -23
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -11,7 +11,6 @@ export async function handleListServers() {
|
|
|
11
11
|
const policyEnforcer = Registry.getPolicyEnforcer();
|
|
12
12
|
try {
|
|
13
13
|
await logger.debug("Listing all installed servers");
|
|
14
|
-
let response = "Currently installed MCP servers:\n\n";
|
|
15
14
|
// Collect all servers for updating the cache
|
|
16
15
|
const allServers = [];
|
|
17
16
|
for (const [runtime, client] of Object.entries(serverManagerClients)) {
|
|
@@ -28,10 +27,7 @@ export async function handleListServers() {
|
|
|
28
27
|
// Filter out blocked servers
|
|
29
28
|
const filteredServers = policyEnforcer.filterBlockedMcpServers(parsed.data.servers, (server) => server.server_id);
|
|
30
29
|
filteredServers.forEach((server) => {
|
|
31
|
-
|
|
32
|
-
response += ` Name: ${server.server_name}\n`;
|
|
33
|
-
response += ` Description: ${server.description}\n\n`;
|
|
34
|
-
// Add to allServers for cache update
|
|
30
|
+
// Add to allServers for cache update and structured response
|
|
35
31
|
allServers.push({
|
|
36
32
|
server_id: server.server_id,
|
|
37
33
|
server_name: server.server_name,
|
|
@@ -42,20 +38,36 @@ export async function handleListServers() {
|
|
|
42
38
|
}
|
|
43
39
|
// Update the servers cache with the fresh list
|
|
44
40
|
serversCache.updateServers(allServers);
|
|
45
|
-
if (response === "Currently installed MCP servers:\n\n") {
|
|
46
|
-
response = promptsCache.getPrompt("list_servers_empty");
|
|
47
|
-
}
|
|
48
41
|
await logger.debug("Successfully retrieved servers list");
|
|
49
42
|
await telemetryLogger.log("client_list_servers", {
|
|
50
43
|
success: true,
|
|
51
44
|
latency_ms: Date.now() - startTime,
|
|
52
45
|
});
|
|
46
|
+
// Build response content
|
|
47
|
+
if (allServers.length === 0) {
|
|
48
|
+
return {
|
|
49
|
+
role: "system",
|
|
50
|
+
content: [
|
|
51
|
+
{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: promptsCache.getPrompt("list_servers_empty"),
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
53
58
|
return {
|
|
54
59
|
role: "system",
|
|
55
60
|
content: [
|
|
56
61
|
{
|
|
57
62
|
type: "text",
|
|
58
|
-
text:
|
|
63
|
+
text: JSON.stringify({
|
|
64
|
+
servers: allServers,
|
|
65
|
+
count: allServers.length,
|
|
66
|
+
}),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: `Found ${allServers.length} installed MCP server${allServers.length !== 1 ? "s" : ""}`,
|
|
59
71
|
},
|
|
60
72
|
],
|
|
61
73
|
};
|
|
@@ -11,7 +11,7 @@ export async function handleListTools(params) {
|
|
|
11
11
|
const policyEnforcer = Registry.getPolicyEnforcer();
|
|
12
12
|
try {
|
|
13
13
|
const server_id = params.server_id;
|
|
14
|
-
|
|
14
|
+
const content = [];
|
|
15
15
|
if (server_id) {
|
|
16
16
|
// Check if server is blocked using policy enforcer
|
|
17
17
|
policyEnforcer.enforceUseServerPolicy(server_id);
|
|
@@ -27,23 +27,34 @@ export async function handleListTools(params) {
|
|
|
27
27
|
if (!parsed.success) {
|
|
28
28
|
throw new Error(`Invalid response from server manager: ${parsed.error}`);
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
const tools = parsed.data.tools || [];
|
|
31
|
+
if (tools.length > 0) {
|
|
32
|
+
// First: Structured JSON for easy parsing
|
|
33
|
+
content.push({
|
|
34
|
+
type: "text",
|
|
35
|
+
text: JSON.stringify({
|
|
36
|
+
server_id: parsed.data.server_id,
|
|
37
|
+
server_name: parsed.data.server_name,
|
|
38
|
+
tools: tools,
|
|
39
|
+
tool_count: tools.length,
|
|
40
|
+
}),
|
|
41
|
+
});
|
|
42
|
+
// Second: Human-readable summary
|
|
43
|
+
content.push({
|
|
44
|
+
type: "text",
|
|
45
|
+
text: `Available tools from server '${parsed.data.server_name}' (${parsed.data.server_id}): ${tools.length} tool${tools.length !== 1 ? "s" : ""}`,
|
|
46
|
+
});
|
|
36
47
|
}
|
|
37
48
|
else {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
49
|
+
content.push({
|
|
50
|
+
type: "text",
|
|
51
|
+
text: promptsCache.getPrompt("list_tools_empty"),
|
|
41
52
|
});
|
|
42
53
|
}
|
|
43
54
|
}
|
|
44
55
|
else {
|
|
45
56
|
await logger.debug("Listing tools from all installed servers");
|
|
46
|
-
|
|
57
|
+
const allServerTools = [];
|
|
47
58
|
for (const [runtime, client] of Object.entries(serverManagerClients)) {
|
|
48
59
|
const response_data = await client.sendRequest("list_all_tools", {});
|
|
49
60
|
if (response_data.error) {
|
|
@@ -59,17 +70,35 @@ export async function handleListTools(params) {
|
|
|
59
70
|
const filteredEntries = policyEnforcer.filterBlockedMcpServers(serverEntries, ([serverId]) => serverId);
|
|
60
71
|
for (const [serverId, serverTools] of filteredEntries) {
|
|
61
72
|
if (serverTools && serverTools.length > 0) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
response += ` Input Schema: ${JSON.stringify(tool.inputSchema, null, 2)}\n\n`;
|
|
73
|
+
allServerTools.push({
|
|
74
|
+
server_id: serverId,
|
|
75
|
+
tools: serverTools,
|
|
66
76
|
});
|
|
67
|
-
response += "\n";
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
79
|
}
|
|
71
|
-
if (
|
|
72
|
-
|
|
80
|
+
if (allServerTools.length > 0) {
|
|
81
|
+
const totalTools = allServerTools.reduce((sum, server) => sum + server.tools.length, 0);
|
|
82
|
+
// First: Structured JSON for easy parsing
|
|
83
|
+
content.push({
|
|
84
|
+
type: "text",
|
|
85
|
+
text: JSON.stringify({
|
|
86
|
+
server_tools: allServerTools,
|
|
87
|
+
server_count: allServerTools.length,
|
|
88
|
+
total_tools: totalTools,
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
// Second: Human-readable summary
|
|
92
|
+
content.push({
|
|
93
|
+
type: "text",
|
|
94
|
+
text: `Found ${totalTools} tools across ${allServerTools.length} server${allServerTools.length !== 1 ? "s" : ""}`,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
content.push({
|
|
99
|
+
type: "text",
|
|
100
|
+
text: promptsCache.getPrompt("list_tools_empty"),
|
|
101
|
+
});
|
|
73
102
|
}
|
|
74
103
|
}
|
|
75
104
|
await logger.debug("Successfully retrieved tools list");
|
|
@@ -82,12 +111,7 @@ export async function handleListTools(params) {
|
|
|
82
111
|
});
|
|
83
112
|
return {
|
|
84
113
|
role: "system",
|
|
85
|
-
content
|
|
86
|
-
{
|
|
87
|
-
type: "text",
|
|
88
|
-
text: response,
|
|
89
|
-
},
|
|
90
|
-
],
|
|
114
|
+
content,
|
|
91
115
|
};
|
|
92
116
|
}
|
|
93
117
|
catch (error) {
|
|
@@ -21,6 +21,20 @@ export async function handleLookupEntityTool(params) {
|
|
|
21
21
|
policyEnforcer.enforceUseServerPolicy(params.entity_id);
|
|
22
22
|
}
|
|
23
23
|
let lookupResponse = await apiService.lookupEntity(params.entity_type, params.entity_id);
|
|
24
|
+
// Annotate installed server using resultAnnotators
|
|
25
|
+
if (params.entity_type === "server" &&
|
|
26
|
+
lookupResponse &&
|
|
27
|
+
typeof lookupResponse === "object" &&
|
|
28
|
+
lookupResponse.result &&
|
|
29
|
+
typeof lookupResponse.result === "object") {
|
|
30
|
+
try {
|
|
31
|
+
lookupResponse.result = annotateInstalledServer(lookupResponse.result, serversCache);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
await logger.warn(`Error annotating installed server: ${err}`);
|
|
35
|
+
// fallback: do not annotate
|
|
36
|
+
}
|
|
37
|
+
}
|
|
24
38
|
if (!lookupResponse) {
|
|
25
39
|
await logger.debug("No entity found");
|
|
26
40
|
await telemetryLogger.log("client_lookup_entity", {
|
|
@@ -44,22 +58,7 @@ export async function handleLookupEntityTool(params) {
|
|
|
44
58
|
],
|
|
45
59
|
};
|
|
46
60
|
}
|
|
47
|
-
// Use resultAnnotators to annotate if the server is installed
|
|
48
|
-
if (params.entity_type === "server" &&
|
|
49
|
-
lookupResponse &&
|
|
50
|
-
typeof lookupResponse === "object") {
|
|
51
|
-
try {
|
|
52
|
-
lookupResponse = annotateInstalledServer(lookupResponse, serversCache);
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
await logger.warn(`Error annotating installed server: ${err}`);
|
|
56
|
-
// fallback: do not annotate
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
61
|
await logger.debug(`Found entity: ${JSON.stringify(lookupResponse)}`);
|
|
60
|
-
let response = `Found ${params.entity_type}:\n`;
|
|
61
|
-
response += JSON.stringify(lookupResponse, null, 2);
|
|
62
|
-
response += "\n";
|
|
63
62
|
await logger.debug("Lookup completed successfully");
|
|
64
63
|
await telemetryLogger.log("client_lookup_entity", {
|
|
65
64
|
success: true,
|
|
@@ -69,10 +68,21 @@ export async function handleLookupEntityTool(params) {
|
|
|
69
68
|
},
|
|
70
69
|
latency_ms: Date.now() - startTime,
|
|
71
70
|
});
|
|
71
|
+
// Return structured data first for easy frontend parsing, then instructions
|
|
72
72
|
const content = [
|
|
73
|
+
// First: Structured JSON for easy parsing
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: JSON.stringify({
|
|
77
|
+
entity_type: params.entity_type,
|
|
78
|
+
entity_id: params.entity_id,
|
|
79
|
+
result: lookupResponse,
|
|
80
|
+
}),
|
|
81
|
+
},
|
|
82
|
+
// Second: Human-readable summary
|
|
73
83
|
{
|
|
74
84
|
type: "text",
|
|
75
|
-
text:
|
|
85
|
+
text: `Found ${params.entity_type}: ${lookupResponse.server_name || lookupResponse.description || params.entity_id}`,
|
|
76
86
|
},
|
|
77
87
|
];
|
|
78
88
|
if (params.entity_type === "server") {
|
|
@@ -65,32 +65,34 @@ export async function handleSearchTool(params) {
|
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
67
|
await logger.debug(`Found ${totalResults} results`);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
68
|
+
// Build structured response content
|
|
69
|
+
const content = [
|
|
70
|
+
// First: Structured JSON for easy parsing
|
|
71
|
+
{
|
|
72
|
+
type: "text",
|
|
73
|
+
text: JSON.stringify({
|
|
74
|
+
query,
|
|
75
|
+
expanded_keywords: expandedKeywords,
|
|
76
|
+
filter,
|
|
77
|
+
scope,
|
|
78
|
+
size,
|
|
79
|
+
servers: annotatedServers,
|
|
80
|
+
playbooks,
|
|
81
|
+
server_count: annotatedServers.length,
|
|
82
|
+
playbook_count: playbooks.length,
|
|
83
|
+
total_results: totalResults,
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
// Second: Human-readable summary
|
|
87
|
+
{
|
|
88
|
+
type: "text",
|
|
89
|
+
text: `Found ${totalResults} results for "${query}": ${annotatedServers.length} servers, ${playbooks.length} playbooks`,
|
|
90
|
+
},
|
|
91
|
+
];
|
|
85
92
|
await logger.info("Search completed successfully");
|
|
86
93
|
return {
|
|
87
94
|
role: "system",
|
|
88
|
-
content
|
|
89
|
-
{
|
|
90
|
-
type: "text",
|
|
91
|
-
text: response,
|
|
92
|
-
},
|
|
93
|
-
],
|
|
95
|
+
content,
|
|
94
96
|
};
|
|
95
97
|
}
|
|
96
98
|
catch (error) {
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.1.
|
|
1
|
+
export declare const version = "0.1.6";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '0.1.
|
|
1
|
+
export const version = '0.1.6';
|