@agiflowai/one-mcp 0.2.4 → 0.2.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/README.md CHANGED
@@ -192,6 +192,135 @@ filesystem:
192
192
  read_file, list_directory, search_files
193
193
  ```
194
194
 
195
+ ### Skills
196
+
197
+ Skills are reusable prompt templates that provide specialized capabilities to AI agents. They are markdown files with YAML frontmatter that get loaded and made available through the `describe_tools` output.
198
+
199
+ #### Configuration
200
+
201
+ Enable skills by adding a `skills` section to your config:
202
+
203
+ ```yaml
204
+ mcpServers:
205
+ # ... your MCP servers
206
+
207
+ skills:
208
+ paths:
209
+ - ".claude/skills" # Relative to config file
210
+ - "/absolute/path/to/skills" # Absolute paths also supported
211
+ ```
212
+
213
+ #### Skill File Structure
214
+
215
+ Skills can be organized in two ways:
216
+
217
+ **Flat structure:**
218
+ ```
219
+ .claude/skills/
220
+ ├── pdf/
221
+ │ └── SKILL.md
222
+ └── data-analysis/
223
+ └── SKILL.md
224
+ ```
225
+
226
+ **Skill file format (`SKILL.md`):**
227
+ ```markdown
228
+ ---
229
+ name: pdf
230
+ description: Create and manipulate PDF documents
231
+ ---
232
+
233
+ # PDF Skill
234
+
235
+ This skill helps you work with PDF files...
236
+
237
+ ## Usage
238
+ ...
239
+ ```
240
+
241
+ #### Required Frontmatter
242
+
243
+ Each `SKILL.md` must have:
244
+ - `name`: Unique identifier for the skill
245
+ - `description`: Brief description shown to AI agents
246
+
247
+ #### How Skills Work
248
+
249
+ 1. Skills are discovered from configured paths at startup
250
+ 2. Available skills are listed in the `describe_tools` output
251
+ 3. AI agents can invoke skills by name (e.g., `skill: "pdf"`)
252
+ 4. The skill's content expands as a prompt providing specialized instructions
253
+
254
+ #### Precedence
255
+
256
+ When multiple paths are configured, skills from earlier paths take precedence over skills with the same name from later paths.
257
+
258
+ ### Prompt-Based Skills
259
+
260
+ You can also convert MCP server prompts into skills. This allows you to expose prompts from MCP servers as executable skills that AI agents can invoke.
261
+
262
+ #### Configuration
263
+
264
+ Add a `prompts` section under a server's `config`:
265
+
266
+ ```yaml
267
+ mcpServers:
268
+ my-server:
269
+ command: npx
270
+ args:
271
+ - -y
272
+ - "@mycompany/mcp-server"
273
+ config:
274
+ instruction: "My MCP server"
275
+ prompts:
276
+ code-review:
277
+ skill:
278
+ name: code-reviewer
279
+ description: "Review code for best practices and potential issues"
280
+ folder: "./prompts/code-review" # Optional: resource folder
281
+ documentation:
282
+ skill:
283
+ name: doc-generator
284
+ description: "Generate documentation from code"
285
+ ```
286
+
287
+ #### How Prompt-Based Skills Work
288
+
289
+ 1. **Configuration**: Define which prompts should be exposed as skills in the server config
290
+ 2. **Discovery**: Prompt-based skills appear alongside file-based skills in `describe_tools`
291
+ 3. **Invocation**: When an AI agent requests a prompt-based skill, one-mcp:
292
+ - Fetches the prompt content from the MCP server
293
+ - Returns the prompt messages as skill instructions
294
+ 4. **Execution**: The AI agent follows the skill instructions
295
+
296
+ #### Skill Configuration Fields
297
+
298
+ | Field | Required | Description |
299
+ |-------|----------|-------------|
300
+ | `name` | Yes | Unique skill identifier shown to AI agents |
301
+ | `description` | Yes | Brief description of what the skill does |
302
+ | `folder` | No | Optional folder path for skill resources |
303
+
304
+ #### Example Use Case
305
+
306
+ Convert a complex prompt from an MCP server into a reusable skill:
307
+
308
+ ```yaml
309
+ mcpServers:
310
+ architect-mcp:
311
+ command: npx
312
+ args: ["-y", "@agiflowai/architect-mcp", "mcp-serve"]
313
+ config:
314
+ instruction: "Architecture and design patterns"
315
+ prompts:
316
+ design-review:
317
+ skill:
318
+ name: design-reviewer
319
+ description: "Review code architecture and suggest improvements"
320
+ ```
321
+
322
+ When the AI agent invokes `design-reviewer`, it receives the full prompt content from `architect-mcp`'s `design-review` prompt, enabling sophisticated code review capabilities.
323
+
195
324
  ---
196
325
 
197
326
  ## MCP Tools
package/dist/cli.cjs CHANGED
@@ -1,21 +1,20 @@
1
1
  #!/usr/bin/env node
2
- const require_http = require('./http-3v8zyDO3.cjs');
2
+ const require_http = require('./http-xSfxBa8A.cjs');
3
3
  let node_fs_promises = require("node:fs/promises");
4
4
  let node_path = require("node:path");
5
+ let liquidjs = require("liquidjs");
5
6
  let commander = require("commander");
6
7
  let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
7
- let liquidjs = require("liquidjs");
8
8
 
9
9
  //#region src/types/index.ts
10
10
  /**
11
- * Transport mode types
11
+ * Transport mode constants
12
12
  */
13
- let TransportMode = /* @__PURE__ */ function(TransportMode$1) {
14
- TransportMode$1["STDIO"] = "stdio";
15
- TransportMode$1["HTTP"] = "http";
16
- TransportMode$1["SSE"] = "sse";
17
- return TransportMode$1;
18
- }({});
13
+ const TRANSPORT_MODE = {
14
+ STDIO: "stdio",
15
+ HTTP: "http",
16
+ SSE: "sse"
17
+ };
19
18
 
20
19
  //#endregion
21
20
  //#region src/commands/mcp-serve.ts
@@ -40,7 +39,16 @@ let TransportMode = /* @__PURE__ */ function(TransportMode$1) {
40
39
  * - Not cleaning up resources on shutdown
41
40
  */
42
41
  /**
42
+ * Type guard to validate transport type
43
+ * @param type - The transport type string to validate
44
+ * @returns True if the type is a valid transport type
45
+ */
46
+ function isValidTransportType(type) {
47
+ return type === "stdio" || type === "http" || type === "sse";
48
+ }
49
+ /**
43
50
  * Start MCP server with given transport handler
51
+ * @param handler - The transport handler to start
44
52
  */
45
53
  async function startServer(handler) {
46
54
  await handler.start();
@@ -60,30 +68,30 @@ async function startServer(handler) {
60
68
  /**
61
69
  * MCP Serve command
62
70
  */
63
- const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Force reload configuration from source, bypassing cache").action(async (options) => {
71
+ const mcpServeCommand = new commander.Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").action(async (options) => {
72
+ const transportType = options.type.toLowerCase();
73
+ if (!isValidTransportType(transportType)) {
74
+ console.error(`Unknown transport type: '${transportType}'. Valid options: stdio, http, sse`);
75
+ process.exit(1);
76
+ }
64
77
  try {
65
- const transportType = options.type.toLowerCase();
66
78
  const serverOptions = {
67
- configFilePath: options.config || require_http.findConfigFile(),
79
+ configFilePath: options.config || require_http.findConfigFile() || void 0,
68
80
  noCache: options.cache === false
69
81
  };
70
82
  if (transportType === "stdio") await startServer(new require_http.StdioTransportHandler(await require_http.createServer(serverOptions)));
71
83
  else if (transportType === "http") await startServer(new require_http.HttpTransportHandler(await require_http.createServer(serverOptions), {
72
- mode: TransportMode.HTTP,
84
+ mode: TRANSPORT_MODE.HTTP,
73
85
  port: options.port || Number(process.env.MCP_PORT) || 3e3,
74
86
  host: options.host || process.env.MCP_HOST || "localhost"
75
87
  }));
76
88
  else if (transportType === "sse") await startServer(new require_http.SseTransportHandler(await require_http.createServer(serverOptions), {
77
- mode: TransportMode.SSE,
89
+ mode: TRANSPORT_MODE.SSE,
78
90
  port: options.port || Number(process.env.MCP_PORT) || 3e3,
79
91
  host: options.host || process.env.MCP_HOST || "localhost"
80
92
  }));
81
- else {
82
- console.error(`Unknown transport type: ${transportType}. Use: stdio, http, or sse`);
83
- process.exit(1);
84
- }
85
93
  } catch (error) {
86
- console.error("Failed to start MCP server:", error);
94
+ console.error(`Failed to start MCP server with transport '${transportType}' on ${options.host}:${options.port}:`, error);
87
95
  process.exit(1);
88
96
  }
89
97
  });
@@ -213,7 +221,11 @@ const describeToolsCommand = new commander.Command("describe-tools").description
213
221
  console.error("No MCP servers connected");
214
222
  process.exit(1);
215
223
  }
224
+ const cwd = process.env.PROJECT_PATH || process.cwd();
225
+ const skillPaths = config.skills?.paths || [];
226
+ const skillService = skillPaths.length > 0 ? new require_http.SkillService(cwd, skillPaths) : void 0;
216
227
  const foundTools = [];
228
+ const foundSkills = [];
217
229
  const notFoundTools = [...toolNames];
218
230
  for (const client of clients) {
219
231
  if (options.server && client.serverName !== options.server) continue;
@@ -236,8 +248,30 @@ const describeToolsCommand = new commander.Command("describe-tools").description
236
248
  if (!options.json) console.error(`Failed to list tools from ${client.serverName}:`, error);
237
249
  }
238
250
  }
251
+ if (skillService && notFoundTools.length > 0) {
252
+ const skillsToCheck = [...notFoundTools];
253
+ for (const toolName of skillsToCheck) {
254
+ const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
255
+ const skill = await skillService.getSkill(skillName);
256
+ if (skill) {
257
+ foundSkills.push({
258
+ name: skill.name,
259
+ location: skill.basePath,
260
+ instructions: skill.content
261
+ });
262
+ const idx = notFoundTools.indexOf(toolName);
263
+ if (idx > -1) notFoundTools.splice(idx, 1);
264
+ }
265
+ }
266
+ }
267
+ const nextSteps = [];
268
+ if (foundTools.length > 0) nextSteps.push("For MCP tools: Use the use_tool function with toolName and toolArgs based on the inputSchema above.");
269
+ if (foundSkills.length > 0) nextSteps.push(`For skill, just follow skill's description to continue.`);
239
270
  if (options.json) {
240
- const result = { tools: foundTools };
271
+ const result = {};
272
+ if (foundTools.length > 0) result.tools = foundTools;
273
+ if (foundSkills.length > 0) result.skills = foundSkills;
274
+ if (nextSteps.length > 0) result.nextSteps = nextSteps;
241
275
  if (notFoundTools.length > 0) result.notFound = notFoundTools;
242
276
  console.log(JSON.stringify(result, null, 2));
243
277
  } else {
@@ -252,9 +286,23 @@ const describeToolsCommand = new commander.Command("describe-tools").description
252
286
  console.log("");
253
287
  }
254
288
  }
255
- if (notFoundTools.length > 0) console.error(`\nTools not found: ${notFoundTools.join(", ")}`);
256
- if (foundTools.length === 0) {
257
- console.error("No tools found");
289
+ if (foundSkills.length > 0) {
290
+ console.log("\nFound skills:\n");
291
+ for (const skill of foundSkills) {
292
+ console.log(`Skill: ${skill.name}`);
293
+ console.log(`Location: ${skill.location}`);
294
+ console.log(`Instructions:\n${skill.instructions}`);
295
+ console.log("");
296
+ }
297
+ }
298
+ if (nextSteps.length > 0) {
299
+ console.log("\nNext steps:");
300
+ for (const step of nextSteps) console.log(` • ${step}`);
301
+ console.log("");
302
+ }
303
+ if (notFoundTools.length > 0) console.error(`\nTools/skills not found: ${notFoundTools.join(", ")}`);
304
+ if (foundTools.length === 0 && foundSkills.length === 0) {
305
+ console.error("No tools or skills found");
258
306
  process.exit(1);
259
307
  }
260
308
  }
@@ -355,7 +403,29 @@ const useToolCommand = new commander.Command("use-tool").description("Execute an
355
403
  if (!options.json) console.error(`Failed to list tools from ${client$1.serverName}:`, error);
356
404
  }
357
405
  if (matchingServers.length === 0) {
358
- console.error(`Tool "${toolName}" not found on any connected server`);
406
+ const cwd = process.env.PROJECT_PATH || process.cwd();
407
+ const skillPaths = config.skills?.paths || [];
408
+ if (skillPaths.length > 0) try {
409
+ const skillService = new require_http.SkillService(cwd, skillPaths);
410
+ const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
411
+ const skill = await skillService.getSkill(skillName);
412
+ if (skill) {
413
+ const result = { content: [{
414
+ type: "text",
415
+ text: skill.content
416
+ }] };
417
+ if (options.json) console.log(JSON.stringify(result, null, 2));
418
+ else {
419
+ console.log("\nSkill content:");
420
+ console.log(skill.content);
421
+ }
422
+ await clientManager.disconnectAll();
423
+ return;
424
+ }
425
+ } catch (error) {
426
+ if (!options.json) console.error(`Failed to lookup skill "${toolName}":`, error);
427
+ }
428
+ console.error(`Tool or skill "${toolName}" not found on any connected server or configured skill paths`);
359
429
  await clientManager.disconnectAll();
360
430
  process.exit(1);
361
431
  }
@@ -478,7 +548,7 @@ const initCommand = new commander.Command("init").description("Initialize MCP co
478
548
 
479
549
  //#endregion
480
550
  //#region package.json
481
- var version = "0.2.3";
551
+ var version = "0.2.5";
482
552
 
483
553
  //#endregion
484
554
  //#region src/cli.ts
package/dist/cli.mjs CHANGED
@@ -1,21 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import { a as findConfigFile, i as createServer, n as SseTransportHandler, o as McpClientManagerService, r as StdioTransportHandler, s as ConfigFetcherService, t as HttpTransportHandler } from "./http-CzQfsUEI.mjs";
2
+ import { a as findConfigFile, c as ConfigFetcherService, i as createServer, n as SseTransportHandler, o as SkillService, r as StdioTransportHandler, s as McpClientManagerService, t as HttpTransportHandler } from "./http-D9BDXhHn.mjs";
3
3
  import { writeFile } from "node:fs/promises";
4
4
  import { resolve } from "node:path";
5
+ import { Liquid } from "liquidjs";
5
6
  import { Command } from "commander";
6
7
  import { log } from "@agiflowai/aicode-utils";
7
- import { Liquid } from "liquidjs";
8
8
 
9
9
  //#region src/types/index.ts
10
10
  /**
11
- * Transport mode types
11
+ * Transport mode constants
12
12
  */
13
- let TransportMode = /* @__PURE__ */ function(TransportMode$1) {
14
- TransportMode$1["STDIO"] = "stdio";
15
- TransportMode$1["HTTP"] = "http";
16
- TransportMode$1["SSE"] = "sse";
17
- return TransportMode$1;
18
- }({});
13
+ const TRANSPORT_MODE = {
14
+ STDIO: "stdio",
15
+ HTTP: "http",
16
+ SSE: "sse"
17
+ };
19
18
 
20
19
  //#endregion
21
20
  //#region src/commands/mcp-serve.ts
@@ -40,7 +39,16 @@ let TransportMode = /* @__PURE__ */ function(TransportMode$1) {
40
39
  * - Not cleaning up resources on shutdown
41
40
  */
42
41
  /**
42
+ * Type guard to validate transport type
43
+ * @param type - The transport type string to validate
44
+ * @returns True if the type is a valid transport type
45
+ */
46
+ function isValidTransportType(type) {
47
+ return type === "stdio" || type === "http" || type === "sse";
48
+ }
49
+ /**
43
50
  * Start MCP server with given transport handler
51
+ * @param handler - The transport handler to start
44
52
  */
45
53
  async function startServer(handler) {
46
54
  await handler.start();
@@ -60,30 +68,30 @@ async function startServer(handler) {
60
68
  /**
61
69
  * MCP Serve command
62
70
  */
63
- const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Force reload configuration from source, bypassing cache").action(async (options) => {
71
+ const mcpServeCommand = new Command("mcp-serve").description("Start MCP server with specified transport").option("-t, --type <type>", "Transport type: stdio, http, or sse", "stdio").option("-p, --port <port>", "Port to listen on (http/sse only)", (val) => parseInt(val, 10), 3e3).option("--host <host>", "Host to bind to (http/sse only)", "localhost").option("-c, --config <path>", "Path to MCP server configuration file").option("--no-cache", "Disable configuration caching, always reload from config file").action(async (options) => {
72
+ const transportType = options.type.toLowerCase();
73
+ if (!isValidTransportType(transportType)) {
74
+ console.error(`Unknown transport type: '${transportType}'. Valid options: stdio, http, sse`);
75
+ process.exit(1);
76
+ }
64
77
  try {
65
- const transportType = options.type.toLowerCase();
66
78
  const serverOptions = {
67
- configFilePath: options.config || findConfigFile(),
79
+ configFilePath: options.config || findConfigFile() || void 0,
68
80
  noCache: options.cache === false
69
81
  };
70
82
  if (transportType === "stdio") await startServer(new StdioTransportHandler(await createServer(serverOptions)));
71
83
  else if (transportType === "http") await startServer(new HttpTransportHandler(await createServer(serverOptions), {
72
- mode: TransportMode.HTTP,
84
+ mode: TRANSPORT_MODE.HTTP,
73
85
  port: options.port || Number(process.env.MCP_PORT) || 3e3,
74
86
  host: options.host || process.env.MCP_HOST || "localhost"
75
87
  }));
76
88
  else if (transportType === "sse") await startServer(new SseTransportHandler(await createServer(serverOptions), {
77
- mode: TransportMode.SSE,
89
+ mode: TRANSPORT_MODE.SSE,
78
90
  port: options.port || Number(process.env.MCP_PORT) || 3e3,
79
91
  host: options.host || process.env.MCP_HOST || "localhost"
80
92
  }));
81
- else {
82
- console.error(`Unknown transport type: ${transportType}. Use: stdio, http, or sse`);
83
- process.exit(1);
84
- }
85
93
  } catch (error) {
86
- console.error("Failed to start MCP server:", error);
94
+ console.error(`Failed to start MCP server with transport '${transportType}' on ${options.host}:${options.port}:`, error);
87
95
  process.exit(1);
88
96
  }
89
97
  });
@@ -213,7 +221,11 @@ const describeToolsCommand = new Command("describe-tools").description("Describe
213
221
  console.error("No MCP servers connected");
214
222
  process.exit(1);
215
223
  }
224
+ const cwd = process.env.PROJECT_PATH || process.cwd();
225
+ const skillPaths = config.skills?.paths || [];
226
+ const skillService = skillPaths.length > 0 ? new SkillService(cwd, skillPaths) : void 0;
216
227
  const foundTools = [];
228
+ const foundSkills = [];
217
229
  const notFoundTools = [...toolNames];
218
230
  for (const client of clients) {
219
231
  if (options.server && client.serverName !== options.server) continue;
@@ -236,8 +248,30 @@ const describeToolsCommand = new Command("describe-tools").description("Describe
236
248
  if (!options.json) console.error(`Failed to list tools from ${client.serverName}:`, error);
237
249
  }
238
250
  }
251
+ if (skillService && notFoundTools.length > 0) {
252
+ const skillsToCheck = [...notFoundTools];
253
+ for (const toolName of skillsToCheck) {
254
+ const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
255
+ const skill = await skillService.getSkill(skillName);
256
+ if (skill) {
257
+ foundSkills.push({
258
+ name: skill.name,
259
+ location: skill.basePath,
260
+ instructions: skill.content
261
+ });
262
+ const idx = notFoundTools.indexOf(toolName);
263
+ if (idx > -1) notFoundTools.splice(idx, 1);
264
+ }
265
+ }
266
+ }
267
+ const nextSteps = [];
268
+ if (foundTools.length > 0) nextSteps.push("For MCP tools: Use the use_tool function with toolName and toolArgs based on the inputSchema above.");
269
+ if (foundSkills.length > 0) nextSteps.push(`For skill, just follow skill's description to continue.`);
239
270
  if (options.json) {
240
- const result = { tools: foundTools };
271
+ const result = {};
272
+ if (foundTools.length > 0) result.tools = foundTools;
273
+ if (foundSkills.length > 0) result.skills = foundSkills;
274
+ if (nextSteps.length > 0) result.nextSteps = nextSteps;
241
275
  if (notFoundTools.length > 0) result.notFound = notFoundTools;
242
276
  console.log(JSON.stringify(result, null, 2));
243
277
  } else {
@@ -252,9 +286,23 @@ const describeToolsCommand = new Command("describe-tools").description("Describe
252
286
  console.log("");
253
287
  }
254
288
  }
255
- if (notFoundTools.length > 0) console.error(`\nTools not found: ${notFoundTools.join(", ")}`);
256
- if (foundTools.length === 0) {
257
- console.error("No tools found");
289
+ if (foundSkills.length > 0) {
290
+ console.log("\nFound skills:\n");
291
+ for (const skill of foundSkills) {
292
+ console.log(`Skill: ${skill.name}`);
293
+ console.log(`Location: ${skill.location}`);
294
+ console.log(`Instructions:\n${skill.instructions}`);
295
+ console.log("");
296
+ }
297
+ }
298
+ if (nextSteps.length > 0) {
299
+ console.log("\nNext steps:");
300
+ for (const step of nextSteps) console.log(` • ${step}`);
301
+ console.log("");
302
+ }
303
+ if (notFoundTools.length > 0) console.error(`\nTools/skills not found: ${notFoundTools.join(", ")}`);
304
+ if (foundTools.length === 0 && foundSkills.length === 0) {
305
+ console.error("No tools or skills found");
258
306
  process.exit(1);
259
307
  }
260
308
  }
@@ -355,7 +403,29 @@ const useToolCommand = new Command("use-tool").description("Execute an MCP tool
355
403
  if (!options.json) console.error(`Failed to list tools from ${client$1.serverName}:`, error);
356
404
  }
357
405
  if (matchingServers.length === 0) {
358
- console.error(`Tool "${toolName}" not found on any connected server`);
406
+ const cwd = process.env.PROJECT_PATH || process.cwd();
407
+ const skillPaths = config.skills?.paths || [];
408
+ if (skillPaths.length > 0) try {
409
+ const skillService = new SkillService(cwd, skillPaths);
410
+ const skillName = toolName.startsWith("skill__") ? toolName.slice(7) : toolName;
411
+ const skill = await skillService.getSkill(skillName);
412
+ if (skill) {
413
+ const result = { content: [{
414
+ type: "text",
415
+ text: skill.content
416
+ }] };
417
+ if (options.json) console.log(JSON.stringify(result, null, 2));
418
+ else {
419
+ console.log("\nSkill content:");
420
+ console.log(skill.content);
421
+ }
422
+ await clientManager.disconnectAll();
423
+ return;
424
+ }
425
+ } catch (error) {
426
+ if (!options.json) console.error(`Failed to lookup skill "${toolName}":`, error);
427
+ }
428
+ console.error(`Tool or skill "${toolName}" not found on any connected server or configured skill paths`);
359
429
  await clientManager.disconnectAll();
360
430
  process.exit(1);
361
431
  }
@@ -478,7 +548,7 @@ const initCommand = new Command("init").description("Initialize MCP configuratio
478
548
 
479
549
  //#endregion
480
550
  //#region package.json
481
- var version = "0.2.3";
551
+ var version = "0.2.5";
482
552
 
483
553
  //#endregion
484
554
  //#region src/cli.ts