@toolplex/client 0.1.1 → 0.1.2
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/clientContext.d.ts +7 -4
- package/dist/mcp-server/clientContext.js +21 -10
- package/dist/mcp-server/index.js +9 -7
- package/dist/mcp-server/logging/telemetryLogger.d.ts +2 -2
- package/dist/mcp-server/logging/telemetryLogger.js +2 -2
- package/dist/mcp-server/policy/callToolObserver.js +4 -2
- package/dist/mcp-server/policy/feedbackPolicy.d.ts +4 -4
- package/dist/mcp-server/policy/feedbackPolicy.js +1 -1
- package/dist/mcp-server/policy/installObserver.js +4 -4
- package/dist/mcp-server/policy/playbookPolicy.d.ts +3 -3
- package/dist/mcp-server/policy/playbookPolicy.js +5 -5
- package/dist/mcp-server/policy/policyEnforcer.d.ts +4 -4
- package/dist/mcp-server/policy/policyEnforcer.js +13 -13
- package/dist/mcp-server/policy/serverPolicy.d.ts +1 -1
- package/dist/mcp-server/policy/serverPolicy.js +4 -2
- package/dist/mcp-server/promptsCache.js +2 -2
- package/dist/mcp-server/registry.d.ts +8 -8
- package/dist/mcp-server/registry.js +19 -17
- package/dist/mcp-server/serversCache.d.ts +1 -1
- package/dist/mcp-server/serversCache.js +6 -6
- package/dist/mcp-server/staticPrompts.js +2 -2
- package/dist/mcp-server/toolDefinitionsCache.d.ts +3 -3
- package/dist/mcp-server/toolDefinitionsCache.js +3 -3
- package/dist/mcp-server/toolHandlers/callToolHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/callToolHandler.js +22 -20
- package/dist/mcp-server/toolHandlers/getServerConfigHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/getServerConfigHandler.js +24 -18
- package/dist/mcp-server/toolHandlers/initHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/initHandler.js +41 -39
- package/dist/mcp-server/toolHandlers/installServerHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/installServerHandler.js +36 -32
- package/dist/mcp-server/toolHandlers/listServersHandler.d.ts +1 -1
- package/dist/mcp-server/toolHandlers/listServersHandler.js +21 -17
- package/dist/mcp-server/toolHandlers/listToolsHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/listToolsHandler.js +32 -26
- package/dist/mcp-server/toolHandlers/logPlaybookUsageHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/logPlaybookUsageHandler.js +14 -14
- package/dist/mcp-server/toolHandlers/lookupEntityHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/lookupEntityHandler.js +30 -28
- package/dist/mcp-server/toolHandlers/savePlaybookHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/savePlaybookHandler.js +17 -15
- package/dist/mcp-server/toolHandlers/searchHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/searchHandler.js +33 -28
- package/dist/mcp-server/toolHandlers/serverManagerUtils.d.ts +1 -1
- package/dist/mcp-server/toolHandlers/serverManagerUtils.js +2 -2
- package/dist/mcp-server/toolHandlers/submitFeedbackHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/submitFeedbackHandler.js +17 -15
- package/dist/mcp-server/toolHandlers/uninstallServerHandler.d.ts +2 -2
- package/dist/mcp-server/toolHandlers/uninstallServerHandler.js +21 -19
- package/dist/mcp-server/toolplexApi/service.d.ts +8 -8
- package/dist/mcp-server/toolplexApi/service.js +24 -28
- package/dist/mcp-server/toolplexApi/types.d.ts +3 -3
- package/dist/mcp-server/toolplexServer.d.ts +1 -1
- package/dist/mcp-server/toolplexServer.js +78 -77
- package/dist/mcp-server/tools.d.ts +1 -1
- package/dist/mcp-server/tools.js +3 -3
- package/dist/mcp-server/utils/initServerManagers.d.ts +4 -4
- package/dist/mcp-server/utils/initServerManagers.js +5 -5
- package/dist/mcp-server/utils/resultAnnotators.js +3 -7
- package/dist/mcp-server/utils/runtimeCheck.js +8 -8
- package/dist/server-manager/index.js +4 -4
- package/dist/server-manager/serverManager.d.ts +6 -6
- package/dist/server-manager/serverManager.js +34 -36
- package/dist/server-manager/stdioServer.js +37 -35
- package/dist/server-manager/stdioTransportProtocol.d.ts +2 -2
- package/dist/server-manager/stdioTransportProtocol.js +7 -7
- package/dist/shared/enhancedPath.js +13 -13
- package/dist/shared/fileLogger.js +19 -19
- package/dist/shared/mcpServerTypes.d.ts +4 -3
- package/dist/shared/mcpServerTypes.js +17 -10
- package/dist/shared/serverManagerTypes.d.ts +1 -1
- package/dist/shared/serverManagerTypes.js +1 -1
- package/dist/shared/stdioServerManagerClient.js +20 -18
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// stdioServer.ts
|
|
2
|
-
import { ServerManager } from
|
|
3
|
-
import { StdioTransport, } from
|
|
4
|
-
import { FileLogger } from
|
|
5
|
-
import { CallToolParamsSchema, InstallParamsSchema, ListToolsParamsSchema, UninstallParamsSchema, } from
|
|
2
|
+
import { ServerManager } from "./serverManager.js";
|
|
3
|
+
import { StdioTransport, } from "./stdioTransportProtocol.js";
|
|
4
|
+
import { FileLogger } from "../shared/fileLogger.js";
|
|
5
|
+
import { CallToolParamsSchema, InstallParamsSchema, ListToolsParamsSchema, UninstallParamsSchema, } from "../shared/mcpServerTypes.js";
|
|
6
6
|
const logger = FileLogger;
|
|
7
7
|
export class ServerManagerProtocol {
|
|
8
8
|
constructor() {
|
|
@@ -10,28 +10,28 @@ export class ServerManagerProtocol {
|
|
|
10
10
|
this.transport = new StdioTransport();
|
|
11
11
|
this.transport.setOnMessage(this.handleMessage.bind(this));
|
|
12
12
|
// Clean up on process exit
|
|
13
|
-
process.on(
|
|
14
|
-
await logger.info(
|
|
13
|
+
process.on("exit", async () => {
|
|
14
|
+
await logger.info("Process exit - cleaning up server manager");
|
|
15
15
|
await logger.flush();
|
|
16
16
|
await this.serverManager.cleanup();
|
|
17
17
|
});
|
|
18
|
-
process.on(
|
|
19
|
-
await logger.warn(
|
|
18
|
+
process.on("SIGINT", async () => {
|
|
19
|
+
await logger.warn("SIGINT received - cleaning up server manager");
|
|
20
20
|
await logger.flush();
|
|
21
21
|
await this.serverManager.cleanup();
|
|
22
22
|
process.exit();
|
|
23
23
|
});
|
|
24
|
-
process.on(
|
|
25
|
-
await logger.warn(
|
|
24
|
+
process.on("SIGTERM", async () => {
|
|
25
|
+
await logger.warn("SIGTERM received - cleaning up server manager");
|
|
26
26
|
await logger.flush();
|
|
27
27
|
await this.serverManager.cleanup();
|
|
28
28
|
process.exit();
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
async start() {
|
|
32
|
-
await logger.info(
|
|
32
|
+
await logger.info("Starting ServerManagerProtocol transport");
|
|
33
33
|
await this.transport.start();
|
|
34
|
-
await logger.info(
|
|
34
|
+
await logger.info("ServerManagerProtocol transport started successfully");
|
|
35
35
|
}
|
|
36
36
|
async safeSend(msg) {
|
|
37
37
|
try {
|
|
@@ -43,10 +43,10 @@ export class ServerManagerProtocol {
|
|
|
43
43
|
}
|
|
44
44
|
async handleMessage(message) {
|
|
45
45
|
try {
|
|
46
|
-
if (!(
|
|
46
|
+
if (!("id" in message) || !("method" in message)) {
|
|
47
47
|
await this.safeSend({
|
|
48
|
-
jsonrpc:
|
|
49
|
-
error: { code: -1001, message:
|
|
48
|
+
jsonrpc: "2.0",
|
|
49
|
+
error: { code: -1001, message: "Invalid Request" },
|
|
50
50
|
id: null,
|
|
51
51
|
});
|
|
52
52
|
return;
|
|
@@ -57,15 +57,18 @@ export class ServerManagerProtocol {
|
|
|
57
57
|
result = await this.callMethod(req.method, req.params ?? {});
|
|
58
58
|
}
|
|
59
59
|
catch (err) {
|
|
60
|
-
await logger.error(`callMethod failed (${req.method}): ${err instanceof Error ? err.message :
|
|
60
|
+
await logger.error(`callMethod failed (${req.method}): ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
61
61
|
await this.safeSend({
|
|
62
|
-
jsonrpc:
|
|
63
|
-
error: {
|
|
62
|
+
jsonrpc: "2.0",
|
|
63
|
+
error: {
|
|
64
|
+
code: -1000,
|
|
65
|
+
message: err instanceof Error ? err.message : "Server error",
|
|
66
|
+
},
|
|
64
67
|
id: req.id,
|
|
65
68
|
});
|
|
66
69
|
return;
|
|
67
70
|
}
|
|
68
|
-
await this.safeSend({ jsonrpc:
|
|
71
|
+
await this.safeSend({ jsonrpc: "2.0", result, id: req.id });
|
|
69
72
|
}
|
|
70
73
|
catch (fatal) {
|
|
71
74
|
process.stderr.write(`handleMessage fatal: ${String(fatal)}\n`);
|
|
@@ -74,57 +77,56 @@ export class ServerManagerProtocol {
|
|
|
74
77
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
75
78
|
async callMethod(method, params) {
|
|
76
79
|
switch (method) {
|
|
77
|
-
case
|
|
78
|
-
await logger.info(
|
|
80
|
+
case "initialize": {
|
|
81
|
+
await logger.info("Calling ServerManager.initialize()");
|
|
79
82
|
const { succeeded, failures } = await this.serverManager.initialize();
|
|
80
83
|
return { succeeded, failures };
|
|
81
84
|
}
|
|
82
|
-
case
|
|
85
|
+
case "install": {
|
|
83
86
|
const install_params = InstallParamsSchema.parse(params);
|
|
84
87
|
await logger.info(`Installing server ${install_params.server_id}`);
|
|
85
88
|
await this.serverManager.install(install_params.server_id, install_params.server_name, install_params.description, install_params.config);
|
|
86
89
|
const server_name = await this.serverManager.getServerName(install_params.server_id);
|
|
87
90
|
return { server_id: install_params.server_id, server_name };
|
|
88
91
|
}
|
|
89
|
-
case
|
|
90
|
-
await logger.debug(
|
|
92
|
+
case "list_servers": {
|
|
93
|
+
await logger.debug("Listing servers");
|
|
91
94
|
const servers = await this.serverManager.listServers();
|
|
92
95
|
return { servers };
|
|
93
96
|
}
|
|
94
|
-
case
|
|
97
|
+
case "list_tools": {
|
|
95
98
|
const list_tools_params = ListToolsParamsSchema.parse(params);
|
|
96
99
|
if (!list_tools_params.server_id)
|
|
97
|
-
throw new Error(
|
|
100
|
+
throw new Error("Missing server_id");
|
|
98
101
|
await logger.debug(`Listing tools for server ${list_tools_params.server_id}`);
|
|
99
102
|
const tools = await this.serverManager.listTools(list_tools_params.server_id);
|
|
100
103
|
const server_name = await this.serverManager.getServerName(list_tools_params.server_id);
|
|
101
104
|
return { server_id: list_tools_params.server_id, server_name, tools };
|
|
102
105
|
}
|
|
103
|
-
case
|
|
104
|
-
if (!params || typeof params.server_id !==
|
|
105
|
-
throw new Error(
|
|
106
|
+
case "get_server_config": {
|
|
107
|
+
if (!params || typeof params.server_id !== "string") {
|
|
108
|
+
throw new Error("Missing or invalid server_id");
|
|
106
109
|
}
|
|
107
110
|
await logger.debug(`Getting config for server ${params.server_id}`);
|
|
108
111
|
// Just return the config directly
|
|
109
112
|
const config = await this.serverManager.getServerConfig(params.server_id);
|
|
110
113
|
return config;
|
|
111
114
|
}
|
|
112
|
-
case
|
|
115
|
+
case "call_tool": {
|
|
113
116
|
const call_tool_params = CallToolParamsSchema.parse(params);
|
|
114
117
|
await logger.debug(`Calling tool ${call_tool_params.tool_name} on server ${call_tool_params.server_id}`);
|
|
115
|
-
const result = await this.serverManager.callTool(call_tool_params.server_id, call_tool_params.tool_name, call_tool_params.arguments, 60000
|
|
116
|
-
);
|
|
118
|
+
const result = await this.serverManager.callTool(call_tool_params.server_id, call_tool_params.tool_name, call_tool_params.arguments, 60000);
|
|
117
119
|
return { result };
|
|
118
120
|
}
|
|
119
|
-
case
|
|
121
|
+
case "uninstall": {
|
|
120
122
|
const uninstall_params = UninstallParamsSchema.parse(params);
|
|
121
123
|
await logger.info(`Uninstalling server ${uninstall_params.server_id}`);
|
|
122
124
|
const server_name = await this.serverManager.getServerName(uninstall_params.server_id);
|
|
123
125
|
await this.serverManager.uninstall(uninstall_params.server_id);
|
|
124
126
|
return { server_id: uninstall_params.server_id, server_name };
|
|
125
127
|
}
|
|
126
|
-
case
|
|
127
|
-
await logger.info(
|
|
128
|
+
case "cleanup": {
|
|
129
|
+
await logger.info("Cleaning up server manager");
|
|
128
130
|
await this.serverManager.cleanup();
|
|
129
131
|
return {};
|
|
130
132
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as readline from
|
|
1
|
+
import * as readline from "readline";
|
|
2
2
|
export class StdioTransport {
|
|
3
3
|
constructor(_stdin = process.stdin, _stdout = process.stdout) {
|
|
4
4
|
this._stdin = _stdin;
|
|
@@ -21,14 +21,14 @@ export class StdioTransport {
|
|
|
21
21
|
return; // Prevent double initialization
|
|
22
22
|
}
|
|
23
23
|
this.isStarted = true;
|
|
24
|
-
this._stdin.on(
|
|
24
|
+
this._stdin.on("data", this.dataHandler);
|
|
25
25
|
}
|
|
26
26
|
processBuffer() {
|
|
27
27
|
// Join all chunks and split by lines - more efficient than string concatenation
|
|
28
|
-
const fullBuffer = this.bufferChunks.join(
|
|
29
|
-
const lines = fullBuffer.split(
|
|
28
|
+
const fullBuffer = this.bufferChunks.join("");
|
|
29
|
+
const lines = fullBuffer.split("\n");
|
|
30
30
|
// Keep the last line in buffer if it's incomplete
|
|
31
|
-
const incompleteLine = lines.pop() ||
|
|
31
|
+
const incompleteLine = lines.pop() || "";
|
|
32
32
|
// Clear chunks and store incomplete line
|
|
33
33
|
this.bufferChunks = incompleteLine ? [incompleteLine] : [];
|
|
34
34
|
for (const line of lines) {
|
|
@@ -49,12 +49,12 @@ export class StdioTransport {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
async send(message) {
|
|
52
|
-
const messageStr = JSON.stringify(message) +
|
|
52
|
+
const messageStr = JSON.stringify(message) + "\n";
|
|
53
53
|
this._stdout.write(messageStr);
|
|
54
54
|
}
|
|
55
55
|
async close() {
|
|
56
56
|
if (this.isStarted) {
|
|
57
|
-
this._stdin.removeListener(
|
|
57
|
+
this._stdin.removeListener("data", this.dataHandler);
|
|
58
58
|
this.isStarted = false;
|
|
59
59
|
}
|
|
60
60
|
this.bufferChunks = [];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as path from
|
|
2
|
-
import { existsSync } from
|
|
3
|
-
import { homedir } from
|
|
4
|
-
import { glob } from
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { glob } from "glob";
|
|
5
5
|
/**
|
|
6
6
|
* Returns an enhanced PATH string by prepending common binary directories
|
|
7
7
|
* across platforms (Linux, macOS, Windows).
|
|
@@ -10,12 +10,12 @@ import { glob } from 'glob';
|
|
|
10
10
|
*/
|
|
11
11
|
export function getEnhancedPath() {
|
|
12
12
|
const home = homedir();
|
|
13
|
-
const basePaths = (process.env.PATH ||
|
|
13
|
+
const basePaths = (process.env.PATH || "").split(path.delimiter);
|
|
14
14
|
const extraPaths = getDefaultExtraPaths(home);
|
|
15
15
|
const seen = new Set(basePaths);
|
|
16
16
|
const allPaths = [...basePaths];
|
|
17
17
|
for (const extraPath of extraPaths) {
|
|
18
|
-
if (extraPath.includes(
|
|
18
|
+
if (extraPath.includes("*")) {
|
|
19
19
|
const matches = glob.sync(extraPath);
|
|
20
20
|
for (const match of matches) {
|
|
21
21
|
if (existsSync(match) && !seen.has(match)) {
|
|
@@ -37,16 +37,16 @@ export function getEnhancedPath() {
|
|
|
37
37
|
* Returns platform-specific extra binary paths.
|
|
38
38
|
*/
|
|
39
39
|
function getDefaultExtraPaths(home) {
|
|
40
|
-
const isWindows = process.platform ===
|
|
40
|
+
const isWindows = process.platform === "win32";
|
|
41
41
|
return isWindows
|
|
42
42
|
? [
|
|
43
|
-
path.join(home,
|
|
44
|
-
path.join(home,
|
|
43
|
+
path.join(home, "AppData/Local/Programs/Python/Python3*/Scripts"),
|
|
44
|
+
path.join(home, "AppData/Roaming/npm"),
|
|
45
45
|
]
|
|
46
46
|
: [
|
|
47
|
-
path.join(home,
|
|
48
|
-
path.join(home,
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
path.join(home, ".local/bin"),
|
|
48
|
+
path.join(home, ".cargo/bin"),
|
|
49
|
+
"/usr/local/bin",
|
|
50
|
+
"/opt/homebrew/bin",
|
|
51
51
|
];
|
|
52
52
|
}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import envPaths from
|
|
3
|
-
import winston from
|
|
4
|
-
import callsite from
|
|
5
|
-
import DailyRotateFile from
|
|
6
|
-
const paths = envPaths(
|
|
1
|
+
import path from "path";
|
|
2
|
+
import envPaths from "env-paths";
|
|
3
|
+
import winston from "winston";
|
|
4
|
+
import callsite from "callsite";
|
|
5
|
+
import DailyRotateFile from "winston-daily-rotate-file";
|
|
6
|
+
const paths = envPaths("ToolPlex", { suffix: "" });
|
|
7
7
|
export const logDir = path.join(paths.log);
|
|
8
8
|
function getCallingModule() {
|
|
9
9
|
const stack = callsite();
|
|
10
10
|
for (let i = 2; i < stack.length; i++) {
|
|
11
11
|
const fileName = stack[i].getFileName();
|
|
12
12
|
if (fileName &&
|
|
13
|
-
!fileName.includes(
|
|
14
|
-
!fileName.includes(
|
|
15
|
-
!fileName.includes(
|
|
13
|
+
!fileName.includes("node_modules") &&
|
|
14
|
+
!fileName.includes("fileLogger") &&
|
|
15
|
+
!fileName.includes("callsite")) {
|
|
16
16
|
return path.basename(fileName, path.extname(fileName));
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
return
|
|
19
|
+
return "unknown";
|
|
20
20
|
}
|
|
21
21
|
export class FileLogger {
|
|
22
22
|
static initialize(processName) {
|
|
23
23
|
if (this.logger)
|
|
24
24
|
return;
|
|
25
25
|
this.processName = processName;
|
|
26
|
-
const logLevel = process.env.LOG_LEVEL ||
|
|
26
|
+
const logLevel = process.env.LOG_LEVEL || "info";
|
|
27
27
|
this.transport = new DailyRotateFile({
|
|
28
28
|
dirname: logDir,
|
|
29
29
|
filename: `ToolPlex-${processName}-%DATE%.log`,
|
|
30
|
-
datePattern:
|
|
31
|
-
maxFiles:
|
|
30
|
+
datePattern: "YYYY-MM-DD",
|
|
31
|
+
maxFiles: "7d",
|
|
32
32
|
zippedArchive: false,
|
|
33
33
|
level: logLevel,
|
|
34
34
|
});
|
|
35
35
|
this.logger = winston.createLogger({
|
|
36
36
|
level: logLevel,
|
|
37
37
|
format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ level, message, timestamp, module }) => {
|
|
38
|
-
return `${timestamp} [${level.toUpperCase()}] ${module ||
|
|
38
|
+
return `${timestamp} [${level.toUpperCase()}] ${module || "unknown"} - ${message}`;
|
|
39
39
|
})),
|
|
40
40
|
defaultMeta: {},
|
|
41
41
|
transports: [this.transport],
|
|
@@ -46,20 +46,20 @@ export class FileLogger {
|
|
|
46
46
|
this.logger.log({ level, message, module });
|
|
47
47
|
}
|
|
48
48
|
static info(message) {
|
|
49
|
-
this.log(
|
|
49
|
+
this.log("info", message);
|
|
50
50
|
}
|
|
51
51
|
static warn(message) {
|
|
52
|
-
this.log(
|
|
52
|
+
this.log("warn", message);
|
|
53
53
|
}
|
|
54
54
|
static error(message) {
|
|
55
|
-
this.log(
|
|
55
|
+
this.log("error", message);
|
|
56
56
|
}
|
|
57
57
|
static debug(message) {
|
|
58
|
-
this.log(
|
|
58
|
+
this.log("debug", message);
|
|
59
59
|
}
|
|
60
60
|
static async flush() {
|
|
61
61
|
return new Promise((resolve) => {
|
|
62
|
-
this.transport.on(
|
|
62
|
+
this.transport.on("finish", resolve);
|
|
63
63
|
this.logger.end();
|
|
64
64
|
});
|
|
65
65
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
export type ClientMode =
|
|
3
|
-
export type LogLevel =
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export type ClientMode = "standard" | "restricted";
|
|
3
|
+
export type LogLevel = "error" | "warn" | "info" | "debug";
|
|
4
4
|
export interface ToolplexServerConfig {
|
|
5
5
|
dev: boolean;
|
|
6
6
|
apiKey: string;
|
|
7
7
|
clientMode: ClientMode;
|
|
8
|
+
clientName: string;
|
|
8
9
|
logLevel: LogLevel;
|
|
9
10
|
}
|
|
10
11
|
export declare const TransportTypeSchema: z.ZodEnum<["stdio", "sse"]>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/types/types.ts
|
|
2
|
-
import { z } from
|
|
2
|
+
import { z } from "zod";
|
|
3
3
|
// --------------------
|
|
4
4
|
// Enums
|
|
5
5
|
// --------------------
|
|
6
|
-
export const TransportTypeSchema = z.enum([
|
|
7
|
-
export const RuntimeSchema = z.enum([
|
|
6
|
+
export const TransportTypeSchema = z.enum(["stdio", "sse"]);
|
|
7
|
+
export const RuntimeSchema = z.enum(["node", "python", "go", "docker"]);
|
|
8
8
|
// --------------------
|
|
9
9
|
// LLMContext
|
|
10
10
|
// --------------------
|
|
@@ -41,14 +41,14 @@ export const InitializeToolplexParamsSchema = z.object({
|
|
|
41
41
|
export const SearchParamsSchema = z.object({
|
|
42
42
|
query: z.string(),
|
|
43
43
|
expanded_keywords: z.array(z.string()).optional(),
|
|
44
|
-
filter: z.enum([
|
|
44
|
+
filter: z.enum(["all", "servers_only", "playbooks_only"]).optional(),
|
|
45
45
|
size: z.number().int().min(1).max(25).optional(),
|
|
46
46
|
});
|
|
47
47
|
// --------------------
|
|
48
48
|
// LookupEntityParams
|
|
49
49
|
// --------------------
|
|
50
50
|
export const LookupEntityParamsSchema = z.object({
|
|
51
|
-
entity_type: z.enum([
|
|
51
|
+
entity_type: z.enum(["server", "playbook", "feedback"]),
|
|
52
52
|
entity_id: z.string(),
|
|
53
53
|
});
|
|
54
54
|
// --------------------
|
|
@@ -94,7 +94,14 @@ export const PlaybookActionSchema = z.object({
|
|
|
94
94
|
call: z.string().optional(),
|
|
95
95
|
args: z
|
|
96
96
|
.record(z.object({
|
|
97
|
-
type: z.enum([
|
|
97
|
+
type: z.enum([
|
|
98
|
+
"string",
|
|
99
|
+
"number",
|
|
100
|
+
"boolean",
|
|
101
|
+
"array",
|
|
102
|
+
"object",
|
|
103
|
+
"placeholder",
|
|
104
|
+
]),
|
|
98
105
|
example: z.any(),
|
|
99
106
|
}))
|
|
100
107
|
.optional(),
|
|
@@ -107,9 +114,9 @@ export const SavePlaybookParamsSchema = z.object({
|
|
|
107
114
|
// Requires at least one action to have a "call" property
|
|
108
115
|
actions: z
|
|
109
116
|
.array(PlaybookActionSchema)
|
|
110
|
-
.refine((actions) => actions.some((action) => typeof action.call ===
|
|
117
|
+
.refine((actions) => actions.some((action) => typeof action.call === "string" && action.call.length > 0), {
|
|
111
118
|
message: 'At least one action must include a "call" property',
|
|
112
|
-
path: [
|
|
119
|
+
path: ["actions"],
|
|
113
120
|
}),
|
|
114
121
|
domain: z.string().optional(),
|
|
115
122
|
keywords: z.array(z.string()).optional(),
|
|
@@ -129,9 +136,9 @@ export const LogPlaybookUsageParamsSchema = z.object({
|
|
|
129
136
|
// SubmitFeedbackParams
|
|
130
137
|
// --------------------
|
|
131
138
|
export const SubmitFeedbackParamsSchema = z.object({
|
|
132
|
-
target_type: z.enum([
|
|
139
|
+
target_type: z.enum(["server", "playbook"]),
|
|
133
140
|
target_id: z.string(),
|
|
134
|
-
vote: z.enum([
|
|
141
|
+
vote: z.enum(["up", "down"]),
|
|
135
142
|
message: z.string().optional(),
|
|
136
143
|
security_assessment: z
|
|
137
144
|
.object({
|
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
import { spawn } from
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
2
|
export class StdioServerManagerClient {
|
|
3
3
|
constructor(command, args, env) {
|
|
4
4
|
this.serverProcess = null;
|
|
5
5
|
this.messageHandlers = new Map();
|
|
6
|
-
this.messageBuffer =
|
|
6
|
+
this.messageBuffer = "";
|
|
7
7
|
this.command = command;
|
|
8
8
|
this.args = args;
|
|
9
9
|
this.env = env ? { ...process.env, ...env } : process.env;
|
|
10
10
|
}
|
|
11
11
|
async start() {
|
|
12
12
|
this.serverProcess = spawn(this.command, this.args, {
|
|
13
|
-
stdio: [
|
|
13
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
14
14
|
env: this.env,
|
|
15
15
|
});
|
|
16
16
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
-
this.serverProcess.on(
|
|
17
|
+
this.serverProcess.on("error", (err) => {
|
|
18
18
|
process.stderr.write(`Server process error: ${err}\n`);
|
|
19
19
|
});
|
|
20
|
-
if (!this.serverProcess.stderr ||
|
|
21
|
-
|
|
20
|
+
if (!this.serverProcess.stderr ||
|
|
21
|
+
!this.serverProcess.stdout ||
|
|
22
|
+
!this.serverProcess.stdin) {
|
|
23
|
+
throw new Error("Server process streams not available");
|
|
22
24
|
}
|
|
23
25
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
-
this.serverProcess.stderr.on(
|
|
26
|
+
this.serverProcess.stderr.on("data", (data) => {
|
|
25
27
|
process.stderr.write(data);
|
|
26
28
|
});
|
|
27
|
-
this.serverProcess.stdout.on(
|
|
29
|
+
this.serverProcess.stdout.on("data", (data) => {
|
|
28
30
|
this.messageBuffer += data.toString();
|
|
29
|
-
const lines = this.messageBuffer.split(
|
|
30
|
-
this.messageBuffer = lines.pop() ||
|
|
31
|
+
const lines = this.messageBuffer.split("\n");
|
|
32
|
+
this.messageBuffer = lines.pop() || "";
|
|
31
33
|
for (const line of lines) {
|
|
32
34
|
if (!line.trim())
|
|
33
35
|
continue;
|
|
@@ -45,12 +47,12 @@ export class StdioServerManagerClient {
|
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
});
|
|
48
|
-
this.serverProcess.on(
|
|
50
|
+
this.serverProcess.on("exit", () => {
|
|
49
51
|
for (const [, h] of this.messageHandlers)
|
|
50
|
-
h({ __error__: { message:
|
|
52
|
+
h({ __error__: { message: "Subprocess exited" } });
|
|
51
53
|
this.messageHandlers.clear();
|
|
52
54
|
this.serverProcess = null;
|
|
53
|
-
this.messageBuffer =
|
|
55
|
+
this.messageBuffer = "";
|
|
54
56
|
});
|
|
55
57
|
}
|
|
56
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -58,12 +60,12 @@ export class StdioServerManagerClient {
|
|
|
58
60
|
return new Promise((resolve, reject) => {
|
|
59
61
|
const id = Date.now();
|
|
60
62
|
if (!this.serverProcess?.stdin) {
|
|
61
|
-
reject(Error(
|
|
63
|
+
reject(Error("Server process not started"));
|
|
62
64
|
}
|
|
63
65
|
else {
|
|
64
66
|
this.messageHandlers.set(id, (frame) => {
|
|
65
67
|
if (frame.error || frame.__error__) {
|
|
66
|
-
const msg = frame.error?.message ?? frame.__error__?.message ??
|
|
68
|
+
const msg = frame.error?.message ?? frame.__error__?.message ?? "MCP error";
|
|
67
69
|
reject(new Error(msg));
|
|
68
70
|
}
|
|
69
71
|
else {
|
|
@@ -71,11 +73,11 @@ export class StdioServerManagerClient {
|
|
|
71
73
|
}
|
|
72
74
|
});
|
|
73
75
|
this.serverProcess.stdin.write(JSON.stringify({
|
|
74
|
-
jsonrpc:
|
|
76
|
+
jsonrpc: "2.0",
|
|
75
77
|
method,
|
|
76
78
|
params,
|
|
77
79
|
id,
|
|
78
|
-
}) +
|
|
80
|
+
}) + "\n");
|
|
79
81
|
}
|
|
80
82
|
setTimeout(() => {
|
|
81
83
|
if (this.messageHandlers.has(id)) {
|
|
@@ -90,7 +92,7 @@ export class StdioServerManagerClient {
|
|
|
90
92
|
this.serverProcess.kill();
|
|
91
93
|
this.serverProcess = null;
|
|
92
94
|
this.messageHandlers.clear();
|
|
93
|
-
this.messageBuffer =
|
|
95
|
+
this.messageBuffer = "";
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
98
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.
|
|
1
|
+
export declare const version = "0.1.1";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.
|
|
1
|
+
export const version = '0.1.1';
|