@toolplex/client 0.1.29 → 0.1.31

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.
@@ -13,6 +13,7 @@ const logLevel = process.env.LOG_LEVEL || "info";
13
13
  // These are provided by the host application (e.g., Electron desktop)
14
14
  const bundledDependencies = {
15
15
  node: process.env.TOOLPLEX_NODE_PATH,
16
+ npm: process.env.TOOLPLEX_NPM_PATH,
16
17
  npx: process.env.TOOLPLEX_NPX_PATH,
17
18
  python: process.env.TOOLPLEX_PYTHON_PATH,
18
19
  pip: process.env.TOOLPLEX_PIP_PATH,
@@ -46,7 +46,7 @@ declare class Registry {
46
46
  * Get the path for a specific bundled dependency by name.
47
47
  * Returns undefined if the dependency is not available.
48
48
  */
49
- static getBundledDependencyPath(depName: "node" | "python" | "git" | "uvx" | "npx"): string | undefined;
49
+ static getBundledDependencyPath(depName: "node" | "npm" | "python" | "git" | "uvx" | "npx"): string | undefined;
50
50
  /**
51
51
  * Set the server configuration (includes session resume history).
52
52
  */
@@ -52,9 +52,42 @@ export async function serve(config) {
52
52
  },
53
53
  });
54
54
  // Initialize server manager clients
55
+ // Use bundled node if available, otherwise fall back to system "node"
56
+ // Pass bundled dependency paths so the server-manager can initialize its Registry
55
57
  await logger.info("Initializing server manager clients");
58
+ const nodeCommand = config.bundledDependencies?.node || "node";
56
59
  const serverManagerClients = {
57
- node: new StdioServerManagerClient("node", [path.join(__dirname, "..", "server-manager", "index.js")], { LOG_LEVEL: config.logLevel }),
60
+ node: new StdioServerManagerClient(nodeCommand, [path.join(__dirname, "..", "server-manager", "index.js")], {
61
+ LOG_LEVEL: config.logLevel,
62
+ // Pass the current PATH which includes bundled bin directories
63
+ PATH: process.env.PATH,
64
+ // Pass all bundled dependency paths to server-manager
65
+ // These are critical for proper command resolution (e.g., npx -> node + npx-cli.js)
66
+ ...(config.bundledDependencies?.node && {
67
+ TOOLPLEX_NODE_PATH: config.bundledDependencies.node,
68
+ }),
69
+ ...(config.bundledDependencies?.npm && {
70
+ TOOLPLEX_NPM_PATH: config.bundledDependencies.npm,
71
+ }),
72
+ ...(config.bundledDependencies?.npx && {
73
+ TOOLPLEX_NPX_PATH: config.bundledDependencies.npx,
74
+ }),
75
+ ...(config.bundledDependencies?.python && {
76
+ TOOLPLEX_PYTHON_PATH: config.bundledDependencies.python,
77
+ }),
78
+ ...(config.bundledDependencies?.pip && {
79
+ TOOLPLEX_PIP_PATH: config.bundledDependencies.pip,
80
+ }),
81
+ ...(config.bundledDependencies?.uv && {
82
+ TOOLPLEX_UV_PATH: config.bundledDependencies.uv,
83
+ }),
84
+ ...(config.bundledDependencies?.uvx && {
85
+ TOOLPLEX_UVX_PATH: config.bundledDependencies.uvx,
86
+ }),
87
+ ...(config.bundledDependencies?.git && {
88
+ TOOLPLEX_GIT_PATH: config.bundledDependencies.git,
89
+ }),
90
+ }),
58
91
  };
59
92
  // Start all server manager clients
60
93
  await logger.info("Starting server manager clients");
@@ -1,12 +1,30 @@
1
+ /**
2
+ * Result of resolving a command, which may need to be invoked via node
3
+ * if it's a .js script (e.g., bundled npm/npx on Unix).
4
+ */
5
+ export interface ResolvedCommand {
6
+ command: string;
7
+ prependArgs: string[];
8
+ }
1
9
  export declare class RuntimeCheck {
10
+ /**
11
+ * Resolve a dependency and return both the command and any prepended args needed.
12
+ * This handles the case where bundled npm/npx on Unix are .js scripts that
13
+ * need to be invoked via node.
14
+ *
15
+ * @param commandName - The command to resolve (e.g., "npx", "node", "uvx")
16
+ * @returns ResolvedCommand with command and prependArgs
17
+ * @throws Error if the command is not available
18
+ */
19
+ static resolveCommandWithArgs(commandName: string): ResolvedCommand;
2
20
  /**
3
21
  * Resolve a dependency path with priority order:
4
22
  * 1. Bundled dependencies (if provided by host application like ToolPlex Desktop)
5
23
  * 2. System PATH (fallback for standalone @client usage)
6
24
  * 3. Error if neither available
7
25
  *
8
- * This allows ToolPlex Desktop to provide reliable bundled dependencies while
9
- * still supporting standalone users who have system dependencies installed.
26
+ * NOTE: This returns just the path. For npm/npx which may be .js files on Unix,
27
+ * use resolveCommandWithArgs() instead to get the proper invocation.
10
28
  *
11
29
  * @param commandName - The command to resolve
12
30
  * @returns The full path to the command executable
@@ -8,12 +8,14 @@ const INSTALL_HINTS = {
8
8
  python: "Install Python: https://www.python.org/downloads/. Or check if you have `python3` installed.",
9
9
  python3: "Install Python: https://www.python.org/downloads/. Or check if you have `python` installed.",
10
10
  node: "Install Node.js: https://nodejs.org/en/download/",
11
+ npm: "Install npm (comes with Node.js): https://nodejs.org/en/download/",
11
12
  npx: "Install npx (comes with Node.js): https://nodejs.org/en/download/",
12
13
  git: "Install Git: https://git-scm.com/downloads",
13
14
  };
14
15
  // Commands that should use bundled dependencies (required)
15
16
  const BUNDLED_DEPENDENCY_COMMANDS = [
16
17
  "node",
18
+ "npm",
17
19
  "python",
18
20
  "python3",
19
21
  "git",
@@ -22,44 +24,54 @@ const BUNDLED_DEPENDENCY_COMMANDS = [
22
24
  ];
23
25
  export class RuntimeCheck {
24
26
  /**
25
- * Resolve a dependency path with priority order:
26
- * 1. Bundled dependencies (if provided by host application like ToolPlex Desktop)
27
- * 2. System PATH (fallback for standalone @client usage)
28
- * 3. Error if neither available
29
- *
30
- * This allows ToolPlex Desktop to provide reliable bundled dependencies while
31
- * still supporting standalone users who have system dependencies installed.
27
+ * Resolve a dependency and return both the command and any prepended args needed.
28
+ * This handles the case where bundled npm/npx on Unix are .js scripts that
29
+ * need to be invoked via node.
32
30
  *
33
- * @param commandName - The command to resolve
34
- * @returns The full path to the command executable
35
- * @throws Error if the command is not available in bundled deps or system PATH
31
+ * @param commandName - The command to resolve (e.g., "npx", "node", "uvx")
32
+ * @returns ResolvedCommand with command and prependArgs
33
+ * @throws Error if the command is not available
36
34
  */
37
- static resolveDependency(commandName) {
38
- // Check if this is a known bundled dependency type
35
+ static resolveCommandWithArgs(commandName) {
39
36
  const isBundledDep = BUNDLED_DEPENDENCY_COMMANDS.includes(commandName);
40
37
  if (isBundledDep) {
41
- // Priority 1: Try bundled dependency first (preferred for ToolPlex Desktop)
38
+ // Priority 1: Try bundled dependency first
42
39
  const bundledPath = Registry.getBundledDependencyPath(commandName);
43
40
  if (bundledPath && fs.existsSync(bundledPath)) {
44
- return bundledPath;
41
+ // Check if this is a .js file that needs to be invoked via node
42
+ if (bundledPath.endsWith(".js")) {
43
+ const nodePath = Registry.getBundledDependencyPath("node");
44
+ if (nodePath && fs.existsSync(nodePath)) {
45
+ return {
46
+ command: nodePath,
47
+ prependArgs: [bundledPath],
48
+ };
49
+ }
50
+ // Fallback to system node if bundled node not available
51
+ return {
52
+ command: "node",
53
+ prependArgs: [bundledPath],
54
+ };
55
+ }
56
+ return { command: bundledPath, prependArgs: [] };
45
57
  }
46
- // Handle python3 -> python mapping for bundled deps
58
+ // Handle python3 -> python mapping
47
59
  if (commandName === "python3") {
48
60
  const pythonPath = Registry.getBundledDependencyPath("python");
49
61
  if (pythonPath && fs.existsSync(pythonPath)) {
50
- return pythonPath;
62
+ return { command: pythonPath, prependArgs: [] };
51
63
  }
52
64
  }
53
- // Priority 2: Fall back to system PATH (for standalone @client usage)
65
+ // Priority 2: Fall back to system PATH
54
66
  const enhancedPath = getEnhancedPath();
55
67
  const resolved = which.sync(commandName, {
56
68
  path: enhancedPath,
57
69
  nothrow: true,
58
70
  });
59
71
  if (resolved) {
60
- return resolved;
72
+ return { command: resolved, prependArgs: [] };
61
73
  }
62
- // Priority 3: Neither bundled nor system available - error
74
+ // Priority 3: Error
63
75
  const hint = INSTALL_HINTS[commandName];
64
76
  throw new Error(`Missing required command: '${commandName}'.\n` +
65
77
  `This command is not available in bundled dependencies or system PATH.\n` +
@@ -78,7 +90,28 @@ export class RuntimeCheck {
78
90
  }
79
91
  throw new Error(`Command '${commandName}' not found in enhanced PATH. Please install it manually or check your config.`);
80
92
  }
81
- return resolved;
93
+ return { command: resolved, prependArgs: [] };
94
+ }
95
+ /**
96
+ * Resolve a dependency path with priority order:
97
+ * 1. Bundled dependencies (if provided by host application like ToolPlex Desktop)
98
+ * 2. System PATH (fallback for standalone @client usage)
99
+ * 3. Error if neither available
100
+ *
101
+ * NOTE: This returns just the path. For npm/npx which may be .js files on Unix,
102
+ * use resolveCommandWithArgs() instead to get the proper invocation.
103
+ *
104
+ * @param commandName - The command to resolve
105
+ * @returns The full path to the command executable
106
+ * @throws Error if the command is not available in bundled deps or system PATH
107
+ */
108
+ static resolveDependency(commandName) {
109
+ const resolved = this.resolveCommandWithArgs(commandName);
110
+ // If there are prepend args, the first one is the actual script path
111
+ if (resolved.prependArgs.length > 0) {
112
+ return resolved.prependArgs[0];
113
+ }
114
+ return resolved.command;
82
115
  }
83
116
  /**
84
117
  * Validate that a command is available (either bundled or in system PATH).
@@ -1,6 +1,34 @@
1
1
  import { ServerManagerProtocol } from "./stdioServer.js";
2
2
  import { FileLogger } from "../shared/fileLogger.js";
3
+ import Registry from "../mcp-server/registry.js";
3
4
  FileLogger.initialize("server-manager");
5
+ // Initialize bundled dependencies from environment variables.
6
+ // These are passed from the MCP server process which received them from Electron.
7
+ // This is critical for proper command resolution (e.g., npx -> node + npx-cli.js).
8
+ //
9
+ // NOTE: We do NOT call Registry.init() here because that does heavy initialization
10
+ // (API services, caches, etc.) that the server-manager doesn't need. We only need
11
+ // the bundled dependency paths for command resolution.
12
+ function initializeBundledDeps() {
13
+ const bundledDependencies = {
14
+ node: process.env.TOOLPLEX_NODE_PATH,
15
+ npm: process.env.TOOLPLEX_NPM_PATH,
16
+ npx: process.env.TOOLPLEX_NPX_PATH,
17
+ python: process.env.TOOLPLEX_PYTHON_PATH,
18
+ pip: process.env.TOOLPLEX_PIP_PATH,
19
+ uv: process.env.TOOLPLEX_UV_PATH,
20
+ uvx: process.env.TOOLPLEX_UVX_PATH,
21
+ git: process.env.TOOLPLEX_GIT_PATH,
22
+ };
23
+ // Only set if we have at least one bundled dep
24
+ const hasAnyBundledDep = Object.values(bundledDependencies).some(Boolean);
25
+ if (hasAnyBundledDep) {
26
+ Registry.setBundledDependencies(bundledDependencies);
27
+ FileLogger.debug(`Server-manager initialized with bundled deps: ${JSON.stringify(bundledDependencies)}`);
28
+ }
29
+ }
30
+ // Initialize bundled deps and start
31
+ initializeBundledDeps();
4
32
  const protocol = new ServerManagerProtocol();
5
33
  protocol.start().catch((error) => {
6
34
  console.error("Failed to start server:", error);
@@ -6,6 +6,22 @@ import * as path from "path";
6
6
  import { FileLogger } from "../shared/fileLogger.js";
7
7
  import envPaths from "env-paths";
8
8
  import { getEnhancedPath } from "../shared/enhancedPath.js";
9
+ import { version } from "../version.js";
10
+ /**
11
+ * A permissive JSON Schema validator that doesn't fail on unresolved $ref.
12
+ * This is needed because MCP SDK 1.22.0 uses AJV which throws errors when
13
+ * output schemas have $ref references to $defs that aren't in the schema
14
+ * (e.g., "#/$defs/TextContent" from Pydantic/FastMCP-generated schemas).
15
+ */
16
+ class PermissiveJsonSchemaValidator {
17
+ getValidator(_schema) {
18
+ return (input) => ({
19
+ valid: true,
20
+ data: input,
21
+ errorMessage: undefined,
22
+ });
23
+ }
24
+ }
9
25
  const logger = FileLogger;
10
26
  export class ServerManager {
11
27
  constructor() {
@@ -242,18 +258,45 @@ export class ServerManager {
242
258
  else if (config.transport === "stdio") {
243
259
  if (!config.command)
244
260
  throw new Error("Command is required for stdio transport");
245
- // Use RuntimeCheck to resolve the command, which prioritizes bundled dependencies
246
- const { RuntimeCheck } = await import("../mcp-server/utils/runtimeCheck.js");
247
- // Extract command name first (handles paths with spaces correctly)
248
- const commandName = RuntimeCheck.extractCommandName(config.command);
249
- const resolvedCommand = RuntimeCheck.resolveDependency(commandName);
250
- const enhancedPath = getEnhancedPath();
261
+ // Use the inherited PATH from the parent process (MCP server -> Electron).
262
+ // This PATH already includes bundled bin directories prepended, so commands
263
+ // like "npx", "uvx", "git" will resolve to bundled versions first.
264
+ // We use process.env.PATH directly instead of rebuilding with getEnhancedPath()
265
+ // to preserve the bundled directories that were set up by Electron.
266
+ let inheritedPath = process.env.PATH || getEnhancedPath();
267
+ // When npx downloads and runs packages, it spawns child processes
268
+ // that need to find 'node' in PATH. The bundled node directory MUST be explicitly
269
+ // prepended to PATH to ensure child processes can find the node executable.
270
+ if (process.env.TOOLPLEX_NODE_PATH) {
271
+ const nodeDir = path.dirname(process.env.TOOLPLEX_NODE_PATH);
272
+ const pathDelimiter = process.platform === "win32" ? ";" : ":";
273
+ if (nodeDir && !inheritedPath.startsWith(nodeDir)) {
274
+ inheritedPath = nodeDir + pathDelimiter + inheritedPath;
275
+ }
276
+ }
277
+ // For the command itself, resolve it properly handling the case where
278
+ // bundled npm/npx on Unix are .js scripts that need to be invoked via node.
279
+ let resolvedCommand = config.command;
280
+ let prependArgs = [];
281
+ if (!config.command.startsWith("/") &&
282
+ !/^[A-Za-z]:[\\/]/.test(config.command)) {
283
+ // It's a relative command name (like "npx"), resolve via RuntimeCheck
284
+ const { RuntimeCheck } = await import("../mcp-server/utils/runtimeCheck.js");
285
+ const commandName = RuntimeCheck.extractCommandName(config.command);
286
+ const resolved = RuntimeCheck.resolveCommandWithArgs(commandName);
287
+ resolvedCommand = resolved.command;
288
+ prependArgs = resolved.prependArgs;
289
+ }
290
+ // Combine prependArgs with config.args
291
+ // e.g., if npx is a .js file: command="node", prependArgs=["/path/to/npx-cli.js"]
292
+ // then args become ["/path/to/npx-cli.js", "-y", "@wonderwhy-er/desktop-commander"]
293
+ const finalArgs = [...prependArgs, ...(config.args || [])];
251
294
  const serverParams = {
252
295
  command: resolvedCommand,
253
- args: config.args || [],
296
+ args: finalArgs,
254
297
  env: {
255
298
  ...process.env,
256
- PATH: enhancedPath,
299
+ PATH: inheritedPath,
257
300
  ...(config.env || {}),
258
301
  },
259
302
  stderr: "pipe",
@@ -263,7 +306,9 @@ export class ServerManager {
263
306
  else {
264
307
  throw new Error(`Invalid transport type: ${config.transport}`);
265
308
  }
266
- const client = new Client({ name: serverId, version: "1.0.0" }, { capabilities: { prompts: {}, resources: {}, tools: {} } });
309
+ const client = new Client({ name: serverId, version }, {
310
+ jsonSchemaValidator: new PermissiveJsonSchemaValidator(),
311
+ });
267
312
  try {
268
313
  const toolsResponse = await this.connectWithHandshakeTimeout(client, transport, 60000, stderrBuffer, serverId);
269
314
  const tools = toolsResponse.tools || [];
@@ -4,9 +4,14 @@ export type LogLevel = "error" | "warn" | "info" | "debug";
4
4
  /**
5
5
  * Paths to bundled dependencies provided by the host application (e.g., Electron).
6
6
  * These dependencies are required for MCP server installations and execution.
7
+ *
8
+ * NOTE: On Unix systems, npm/npx paths point to the actual CLI .js files
9
+ * (e.g., lib/node_modules/npm/bin/npx-cli.js) because electron-builder dereferences
10
+ * symlinks during packaging. These must be invoked via `node <script>`.
7
11
  */
8
12
  export interface BundledDependencies {
9
13
  node?: string;
14
+ npm?: string;
10
15
  npx?: string;
11
16
  python?: string;
12
17
  pip?: string;
@@ -8,12 +8,14 @@ const INSTALL_HINTS = {
8
8
  python: "Install Python: https://www.python.org/downloads/. Or check if you have `python3` installed.",
9
9
  python3: "Install Python: https://www.python.org/downloads/. Or check if you have `python` installed.",
10
10
  node: "Install Node.js: https://nodejs.org/en/download/",
11
+ npm: "Install npm (comes with Node.js): https://nodejs.org/en/download/",
11
12
  npx: "Install npx (comes with Node.js): https://nodejs.org/en/download/",
12
13
  git: "Install Git: https://git-scm.com/downloads",
13
14
  };
14
15
  // Commands that should use bundled dependencies (required)
15
16
  const BUNDLED_DEPENDENCY_COMMANDS = [
16
17
  "node",
18
+ "npm",
17
19
  "python",
18
20
  "python3",
19
21
  "git",
@@ -22,44 +24,54 @@ const BUNDLED_DEPENDENCY_COMMANDS = [
22
24
  ];
23
25
  export class RuntimeCheck {
24
26
  /**
25
- * Resolve a dependency path with priority order:
26
- * 1. Bundled dependencies (if provided by host application like ToolPlex Desktop)
27
- * 2. System PATH (fallback for standalone @client usage)
28
- * 3. Error if neither available
29
- *
30
- * This allows ToolPlex Desktop to provide reliable bundled dependencies while
31
- * still supporting standalone users who have system dependencies installed.
27
+ * Resolve a dependency and return both the command and any prepended args needed.
28
+ * This handles the case where bundled npm/npx on Unix are .js scripts that
29
+ * need to be invoked via node.
32
30
  *
33
- * @param commandName - The command to resolve
34
- * @returns The full path to the command executable
35
- * @throws Error if the command is not available in bundled deps or system PATH
31
+ * @param commandName - The command to resolve (e.g., "npx", "node", "uvx")
32
+ * @returns ResolvedCommand with command and prependArgs
33
+ * @throws Error if the command is not available
36
34
  */
37
- static resolveDependency(commandName) {
38
- // Check if this is a known bundled dependency type
35
+ static resolveCommandWithArgs(commandName) {
39
36
  const isBundledDep = BUNDLED_DEPENDENCY_COMMANDS.includes(commandName);
40
37
  if (isBundledDep) {
41
- // Priority 1: Try bundled dependency first (preferred for ToolPlex Desktop)
38
+ // Priority 1: Try bundled dependency first
42
39
  const bundledPath = Registry.getBundledDependencyPath(commandName);
43
40
  if (bundledPath && fs.existsSync(bundledPath)) {
44
- return bundledPath;
41
+ // Check if this is a .js file that needs to be invoked via node
42
+ if (bundledPath.endsWith(".js")) {
43
+ const nodePath = Registry.getBundledDependencyPath("node");
44
+ if (nodePath && fs.existsSync(nodePath)) {
45
+ return {
46
+ command: nodePath,
47
+ prependArgs: [bundledPath],
48
+ };
49
+ }
50
+ // Fallback to system node if bundled node not available
51
+ return {
52
+ command: "node",
53
+ prependArgs: [bundledPath],
54
+ };
55
+ }
56
+ return { command: bundledPath, prependArgs: [] };
45
57
  }
46
- // Handle python3 -> python mapping for bundled deps
58
+ // Handle python3 -> python mapping
47
59
  if (commandName === "python3") {
48
60
  const pythonPath = Registry.getBundledDependencyPath("python");
49
61
  if (pythonPath && fs.existsSync(pythonPath)) {
50
- return pythonPath;
62
+ return { command: pythonPath, prependArgs: [] };
51
63
  }
52
64
  }
53
- // Priority 2: Fall back to system PATH (for standalone @client usage)
65
+ // Priority 2: Fall back to system PATH
54
66
  const enhancedPath = getEnhancedPath();
55
67
  const resolved = which.sync(commandName, {
56
68
  path: enhancedPath,
57
69
  nothrow: true,
58
70
  });
59
71
  if (resolved) {
60
- return resolved;
72
+ return { command: resolved, prependArgs: [] };
61
73
  }
62
- // Priority 3: Neither bundled nor system available - error
74
+ // Priority 3: Error
63
75
  const hint = INSTALL_HINTS[commandName];
64
76
  throw new Error(`Missing required command: '${commandName}'.\n` +
65
77
  `This command is not available in bundled dependencies or system PATH.\n` +
@@ -78,7 +90,28 @@ export class RuntimeCheck {
78
90
  }
79
91
  throw new Error(`Command '${commandName}' not found in enhanced PATH. Please install it manually or check your config.`);
80
92
  }
81
- return resolved;
93
+ return { command: resolved, prependArgs: [] };
94
+ }
95
+ /**
96
+ * Resolve a dependency path with priority order:
97
+ * 1. Bundled dependencies (if provided by host application like ToolPlex Desktop)
98
+ * 2. System PATH (fallback for standalone @client usage)
99
+ * 3. Error if neither available
100
+ *
101
+ * NOTE: This returns just the path. For npm/npx which may be .js files on Unix,
102
+ * use resolveCommandWithArgs() instead to get the proper invocation.
103
+ *
104
+ * @param commandName - The command to resolve
105
+ * @returns The full path to the command executable
106
+ * @throws Error if the command is not available in bundled deps or system PATH
107
+ */
108
+ static resolveDependency(commandName) {
109
+ const resolved = this.resolveCommandWithArgs(commandName);
110
+ // If there are prepend args, the first one is the actual script path
111
+ if (resolved.prependArgs.length > 0) {
112
+ return resolved.prependArgs[0];
113
+ }
114
+ return resolved.command;
82
115
  }
83
116
  /**
84
117
  * Validate that a command is available (either bundled or in system PATH).
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.1.29";
1
+ export declare const version = "0.1.31";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '0.1.29';
1
+ export const version = '0.1.31';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolplex/client",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "author": "ToolPlex LLC",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "description": "The official ToolPlex client for AI agent tool discovery and execution",
@@ -44,7 +44,7 @@
44
44
  "ai-integration"
45
45
  ],
46
46
  "dependencies": {
47
- "@modelcontextprotocol/sdk": "^1.7.0",
47
+ "@modelcontextprotocol/sdk": "^1.22.0",
48
48
  "@types/node": "^22.13.11",
49
49
  "@types/node-fetch": "^2.6.12",
50
50
  "@types/which": "^3.0.4",