@toolplex/client 0.1.6 → 0.1.8
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/installServerHandler.js +65 -0
- package/dist/mcp-server/toolHandlers/lookupEntityHandler.js +1 -1
- package/dist/mcp-server/toolHandlers/savePlaybookHandler.js +2 -2
- package/dist/mcp-server/toolplexApi/service.d.ts +1 -1
- package/dist/mcp-server/toolplexApi/service.js +2 -1
- package/dist/mcp-server/toolplexApi/types.d.ts +1 -0
- package/dist/shared/mcpServerTypes.d.ts +3 -0
- package/dist/shared/mcpServerTypes.js +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,71 @@ import { FileLogger } from "../../shared/fileLogger.js";
|
|
|
2
2
|
import { ServerInstallResultSchema, ListToolsResultSchema, } from "../../shared/serverManagerTypes.js";
|
|
3
3
|
import Registry from "../registry.js";
|
|
4
4
|
import { RuntimeCheck } from "../utils/runtimeCheck.js";
|
|
5
|
+
import { isAbsolute, parse } from "path";
|
|
5
6
|
const logger = FileLogger;
|
|
7
|
+
/**
|
|
8
|
+
* Sanitizes ServerConfig for telemetry logging by extracting aggregate patterns
|
|
9
|
+
* while avoiding PII exposure. This function extracts useful installation patterns
|
|
10
|
+
* without logging sensitive data like file paths, API keys, or user-specific values.
|
|
11
|
+
*
|
|
12
|
+
* SECURITY: This function only logs metadata patterns, never actual values:
|
|
13
|
+
* - Command names (not paths): "npx" vs "/Users/john/bin/tool"
|
|
14
|
+
* - Argument flags (not values): "--port" vs actual port numbers
|
|
15
|
+
* - Environment variable names (not values): "API_KEY" vs actual keys
|
|
16
|
+
* - Path types for portability analysis: "absolute" vs "package_manager"
|
|
17
|
+
*/
|
|
18
|
+
function sanitizeServerConfig(config) {
|
|
19
|
+
// Extract command executable name without sensitive path information
|
|
20
|
+
const extractCommandType = (command) => {
|
|
21
|
+
if (!command)
|
|
22
|
+
return "none";
|
|
23
|
+
// For absolute paths, extract only the executable name (e.g., "/usr/bin/node" -> "node")
|
|
24
|
+
if (isAbsolute(command)) {
|
|
25
|
+
return parse(command).name;
|
|
26
|
+
}
|
|
27
|
+
// For relative commands, get the base command (e.g., "npx" from "npx --version")
|
|
28
|
+
return (command
|
|
29
|
+
.split(/[\s/\\]/)
|
|
30
|
+
.pop()
|
|
31
|
+
?.split(".")[0] || "unknown");
|
|
32
|
+
};
|
|
33
|
+
// Categorize path types for portability analysis - helps identify installation reliability patterns
|
|
34
|
+
const detectPathType = (command, args) => {
|
|
35
|
+
if (!command)
|
|
36
|
+
return "system_command";
|
|
37
|
+
// Absolute paths indicate potential portability issues
|
|
38
|
+
if (isAbsolute(command) || args?.some((arg) => isAbsolute(arg))) {
|
|
39
|
+
return "absolute";
|
|
40
|
+
}
|
|
41
|
+
// Package managers are typically more reliable across systems
|
|
42
|
+
if (["npx", "uvx", "pip", "yarn", "pnpm"].includes(command)) {
|
|
43
|
+
return "package_manager";
|
|
44
|
+
}
|
|
45
|
+
return "system_command";
|
|
46
|
+
};
|
|
47
|
+
// Extract common argument flags and patterns (not values) for usage analysis
|
|
48
|
+
const extractArgPatterns = (args) => {
|
|
49
|
+
return (args?.filter((arg) => arg.startsWith("-") || // Command flags like --port, --config
|
|
50
|
+
["stdio", "mcp", "start", "latest", "@latest"].includes(arg)) || []);
|
|
51
|
+
};
|
|
52
|
+
// Extract environment variable names (not values) to understand integration patterns
|
|
53
|
+
// SAFE: Only logs key names like "API_KEY", "DATABASE_URL" - never the actual values
|
|
54
|
+
const extractEnvKeys = (env) => {
|
|
55
|
+
if (!env)
|
|
56
|
+
return [];
|
|
57
|
+
return Object.keys(env).sort();
|
|
58
|
+
};
|
|
59
|
+
return {
|
|
60
|
+
runtime: config.runtime || "node",
|
|
61
|
+
transport: config.transport,
|
|
62
|
+
command_type: extractCommandType(config.command),
|
|
63
|
+
path_type: detectPathType(config.command, config.args),
|
|
64
|
+
arg_patterns: extractArgPatterns(config.args),
|
|
65
|
+
arg_count: config.args?.length || 0,
|
|
66
|
+
env_keys: extractEnvKeys(config.env),
|
|
67
|
+
env_count: config.env ? Object.keys(config.env).length : 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
6
70
|
async function installServer(serverId, serverName, description, serverManagerClient, serverConfig) {
|
|
7
71
|
await logger.info(`Starting installation of tool ${serverId}: ${serverName}`);
|
|
8
72
|
await logger.debug(`Server config: ${JSON.stringify(serverConfig)}, Server ID: ${serverId}`);
|
|
@@ -91,6 +155,7 @@ export async function handleInstallServer(params) {
|
|
|
91
155
|
success: true,
|
|
92
156
|
log_context: {
|
|
93
157
|
server_id: installResult.server_id,
|
|
158
|
+
sanitized_config: sanitizeServerConfig(config),
|
|
94
159
|
},
|
|
95
160
|
latency_ms: Date.now() - startTime,
|
|
96
161
|
});
|
|
@@ -20,7 +20,7 @@ export async function handleLookupEntityTool(params) {
|
|
|
20
20
|
if (params.entity_type === "server") {
|
|
21
21
|
policyEnforcer.enforceUseServerPolicy(params.entity_id);
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
const lookupResponse = await apiService.lookupEntity(params.entity_type, params.entity_id);
|
|
24
24
|
// Annotate installed server using resultAnnotators
|
|
25
25
|
if (params.entity_type === "server" &&
|
|
26
26
|
lookupResponse &&
|
|
@@ -21,8 +21,8 @@ export async function handleSavePlaybook(params) {
|
|
|
21
21
|
}
|
|
22
22
|
// Enforce playbook policy before saving
|
|
23
23
|
policyEnforcer.enforceSavePlaybookPolicy(params);
|
|
24
|
-
const { description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason, } = params;
|
|
25
|
-
const response = await apiService.createPlaybook(description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason);
|
|
24
|
+
const { playbook_name, description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason, } = params;
|
|
25
|
+
const response = await apiService.createPlaybook(playbook_name, description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason);
|
|
26
26
|
await logger.info(`Playbook created successfully with ID: ${response.id}`);
|
|
27
27
|
await telemetryLogger.log("client_save_playbook", {
|
|
28
28
|
success: true,
|
|
@@ -25,7 +25,7 @@ export declare class ToolplexApiService {
|
|
|
25
25
|
mcp_servers?: any[];
|
|
26
26
|
playbooks?: any[];
|
|
27
27
|
}>;
|
|
28
|
-
createPlaybook(description: string, actions: Array<PlaybookAction>, domain?: string, keywords?: string[], requirements?: string[], privacy?: "public" | "private", sourcePlaybookId?: string, forkReason?: string): Promise<CreatePlaybookResponse>;
|
|
28
|
+
createPlaybook(playbook_name: string, description: string, actions: Array<PlaybookAction>, domain?: string, keywords?: string[], requirements?: string[], privacy?: "public" | "private", sourcePlaybookId?: string, forkReason?: string): Promise<CreatePlaybookResponse>;
|
|
29
29
|
logPlaybookUsage(playbookId: string, success: boolean, errorMessage?: string): Promise<LogPlaybookUsageResponse>;
|
|
30
30
|
submitFeedback(targetType: "server" | "playbook", targetId: string, vote: "up" | "down", message?: string, securityAssessment?: SecurityAssessment): Promise<SubmitFeedbackResponse>;
|
|
31
31
|
getFeedbackSummary(): Promise<FeedbackSummaryResponse>;
|
|
@@ -136,8 +136,9 @@ export class ToolplexApiService {
|
|
|
136
136
|
throw err;
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
async createPlaybook(description, actions, domain, keywords, requirements, privacy, sourcePlaybookId, forkReason) {
|
|
139
|
+
async createPlaybook(playbook_name, description, actions, domain, keywords, requirements, privacy, sourcePlaybookId, forkReason) {
|
|
140
140
|
const requestBody = {
|
|
141
|
+
playbook_name,
|
|
141
142
|
description,
|
|
142
143
|
actions,
|
|
143
144
|
llm_context: this.clientContext.llmContext,
|
|
@@ -252,6 +252,7 @@ export declare const PlaybookActionSchema: z.ZodObject<{
|
|
|
252
252
|
}>;
|
|
253
253
|
export type PlaybookAction = z.infer<typeof PlaybookActionSchema>;
|
|
254
254
|
export declare const SavePlaybookParamsSchema: z.ZodObject<{
|
|
255
|
+
playbook_name: z.ZodString;
|
|
255
256
|
description: z.ZodString;
|
|
256
257
|
actions: z.ZodEffects<z.ZodArray<z.ZodObject<{
|
|
257
258
|
do: z.ZodString;
|
|
@@ -303,6 +304,7 @@ export declare const SavePlaybookParamsSchema: z.ZodObject<{
|
|
|
303
304
|
fork_reason: z.ZodOptional<z.ZodString>;
|
|
304
305
|
}, "strip", z.ZodTypeAny, {
|
|
305
306
|
description: string;
|
|
307
|
+
playbook_name: string;
|
|
306
308
|
actions: {
|
|
307
309
|
do: string;
|
|
308
310
|
args?: Record<string, {
|
|
@@ -319,6 +321,7 @@ export declare const SavePlaybookParamsSchema: z.ZodObject<{
|
|
|
319
321
|
fork_reason?: string | undefined;
|
|
320
322
|
}, {
|
|
321
323
|
description: string;
|
|
324
|
+
playbook_name: string;
|
|
322
325
|
actions: {
|
|
323
326
|
do: string;
|
|
324
327
|
args?: Record<string, {
|
|
@@ -111,6 +111,7 @@ export const PlaybookActionSchema = z.object({
|
|
|
111
111
|
// SavePlaybookParams
|
|
112
112
|
// --------------------
|
|
113
113
|
export const SavePlaybookParamsSchema = z.object({
|
|
114
|
+
playbook_name: z.string(),
|
|
114
115
|
description: z.string(),
|
|
115
116
|
// Requires at least one action to have a "call" property
|
|
116
117
|
actions: z
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.1.
|
|
1
|
+
export declare const version = "0.1.8";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '0.1.
|
|
1
|
+
export const version = '0.1.8';
|