@agiflowai/one-mcp 0.2.5 → 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 +129 -0
- package/dist/cli.cjs +2 -2
- package/dist/cli.mjs +2 -2
- package/dist/{http-BKDyW8YB.mjs → http-D9BDXhHn.mjs} +241 -29
- package/dist/{http-Q8LPwwwP.cjs → http-xSfxBa8A.cjs} +240 -28
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.mts +23 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -4
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,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_http = require('./http-
|
|
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
5
|
let liquidjs = require("liquidjs");
|
|
@@ -548,7 +548,7 @@ const initCommand = new commander.Command("init").description("Initialize MCP co
|
|
|
548
548
|
|
|
549
549
|
//#endregion
|
|
550
550
|
//#region package.json
|
|
551
|
-
var version = "0.2.
|
|
551
|
+
var version = "0.2.5";
|
|
552
552
|
|
|
553
553
|
//#endregion
|
|
554
554
|
//#region src/cli.ts
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
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-
|
|
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
5
|
import { Liquid } from "liquidjs";
|
|
@@ -548,7 +548,7 @@ const initCommand = new Command("init").description("Initialize MCP configuratio
|
|
|
548
548
|
|
|
549
549
|
//#endregion
|
|
550
550
|
//#region package.json
|
|
551
|
-
var version = "0.2.
|
|
551
|
+
var version = "0.2.5";
|
|
552
552
|
|
|
553
553
|
//#endregion
|
|
554
554
|
//#region src/cli.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
-
import { CallToolRequestSchema, ListToolsRequestSchema, isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema, isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import { access, mkdir, readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import yaml from "js-yaml";
|
|
@@ -175,10 +175,25 @@ function validateRemoteConfigSource(source) {
|
|
|
175
175
|
* Claude Code / Claude Desktop standard MCP config format
|
|
176
176
|
* This is the format users write in their config files
|
|
177
177
|
*/
|
|
178
|
+
/**
|
|
179
|
+
* Prompt skill configuration schema
|
|
180
|
+
* Converts a prompt to an executable skill
|
|
181
|
+
*/
|
|
182
|
+
const PromptSkillConfigSchema = z.object({
|
|
183
|
+
name: z.string(),
|
|
184
|
+
description: z.string(),
|
|
185
|
+
folder: z.string().optional()
|
|
186
|
+
});
|
|
187
|
+
/**
|
|
188
|
+
* Prompt configuration schema
|
|
189
|
+
* Supports converting prompts to skills
|
|
190
|
+
*/
|
|
191
|
+
const PromptConfigSchema = z.object({ skill: PromptSkillConfigSchema.optional() });
|
|
178
192
|
const AdditionalConfigSchema = z.object({
|
|
179
193
|
instruction: z.string().optional(),
|
|
180
194
|
toolBlacklist: z.array(z.string()).optional(),
|
|
181
|
-
omitToolDescription: z.boolean().optional()
|
|
195
|
+
omitToolDescription: z.boolean().optional(),
|
|
196
|
+
prompts: z.record(z.string(), PromptConfigSchema).optional()
|
|
182
197
|
}).optional();
|
|
183
198
|
const ClaudeCodeStdioServerSchema = z.object({
|
|
184
199
|
command: z.string(),
|
|
@@ -245,12 +260,25 @@ const McpSseConfigSchema = z.object({
|
|
|
245
260
|
url: z.string().url(),
|
|
246
261
|
headers: z.record(z.string(), z.string()).optional()
|
|
247
262
|
});
|
|
263
|
+
/**
|
|
264
|
+
* Internal prompt skill configuration schema
|
|
265
|
+
*/
|
|
266
|
+
const InternalPromptSkillConfigSchema = z.object({
|
|
267
|
+
name: z.string(),
|
|
268
|
+
description: z.string(),
|
|
269
|
+
folder: z.string().optional()
|
|
270
|
+
});
|
|
271
|
+
/**
|
|
272
|
+
* Internal prompt configuration schema
|
|
273
|
+
*/
|
|
274
|
+
const InternalPromptConfigSchema = z.object({ skill: InternalPromptSkillConfigSchema.optional() });
|
|
248
275
|
const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
249
276
|
z.object({
|
|
250
277
|
name: z.string(),
|
|
251
278
|
instruction: z.string().optional(),
|
|
252
279
|
toolBlacklist: z.array(z.string()).optional(),
|
|
253
280
|
omitToolDescription: z.boolean().optional(),
|
|
281
|
+
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
254
282
|
transport: z.literal("stdio"),
|
|
255
283
|
config: McpStdioConfigSchema
|
|
256
284
|
}),
|
|
@@ -259,6 +287,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
259
287
|
instruction: z.string().optional(),
|
|
260
288
|
toolBlacklist: z.array(z.string()).optional(),
|
|
261
289
|
omitToolDescription: z.boolean().optional(),
|
|
290
|
+
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
262
291
|
transport: z.literal("http"),
|
|
263
292
|
config: McpHttpConfigSchema
|
|
264
293
|
}),
|
|
@@ -267,6 +296,7 @@ const McpServerConfigSchema = z.discriminatedUnion("transport", [
|
|
|
267
296
|
instruction: z.string().optional(),
|
|
268
297
|
toolBlacklist: z.array(z.string()).optional(),
|
|
269
298
|
omitToolDescription: z.boolean().optional(),
|
|
299
|
+
prompts: z.record(z.string(), InternalPromptConfigSchema).optional(),
|
|
270
300
|
transport: z.literal("sse"),
|
|
271
301
|
config: McpSseConfigSchema
|
|
272
302
|
})
|
|
@@ -299,6 +329,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
299
329
|
instruction: stdioConfig.instruction || stdioConfig.config?.instruction,
|
|
300
330
|
toolBlacklist: stdioConfig.config?.toolBlacklist,
|
|
301
331
|
omitToolDescription: stdioConfig.config?.omitToolDescription,
|
|
332
|
+
prompts: stdioConfig.config?.prompts,
|
|
302
333
|
transport: "stdio",
|
|
303
334
|
config: {
|
|
304
335
|
command: interpolatedCommand,
|
|
@@ -316,6 +347,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
316
347
|
instruction: httpConfig.instruction || httpConfig.config?.instruction,
|
|
317
348
|
toolBlacklist: httpConfig.config?.toolBlacklist,
|
|
318
349
|
omitToolDescription: httpConfig.config?.omitToolDescription,
|
|
350
|
+
prompts: httpConfig.config?.prompts,
|
|
319
351
|
transport,
|
|
320
352
|
config: {
|
|
321
353
|
url: interpolatedUrl,
|
|
@@ -776,12 +808,14 @@ var ConfigFetcherService = class {
|
|
|
776
808
|
//#region src/services/McpClientManagerService.ts
|
|
777
809
|
/**
|
|
778
810
|
* MCP Client wrapper for managing individual server connections
|
|
811
|
+
* This is an internal class used by McpClientManagerService
|
|
779
812
|
*/
|
|
780
813
|
var McpClient = class {
|
|
781
814
|
serverName;
|
|
782
815
|
serverInstruction;
|
|
783
816
|
toolBlacklist;
|
|
784
817
|
omitToolDescription;
|
|
818
|
+
prompts;
|
|
785
819
|
transport;
|
|
786
820
|
client;
|
|
787
821
|
childProcess;
|
|
@@ -791,6 +825,7 @@ var McpClient = class {
|
|
|
791
825
|
this.serverInstruction = config.instruction;
|
|
792
826
|
this.toolBlacklist = config.toolBlacklist;
|
|
793
827
|
this.omitToolDescription = config.omitToolDescription;
|
|
828
|
+
this.prompts = config.prompts;
|
|
794
829
|
this.transport = transport;
|
|
795
830
|
this.client = client;
|
|
796
831
|
}
|
|
@@ -886,7 +921,8 @@ var McpClientManagerService = class {
|
|
|
886
921
|
const mcpClient = new McpClient(serverName, config.transport, client, {
|
|
887
922
|
instruction: config.instruction,
|
|
888
923
|
toolBlacklist: config.toolBlacklist,
|
|
889
|
-
omitToolDescription: config.omitToolDescription
|
|
924
|
+
omitToolDescription: config.omitToolDescription,
|
|
925
|
+
prompts: config.prompts
|
|
890
926
|
});
|
|
891
927
|
try {
|
|
892
928
|
await Promise.race([this.performConnection(mcpClient, config), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`Connection timeout after ${timeoutMs}ms`)), timeoutMs))]);
|
|
@@ -1289,11 +1325,11 @@ function parseToolName(toolName) {
|
|
|
1289
1325
|
|
|
1290
1326
|
//#endregion
|
|
1291
1327
|
//#region src/templates/skills-description.liquid?raw
|
|
1292
|
-
var skills_description_default = "{% if skills.size > 0 %}\n<skills>\n<instructions>\nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.\n\nHow to use skills:\n- Invoke skills using this tool with the skill name only (no arguments)\n- When you invoke a skill, you will see <command-message>The \"{name}\" skill is loading</command-message>\n- The skill's prompt will expand and provide detailed instructions on how to complete the task\n- Examples:\n - `skill: \"pdf\"` - invoke the pdf skill\n - `skill: \"xlsx\"` - invoke the xlsx skill\n - `skill: \"ms-office-suite:pdf\"` - invoke using fully qualified name\n\nImportant:\n- Only use skills listed in <available_skills> below\n- Do not invoke a skill that is already running\n- Do not use this tool for built-in CLI commands (like /help, /clear, etc.)\n</instructions>\n\n<available_skills>\n{% for skill in skills -%}\n<
|
|
1328
|
+
var skills_description_default = "{% if skills.size > 0 %}\n<skills>\n<instructions>\nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.\n\nHow to use skills:\n- Invoke skills using this tool with the skill name only (no arguments)\n- When you invoke a skill, you will see <command-message>The \"{name}\" skill is loading</command-message>\n- The skill's prompt will expand and provide detailed instructions on how to complete the task\n- Examples:\n - `skill: \"pdf\"` - invoke the pdf skill\n - `skill: \"xlsx\"` - invoke the xlsx skill\n - `skill: \"ms-office-suite:pdf\"` - invoke using fully qualified name\n\nImportant:\n- Only use skills listed in <available_skills> below\n- Do not invoke a skill that is already running\n- Do not use this tool for built-in CLI commands (like /help, /clear, etc.)\n</instructions>\n\n<available_skills>\n{% for skill in skills -%}\n<item><name>{{ skill.displayName }}</name><description>{{ skill.description }}</description></item>\n{% endfor -%}\n</available_skills>\n</skills>\n{% endif %}\n";
|
|
1293
1329
|
|
|
1294
1330
|
//#endregion
|
|
1295
1331
|
//#region src/templates/mcp-servers-description.liquid?raw
|
|
1296
|
-
var mcp_servers_description_default = "<mcp_servers>\n{% for server in servers -%}\n<server name=\"{{ server.name }}\">\n{% if server.instruction -%}\n<instruction>{{ server.instruction }}</instruction>\n{% endif -%}\n<tools>\n{% if server.omitToolDescription -%}\n{{ server.toolNames | join: \", \" }}\n{% else -%}\n{% for tool in server.tools -%}\n<
|
|
1332
|
+
var mcp_servers_description_default = "<mcp_servers>\n<instructions>\nBefore you use any tools above, you MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:\n- Arguments schema needed to pass to the tool use\n- Description about each tool\n\nThis tool is optimized for batch queries - you can request multiple tools at once for better performance.\n</instructions>\n\n{% for server in servers -%}\n<server name=\"{{ server.name }}\">\n{% if server.instruction -%}\n<instruction>{{ server.instruction }}</instruction>\n{% endif -%}\n<tools>\n{% if server.omitToolDescription -%}\n{{ server.toolNames | join: \", \" }}\n{% else -%}\n{% for tool in server.tools -%}\n<item><name>{{ tool.displayName }}</name><description>{{ tool.description | default: \"No description\" }}</description></item>\n{% endfor -%}\n{% endif -%}\n</tools>\n</server>\n{% endfor -%}\n</mcp_servers>\n";
|
|
1297
1333
|
|
|
1298
1334
|
//#endregion
|
|
1299
1335
|
//#region src/tools/DescribeToolsTool.ts
|
|
@@ -1333,20 +1369,96 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1333
1369
|
this.skillService = skillService;
|
|
1334
1370
|
}
|
|
1335
1371
|
/**
|
|
1372
|
+
* Collects skills derived from prompt configurations across all connected MCP servers.
|
|
1373
|
+
* Prompts with a skill configuration are converted to skill format for display.
|
|
1374
|
+
*
|
|
1375
|
+
* @returns Array of skill template data derived from prompts
|
|
1376
|
+
*/
|
|
1377
|
+
collectPromptSkills() {
|
|
1378
|
+
const clients = this.clientManager.getAllClients();
|
|
1379
|
+
const promptSkills = [];
|
|
1380
|
+
for (const client of clients) {
|
|
1381
|
+
if (!client.prompts) continue;
|
|
1382
|
+
for (const promptConfig of Object.values(client.prompts)) if (promptConfig.skill) promptSkills.push({
|
|
1383
|
+
name: promptConfig.skill.name,
|
|
1384
|
+
displayName: promptConfig.skill.name,
|
|
1385
|
+
description: promptConfig.skill.description
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
return promptSkills;
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Finds a prompt-based skill by name from all connected MCP servers.
|
|
1392
|
+
* Returns the prompt name and skill config for fetching the prompt content.
|
|
1393
|
+
*
|
|
1394
|
+
* @param skillName - The skill name to search for
|
|
1395
|
+
* @returns Object with serverName, promptName, and skill config, or undefined if not found
|
|
1396
|
+
*/
|
|
1397
|
+
findPromptSkill(skillName) {
|
|
1398
|
+
if (!skillName) return void 0;
|
|
1399
|
+
const clients = this.clientManager.getAllClients();
|
|
1400
|
+
for (const client of clients) {
|
|
1401
|
+
if (!client.prompts) continue;
|
|
1402
|
+
for (const [promptName, promptConfig] of Object.entries(client.prompts)) if (promptConfig.skill && promptConfig.skill.name === skillName) return {
|
|
1403
|
+
serverName: client.serverName,
|
|
1404
|
+
promptName,
|
|
1405
|
+
skill: promptConfig.skill
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Retrieves skill content from a prompt-based skill configuration.
|
|
1411
|
+
* Fetches the prompt from the MCP server and extracts text content.
|
|
1412
|
+
*
|
|
1413
|
+
* @param skillName - The skill name being requested
|
|
1414
|
+
* @returns SkillDescription if found and successfully fetched, undefined otherwise
|
|
1415
|
+
*/
|
|
1416
|
+
async getPromptSkillContent(skillName) {
|
|
1417
|
+
const promptSkill = this.findPromptSkill(skillName);
|
|
1418
|
+
if (!promptSkill) return void 0;
|
|
1419
|
+
const client = this.clientManager.getClient(promptSkill.serverName);
|
|
1420
|
+
if (!client) {
|
|
1421
|
+
console.error(`Client not found for server '${promptSkill.serverName}' when fetching prompt skill '${skillName}'`);
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
try {
|
|
1425
|
+
const instructions = (await client.getPrompt(promptSkill.promptName)).messages?.map((m) => {
|
|
1426
|
+
const content = m.content;
|
|
1427
|
+
if (typeof content === "string") return content;
|
|
1428
|
+
if (content && typeof content === "object" && "text" in content) return String(content.text);
|
|
1429
|
+
return "";
|
|
1430
|
+
}).join("\n") || "";
|
|
1431
|
+
return {
|
|
1432
|
+
name: promptSkill.skill.name,
|
|
1433
|
+
location: promptSkill.skill.folder || `prompt:${promptSkill.serverName}/${promptSkill.promptName}`,
|
|
1434
|
+
instructions
|
|
1435
|
+
};
|
|
1436
|
+
} catch (error) {
|
|
1437
|
+
console.error(`Failed to get prompt-based skill '${skillName}': ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
/**
|
|
1336
1442
|
* Builds the skills section of the tool description using a Liquid template.
|
|
1337
1443
|
*
|
|
1338
|
-
* Retrieves all available skills from the SkillService and
|
|
1339
|
-
* using the skills-description.liquid template. Skills are only
|
|
1340
|
-
* with skill__ when their name clashes with an MCP tool or another skill.
|
|
1444
|
+
* Retrieves all available skills from the SkillService and prompt-based skills,
|
|
1445
|
+
* then renders them using the skills-description.liquid template. Skills are only
|
|
1446
|
+
* prefixed with skill__ when their name clashes with an MCP tool or another skill.
|
|
1341
1447
|
*
|
|
1342
1448
|
* @param mcpToolNames - Set of MCP tool names to check for clashes
|
|
1343
1449
|
* @returns Rendered skills section string with available skills list
|
|
1344
1450
|
*/
|
|
1345
1451
|
async buildSkillsSection(mcpToolNames) {
|
|
1346
1452
|
const rawSkills = this.skillService ? await this.skillService.getSkills() : [];
|
|
1453
|
+
const promptSkills = this.collectPromptSkills();
|
|
1454
|
+
const allSkillsData = [...rawSkills.map((skill) => ({
|
|
1455
|
+
name: skill.name,
|
|
1456
|
+
displayName: skill.name,
|
|
1457
|
+
description: skill.description
|
|
1458
|
+
})), ...promptSkills];
|
|
1347
1459
|
const skillNameCounts = /* @__PURE__ */ new Map();
|
|
1348
|
-
for (const skill of
|
|
1349
|
-
const skills =
|
|
1460
|
+
for (const skill of allSkillsData) skillNameCounts.set(skill.name, (skillNameCounts.get(skill.name) || 0) + 1);
|
|
1461
|
+
const skills = allSkillsData.map((skill) => {
|
|
1350
1462
|
const clashesWithMcpTool = mcpToolNames.has(skill.name);
|
|
1351
1463
|
const clashesWithOtherSkill = (skillNameCounts.get(skill.name) || 0) > 1;
|
|
1352
1464
|
const needsPrefix = clashesWithMcpTool || clashesWithOtherSkill;
|
|
@@ -1504,13 +1616,21 @@ ${skillsSection}`,
|
|
|
1504
1616
|
const skillName = requestedName.slice(7);
|
|
1505
1617
|
if (this.skillService) {
|
|
1506
1618
|
const skill = await this.skillService.getSkill(skillName);
|
|
1507
|
-
if (skill)
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1619
|
+
if (skill) {
|
|
1620
|
+
foundSkills.push({
|
|
1621
|
+
name: skill.name,
|
|
1622
|
+
location: skill.basePath,
|
|
1623
|
+
instructions: skill.content
|
|
1624
|
+
});
|
|
1625
|
+
continue;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
const promptSkillContent = await this.getPromptSkillContent(skillName);
|
|
1629
|
+
if (promptSkillContent) {
|
|
1630
|
+
foundSkills.push(promptSkillContent);
|
|
1631
|
+
continue;
|
|
1632
|
+
}
|
|
1633
|
+
notFoundItems.push(requestedName);
|
|
1514
1634
|
continue;
|
|
1515
1635
|
}
|
|
1516
1636
|
const { serverName, actualToolName } = parseToolName(requestedName);
|
|
@@ -1544,6 +1664,11 @@ ${skillsSection}`,
|
|
|
1544
1664
|
continue;
|
|
1545
1665
|
}
|
|
1546
1666
|
}
|
|
1667
|
+
const promptSkillContent = await this.getPromptSkillContent(actualToolName);
|
|
1668
|
+
if (promptSkillContent) {
|
|
1669
|
+
foundSkills.push(promptSkillContent);
|
|
1670
|
+
continue;
|
|
1671
|
+
}
|
|
1547
1672
|
notFoundItems.push(requestedName);
|
|
1548
1673
|
continue;
|
|
1549
1674
|
}
|
|
@@ -1652,7 +1777,7 @@ var UseToolTool = class UseToolTool {
|
|
|
1652
1777
|
getDefinition() {
|
|
1653
1778
|
return {
|
|
1654
1779
|
name: UseToolTool.TOOL_NAME,
|
|
1655
|
-
description: `Execute an MCP tool with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
|
|
1780
|
+
description: `Execute an MCP tool (NOT Skill) with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
|
|
1656
1781
|
- Provide toolName and toolArgs based on the schema
|
|
1657
1782
|
- If multiple servers provide the same tool, specify serverName
|
|
1658
1783
|
`,
|
|
@@ -1691,6 +1816,37 @@ var UseToolTool = class UseToolTool {
|
|
|
1691
1816
|
}] };
|
|
1692
1817
|
}
|
|
1693
1818
|
/**
|
|
1819
|
+
* Finds a prompt-based skill by name from all connected MCP servers.
|
|
1820
|
+
*
|
|
1821
|
+
* @param skillName - The skill name to search for
|
|
1822
|
+
* @returns PromptSkillMatch if found, undefined otherwise
|
|
1823
|
+
*/
|
|
1824
|
+
findPromptSkill(skillName) {
|
|
1825
|
+
if (!skillName) return void 0;
|
|
1826
|
+
const clients = this.clientManager.getAllClients();
|
|
1827
|
+
for (const client of clients) {
|
|
1828
|
+
if (!client.prompts) continue;
|
|
1829
|
+
for (const [promptName, promptConfig] of Object.entries(client.prompts)) if (promptConfig.skill && promptConfig.skill.name === skillName) return {
|
|
1830
|
+
serverName: client.serverName,
|
|
1831
|
+
promptName,
|
|
1832
|
+
skill: promptConfig.skill
|
|
1833
|
+
};
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Returns guidance message for prompt-based skill invocation.
|
|
1838
|
+
*
|
|
1839
|
+
* @param promptSkill - The prompt skill match that was found
|
|
1840
|
+
* @returns CallToolResult with guidance message
|
|
1841
|
+
*/
|
|
1842
|
+
executePromptSkill(promptSkill) {
|
|
1843
|
+
const location = promptSkill.skill.folder || `prompt:${promptSkill.serverName}/${promptSkill.promptName}`;
|
|
1844
|
+
return { content: [{
|
|
1845
|
+
type: "text",
|
|
1846
|
+
text: `Skill "${promptSkill.skill.name}" found. Skills provide instructions and should not be executed via use_tool.\n\nUse describe_tools to view the skill details at: ${location}\n\nThen follow the skill's instructions directly.`
|
|
1847
|
+
}] };
|
|
1848
|
+
}
|
|
1849
|
+
/**
|
|
1694
1850
|
* Executes a tool or skill based on the provided input.
|
|
1695
1851
|
*
|
|
1696
1852
|
* Handles three invocation patterns:
|
|
@@ -1711,22 +1867,19 @@ var UseToolTool = class UseToolTool {
|
|
|
1711
1867
|
const { toolName: inputToolName, toolArgs = {} } = input;
|
|
1712
1868
|
if (inputToolName.startsWith(SKILL_PREFIX)) {
|
|
1713
1869
|
const skillName = inputToolName.slice(7);
|
|
1714
|
-
if (
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
const skill = await this.skillService.getSkill(skillName);
|
|
1722
|
-
if (!skill) return {
|
|
1870
|
+
if (this.skillService) {
|
|
1871
|
+
const skill = await this.skillService.getSkill(skillName);
|
|
1872
|
+
if (skill) return this.executeSkill(skill);
|
|
1873
|
+
}
|
|
1874
|
+
const promptSkill = this.findPromptSkill(skillName);
|
|
1875
|
+
if (promptSkill) return this.executePromptSkill(promptSkill);
|
|
1876
|
+
return {
|
|
1723
1877
|
content: [{
|
|
1724
1878
|
type: "text",
|
|
1725
1879
|
text: `Skill "${skillName}" not found. Use describe_tools to see available skills.`
|
|
1726
1880
|
}],
|
|
1727
1881
|
isError: true
|
|
1728
1882
|
};
|
|
1729
|
-
return this.executeSkill(skill);
|
|
1730
1883
|
}
|
|
1731
1884
|
const clients = this.clientManager.getAllClients();
|
|
1732
1885
|
const { serverName, actualToolName } = parseToolName(inputToolName);
|
|
@@ -1774,6 +1927,8 @@ var UseToolTool = class UseToolTool {
|
|
|
1774
1927
|
const skill = await this.skillService.getSkill(actualToolName);
|
|
1775
1928
|
if (skill) return this.executeSkill(skill);
|
|
1776
1929
|
}
|
|
1930
|
+
const promptSkill = this.findPromptSkill(actualToolName);
|
|
1931
|
+
if (promptSkill) return this.executePromptSkill(promptSkill);
|
|
1777
1932
|
return {
|
|
1778
1933
|
content: [{
|
|
1779
1934
|
type: "text",
|
|
@@ -1840,7 +1995,10 @@ async function createServer(options) {
|
|
|
1840
1995
|
const server = new Server({
|
|
1841
1996
|
name: "@agiflowai/one-mcp",
|
|
1842
1997
|
version: "0.1.0"
|
|
1843
|
-
}, { capabilities: {
|
|
1998
|
+
}, { capabilities: {
|
|
1999
|
+
tools: {},
|
|
2000
|
+
prompts: {}
|
|
2001
|
+
} });
|
|
1844
2002
|
const clientManager = new McpClientManagerService();
|
|
1845
2003
|
let configSkills;
|
|
1846
2004
|
if (options?.configFilePath) {
|
|
@@ -1891,6 +2049,60 @@ async function createServer(options) {
|
|
|
1891
2049
|
}
|
|
1892
2050
|
throw new Error(`Unknown tool: ${name}`);
|
|
1893
2051
|
});
|
|
2052
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
2053
|
+
const clients = clientManager.getAllClients();
|
|
2054
|
+
const promptToServers = /* @__PURE__ */ new Map();
|
|
2055
|
+
const serverPromptsMap = /* @__PURE__ */ new Map();
|
|
2056
|
+
await Promise.all(clients.map(async (client) => {
|
|
2057
|
+
try {
|
|
2058
|
+
const prompts = await client.listPrompts();
|
|
2059
|
+
serverPromptsMap.set(client.serverName, prompts);
|
|
2060
|
+
for (const prompt of prompts) {
|
|
2061
|
+
if (!promptToServers.has(prompt.name)) promptToServers.set(prompt.name, []);
|
|
2062
|
+
promptToServers.get(prompt.name).push(client.serverName);
|
|
2063
|
+
}
|
|
2064
|
+
} catch (error) {
|
|
2065
|
+
console.error(`Failed to list prompts from ${client.serverName}:`, error);
|
|
2066
|
+
serverPromptsMap.set(client.serverName, []);
|
|
2067
|
+
}
|
|
2068
|
+
}));
|
|
2069
|
+
const aggregatedPrompts = [];
|
|
2070
|
+
for (const client of clients) {
|
|
2071
|
+
const prompts = serverPromptsMap.get(client.serverName) || [];
|
|
2072
|
+
for (const prompt of prompts) {
|
|
2073
|
+
const hasClash = (promptToServers.get(prompt.name) || []).length > 1;
|
|
2074
|
+
aggregatedPrompts.push({
|
|
2075
|
+
name: hasClash ? `${client.serverName}__${prompt.name}` : prompt.name,
|
|
2076
|
+
description: prompt.description,
|
|
2077
|
+
arguments: prompt.arguments
|
|
2078
|
+
});
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
return { prompts: aggregatedPrompts };
|
|
2082
|
+
});
|
|
2083
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
2084
|
+
const { name, arguments: args } = request.params;
|
|
2085
|
+
const clients = clientManager.getAllClients();
|
|
2086
|
+
const { serverName, actualToolName: actualPromptName } = parseToolName(name);
|
|
2087
|
+
if (serverName) {
|
|
2088
|
+
const client$1 = clientManager.getClient(serverName);
|
|
2089
|
+
if (!client$1) throw new Error(`Server not found: ${serverName}`);
|
|
2090
|
+
return await client$1.getPrompt(actualPromptName, args);
|
|
2091
|
+
}
|
|
2092
|
+
const serversWithPrompt = [];
|
|
2093
|
+
await Promise.all(clients.map(async (client$1) => {
|
|
2094
|
+
try {
|
|
2095
|
+
if ((await client$1.listPrompts()).some((p) => p.name === name)) serversWithPrompt.push(client$1.serverName);
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
console.error(`Failed to list prompts from ${client$1.serverName}:`, error);
|
|
2098
|
+
}
|
|
2099
|
+
}));
|
|
2100
|
+
if (serversWithPrompt.length === 0) throw new Error(`Prompt not found: ${name}`);
|
|
2101
|
+
if (serversWithPrompt.length > 1) throw new Error(`Prompt "${name}" exists on multiple servers: ${serversWithPrompt.join(", ")}. Use the prefixed format (e.g., "${serversWithPrompt[0]}__${name}") to specify which server to use.`);
|
|
2102
|
+
const client = clientManager.getClient(serversWithPrompt[0]);
|
|
2103
|
+
if (!client) throw new Error(`Server not found: ${serversWithPrompt[0]}`);
|
|
2104
|
+
return await client.getPrompt(name, args);
|
|
2105
|
+
});
|
|
1894
2106
|
return server;
|
|
1895
2107
|
}
|
|
1896
2108
|
|
|
@@ -204,10 +204,25 @@ function validateRemoteConfigSource(source) {
|
|
|
204
204
|
* Claude Code / Claude Desktop standard MCP config format
|
|
205
205
|
* This is the format users write in their config files
|
|
206
206
|
*/
|
|
207
|
+
/**
|
|
208
|
+
* Prompt skill configuration schema
|
|
209
|
+
* Converts a prompt to an executable skill
|
|
210
|
+
*/
|
|
211
|
+
const PromptSkillConfigSchema = zod.z.object({
|
|
212
|
+
name: zod.z.string(),
|
|
213
|
+
description: zod.z.string(),
|
|
214
|
+
folder: zod.z.string().optional()
|
|
215
|
+
});
|
|
216
|
+
/**
|
|
217
|
+
* Prompt configuration schema
|
|
218
|
+
* Supports converting prompts to skills
|
|
219
|
+
*/
|
|
220
|
+
const PromptConfigSchema = zod.z.object({ skill: PromptSkillConfigSchema.optional() });
|
|
207
221
|
const AdditionalConfigSchema = zod.z.object({
|
|
208
222
|
instruction: zod.z.string().optional(),
|
|
209
223
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
210
|
-
omitToolDescription: zod.z.boolean().optional()
|
|
224
|
+
omitToolDescription: zod.z.boolean().optional(),
|
|
225
|
+
prompts: zod.z.record(zod.z.string(), PromptConfigSchema).optional()
|
|
211
226
|
}).optional();
|
|
212
227
|
const ClaudeCodeStdioServerSchema = zod.z.object({
|
|
213
228
|
command: zod.z.string(),
|
|
@@ -274,12 +289,25 @@ const McpSseConfigSchema = zod.z.object({
|
|
|
274
289
|
url: zod.z.string().url(),
|
|
275
290
|
headers: zod.z.record(zod.z.string(), zod.z.string()).optional()
|
|
276
291
|
});
|
|
292
|
+
/**
|
|
293
|
+
* Internal prompt skill configuration schema
|
|
294
|
+
*/
|
|
295
|
+
const InternalPromptSkillConfigSchema = zod.z.object({
|
|
296
|
+
name: zod.z.string(),
|
|
297
|
+
description: zod.z.string(),
|
|
298
|
+
folder: zod.z.string().optional()
|
|
299
|
+
});
|
|
300
|
+
/**
|
|
301
|
+
* Internal prompt configuration schema
|
|
302
|
+
*/
|
|
303
|
+
const InternalPromptConfigSchema = zod.z.object({ skill: InternalPromptSkillConfigSchema.optional() });
|
|
277
304
|
const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
278
305
|
zod.z.object({
|
|
279
306
|
name: zod.z.string(),
|
|
280
307
|
instruction: zod.z.string().optional(),
|
|
281
308
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
282
309
|
omitToolDescription: zod.z.boolean().optional(),
|
|
310
|
+
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
283
311
|
transport: zod.z.literal("stdio"),
|
|
284
312
|
config: McpStdioConfigSchema
|
|
285
313
|
}),
|
|
@@ -288,6 +316,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
288
316
|
instruction: zod.z.string().optional(),
|
|
289
317
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
290
318
|
omitToolDescription: zod.z.boolean().optional(),
|
|
319
|
+
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
291
320
|
transport: zod.z.literal("http"),
|
|
292
321
|
config: McpHttpConfigSchema
|
|
293
322
|
}),
|
|
@@ -296,6 +325,7 @@ const McpServerConfigSchema = zod.z.discriminatedUnion("transport", [
|
|
|
296
325
|
instruction: zod.z.string().optional(),
|
|
297
326
|
toolBlacklist: zod.z.array(zod.z.string()).optional(),
|
|
298
327
|
omitToolDescription: zod.z.boolean().optional(),
|
|
328
|
+
prompts: zod.z.record(zod.z.string(), InternalPromptConfigSchema).optional(),
|
|
299
329
|
transport: zod.z.literal("sse"),
|
|
300
330
|
config: McpSseConfigSchema
|
|
301
331
|
})
|
|
@@ -328,6 +358,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
328
358
|
instruction: stdioConfig.instruction || stdioConfig.config?.instruction,
|
|
329
359
|
toolBlacklist: stdioConfig.config?.toolBlacklist,
|
|
330
360
|
omitToolDescription: stdioConfig.config?.omitToolDescription,
|
|
361
|
+
prompts: stdioConfig.config?.prompts,
|
|
331
362
|
transport: "stdio",
|
|
332
363
|
config: {
|
|
333
364
|
command: interpolatedCommand,
|
|
@@ -345,6 +376,7 @@ function transformClaudeCodeConfig(claudeConfig) {
|
|
|
345
376
|
instruction: httpConfig.instruction || httpConfig.config?.instruction,
|
|
346
377
|
toolBlacklist: httpConfig.config?.toolBlacklist,
|
|
347
378
|
omitToolDescription: httpConfig.config?.omitToolDescription,
|
|
379
|
+
prompts: httpConfig.config?.prompts,
|
|
348
380
|
transport,
|
|
349
381
|
config: {
|
|
350
382
|
url: interpolatedUrl,
|
|
@@ -805,12 +837,14 @@ var ConfigFetcherService = class {
|
|
|
805
837
|
//#region src/services/McpClientManagerService.ts
|
|
806
838
|
/**
|
|
807
839
|
* MCP Client wrapper for managing individual server connections
|
|
840
|
+
* This is an internal class used by McpClientManagerService
|
|
808
841
|
*/
|
|
809
842
|
var McpClient = class {
|
|
810
843
|
serverName;
|
|
811
844
|
serverInstruction;
|
|
812
845
|
toolBlacklist;
|
|
813
846
|
omitToolDescription;
|
|
847
|
+
prompts;
|
|
814
848
|
transport;
|
|
815
849
|
client;
|
|
816
850
|
childProcess;
|
|
@@ -820,6 +854,7 @@ var McpClient = class {
|
|
|
820
854
|
this.serverInstruction = config.instruction;
|
|
821
855
|
this.toolBlacklist = config.toolBlacklist;
|
|
822
856
|
this.omitToolDescription = config.omitToolDescription;
|
|
857
|
+
this.prompts = config.prompts;
|
|
823
858
|
this.transport = transport;
|
|
824
859
|
this.client = client;
|
|
825
860
|
}
|
|
@@ -915,7 +950,8 @@ var McpClientManagerService = class {
|
|
|
915
950
|
const mcpClient = new McpClient(serverName, config.transport, client, {
|
|
916
951
|
instruction: config.instruction,
|
|
917
952
|
toolBlacklist: config.toolBlacklist,
|
|
918
|
-
omitToolDescription: config.omitToolDescription
|
|
953
|
+
omitToolDescription: config.omitToolDescription,
|
|
954
|
+
prompts: config.prompts
|
|
919
955
|
});
|
|
920
956
|
try {
|
|
921
957
|
await Promise.race([this.performConnection(mcpClient, config), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error(`Connection timeout after ${timeoutMs}ms`)), timeoutMs))]);
|
|
@@ -1318,11 +1354,11 @@ function parseToolName(toolName) {
|
|
|
1318
1354
|
|
|
1319
1355
|
//#endregion
|
|
1320
1356
|
//#region src/templates/skills-description.liquid?raw
|
|
1321
|
-
var skills_description_default = "{% if skills.size > 0 %}\n<skills>\n<instructions>\nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.\n\nHow to use skills:\n- Invoke skills using this tool with the skill name only (no arguments)\n- When you invoke a skill, you will see <command-message>The \"{name}\" skill is loading</command-message>\n- The skill's prompt will expand and provide detailed instructions on how to complete the task\n- Examples:\n - `skill: \"pdf\"` - invoke the pdf skill\n - `skill: \"xlsx\"` - invoke the xlsx skill\n - `skill: \"ms-office-suite:pdf\"` - invoke using fully qualified name\n\nImportant:\n- Only use skills listed in <available_skills> below\n- Do not invoke a skill that is already running\n- Do not use this tool for built-in CLI commands (like /help, /clear, etc.)\n</instructions>\n\n<available_skills>\n{% for skill in skills -%}\n<
|
|
1357
|
+
var skills_description_default = "{% if skills.size > 0 %}\n<skills>\n<instructions>\nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.\n\nHow to use skills:\n- Invoke skills using this tool with the skill name only (no arguments)\n- When you invoke a skill, you will see <command-message>The \"{name}\" skill is loading</command-message>\n- The skill's prompt will expand and provide detailed instructions on how to complete the task\n- Examples:\n - `skill: \"pdf\"` - invoke the pdf skill\n - `skill: \"xlsx\"` - invoke the xlsx skill\n - `skill: \"ms-office-suite:pdf\"` - invoke using fully qualified name\n\nImportant:\n- Only use skills listed in <available_skills> below\n- Do not invoke a skill that is already running\n- Do not use this tool for built-in CLI commands (like /help, /clear, etc.)\n</instructions>\n\n<available_skills>\n{% for skill in skills -%}\n<item><name>{{ skill.displayName }}</name><description>{{ skill.description }}</description></item>\n{% endfor -%}\n</available_skills>\n</skills>\n{% endif %}\n";
|
|
1322
1358
|
|
|
1323
1359
|
//#endregion
|
|
1324
1360
|
//#region src/templates/mcp-servers-description.liquid?raw
|
|
1325
|
-
var mcp_servers_description_default = "<mcp_servers>\n{% for server in servers -%}\n<server name=\"{{ server.name }}\">\n{% if server.instruction -%}\n<instruction>{{ server.instruction }}</instruction>\n{% endif -%}\n<tools>\n{% if server.omitToolDescription -%}\n{{ server.toolNames | join: \", \" }}\n{% else -%}\n{% for tool in server.tools -%}\n<
|
|
1361
|
+
var mcp_servers_description_default = "<mcp_servers>\n<instructions>\nBefore you use any tools above, you MUST call this tool with a list of tool names to learn how to use them properly before use_tool; this includes:\n- Arguments schema needed to pass to the tool use\n- Description about each tool\n\nThis tool is optimized for batch queries - you can request multiple tools at once for better performance.\n</instructions>\n\n{% for server in servers -%}\n<server name=\"{{ server.name }}\">\n{% if server.instruction -%}\n<instruction>{{ server.instruction }}</instruction>\n{% endif -%}\n<tools>\n{% if server.omitToolDescription -%}\n{{ server.toolNames | join: \", \" }}\n{% else -%}\n{% for tool in server.tools -%}\n<item><name>{{ tool.displayName }}</name><description>{{ tool.description | default: \"No description\" }}</description></item>\n{% endfor -%}\n{% endif -%}\n</tools>\n</server>\n{% endfor -%}\n</mcp_servers>\n";
|
|
1326
1362
|
|
|
1327
1363
|
//#endregion
|
|
1328
1364
|
//#region src/tools/DescribeToolsTool.ts
|
|
@@ -1362,20 +1398,96 @@ var DescribeToolsTool = class DescribeToolsTool {
|
|
|
1362
1398
|
this.skillService = skillService;
|
|
1363
1399
|
}
|
|
1364
1400
|
/**
|
|
1401
|
+
* Collects skills derived from prompt configurations across all connected MCP servers.
|
|
1402
|
+
* Prompts with a skill configuration are converted to skill format for display.
|
|
1403
|
+
*
|
|
1404
|
+
* @returns Array of skill template data derived from prompts
|
|
1405
|
+
*/
|
|
1406
|
+
collectPromptSkills() {
|
|
1407
|
+
const clients = this.clientManager.getAllClients();
|
|
1408
|
+
const promptSkills = [];
|
|
1409
|
+
for (const client of clients) {
|
|
1410
|
+
if (!client.prompts) continue;
|
|
1411
|
+
for (const promptConfig of Object.values(client.prompts)) if (promptConfig.skill) promptSkills.push({
|
|
1412
|
+
name: promptConfig.skill.name,
|
|
1413
|
+
displayName: promptConfig.skill.name,
|
|
1414
|
+
description: promptConfig.skill.description
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
return promptSkills;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Finds a prompt-based skill by name from all connected MCP servers.
|
|
1421
|
+
* Returns the prompt name and skill config for fetching the prompt content.
|
|
1422
|
+
*
|
|
1423
|
+
* @param skillName - The skill name to search for
|
|
1424
|
+
* @returns Object with serverName, promptName, and skill config, or undefined if not found
|
|
1425
|
+
*/
|
|
1426
|
+
findPromptSkill(skillName) {
|
|
1427
|
+
if (!skillName) return void 0;
|
|
1428
|
+
const clients = this.clientManager.getAllClients();
|
|
1429
|
+
for (const client of clients) {
|
|
1430
|
+
if (!client.prompts) continue;
|
|
1431
|
+
for (const [promptName, promptConfig] of Object.entries(client.prompts)) if (promptConfig.skill && promptConfig.skill.name === skillName) return {
|
|
1432
|
+
serverName: client.serverName,
|
|
1433
|
+
promptName,
|
|
1434
|
+
skill: promptConfig.skill
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
/**
|
|
1439
|
+
* Retrieves skill content from a prompt-based skill configuration.
|
|
1440
|
+
* Fetches the prompt from the MCP server and extracts text content.
|
|
1441
|
+
*
|
|
1442
|
+
* @param skillName - The skill name being requested
|
|
1443
|
+
* @returns SkillDescription if found and successfully fetched, undefined otherwise
|
|
1444
|
+
*/
|
|
1445
|
+
async getPromptSkillContent(skillName) {
|
|
1446
|
+
const promptSkill = this.findPromptSkill(skillName);
|
|
1447
|
+
if (!promptSkill) return void 0;
|
|
1448
|
+
const client = this.clientManager.getClient(promptSkill.serverName);
|
|
1449
|
+
if (!client) {
|
|
1450
|
+
console.error(`Client not found for server '${promptSkill.serverName}' when fetching prompt skill '${skillName}'`);
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
try {
|
|
1454
|
+
const instructions = (await client.getPrompt(promptSkill.promptName)).messages?.map((m) => {
|
|
1455
|
+
const content = m.content;
|
|
1456
|
+
if (typeof content === "string") return content;
|
|
1457
|
+
if (content && typeof content === "object" && "text" in content) return String(content.text);
|
|
1458
|
+
return "";
|
|
1459
|
+
}).join("\n") || "";
|
|
1460
|
+
return {
|
|
1461
|
+
name: promptSkill.skill.name,
|
|
1462
|
+
location: promptSkill.skill.folder || `prompt:${promptSkill.serverName}/${promptSkill.promptName}`,
|
|
1463
|
+
instructions
|
|
1464
|
+
};
|
|
1465
|
+
} catch (error) {
|
|
1466
|
+
console.error(`Failed to get prompt-based skill '${skillName}': ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
/**
|
|
1365
1471
|
* Builds the skills section of the tool description using a Liquid template.
|
|
1366
1472
|
*
|
|
1367
|
-
* Retrieves all available skills from the SkillService and
|
|
1368
|
-
* using the skills-description.liquid template. Skills are only
|
|
1369
|
-
* with skill__ when their name clashes with an MCP tool or another skill.
|
|
1473
|
+
* Retrieves all available skills from the SkillService and prompt-based skills,
|
|
1474
|
+
* then renders them using the skills-description.liquid template. Skills are only
|
|
1475
|
+
* prefixed with skill__ when their name clashes with an MCP tool or another skill.
|
|
1370
1476
|
*
|
|
1371
1477
|
* @param mcpToolNames - Set of MCP tool names to check for clashes
|
|
1372
1478
|
* @returns Rendered skills section string with available skills list
|
|
1373
1479
|
*/
|
|
1374
1480
|
async buildSkillsSection(mcpToolNames) {
|
|
1375
1481
|
const rawSkills = this.skillService ? await this.skillService.getSkills() : [];
|
|
1482
|
+
const promptSkills = this.collectPromptSkills();
|
|
1483
|
+
const allSkillsData = [...rawSkills.map((skill) => ({
|
|
1484
|
+
name: skill.name,
|
|
1485
|
+
displayName: skill.name,
|
|
1486
|
+
description: skill.description
|
|
1487
|
+
})), ...promptSkills];
|
|
1376
1488
|
const skillNameCounts = /* @__PURE__ */ new Map();
|
|
1377
|
-
for (const skill of
|
|
1378
|
-
const skills =
|
|
1489
|
+
for (const skill of allSkillsData) skillNameCounts.set(skill.name, (skillNameCounts.get(skill.name) || 0) + 1);
|
|
1490
|
+
const skills = allSkillsData.map((skill) => {
|
|
1379
1491
|
const clashesWithMcpTool = mcpToolNames.has(skill.name);
|
|
1380
1492
|
const clashesWithOtherSkill = (skillNameCounts.get(skill.name) || 0) > 1;
|
|
1381
1493
|
const needsPrefix = clashesWithMcpTool || clashesWithOtherSkill;
|
|
@@ -1533,13 +1645,21 @@ ${skillsSection}`,
|
|
|
1533
1645
|
const skillName = requestedName.slice(7);
|
|
1534
1646
|
if (this.skillService) {
|
|
1535
1647
|
const skill = await this.skillService.getSkill(skillName);
|
|
1536
|
-
if (skill)
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1648
|
+
if (skill) {
|
|
1649
|
+
foundSkills.push({
|
|
1650
|
+
name: skill.name,
|
|
1651
|
+
location: skill.basePath,
|
|
1652
|
+
instructions: skill.content
|
|
1653
|
+
});
|
|
1654
|
+
continue;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
const promptSkillContent = await this.getPromptSkillContent(skillName);
|
|
1658
|
+
if (promptSkillContent) {
|
|
1659
|
+
foundSkills.push(promptSkillContent);
|
|
1660
|
+
continue;
|
|
1661
|
+
}
|
|
1662
|
+
notFoundItems.push(requestedName);
|
|
1543
1663
|
continue;
|
|
1544
1664
|
}
|
|
1545
1665
|
const { serverName, actualToolName } = parseToolName(requestedName);
|
|
@@ -1573,6 +1693,11 @@ ${skillsSection}`,
|
|
|
1573
1693
|
continue;
|
|
1574
1694
|
}
|
|
1575
1695
|
}
|
|
1696
|
+
const promptSkillContent = await this.getPromptSkillContent(actualToolName);
|
|
1697
|
+
if (promptSkillContent) {
|
|
1698
|
+
foundSkills.push(promptSkillContent);
|
|
1699
|
+
continue;
|
|
1700
|
+
}
|
|
1576
1701
|
notFoundItems.push(requestedName);
|
|
1577
1702
|
continue;
|
|
1578
1703
|
}
|
|
@@ -1681,7 +1806,7 @@ var UseToolTool = class UseToolTool {
|
|
|
1681
1806
|
getDefinition() {
|
|
1682
1807
|
return {
|
|
1683
1808
|
name: UseToolTool.TOOL_NAME,
|
|
1684
|
-
description: `Execute an MCP tool with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
|
|
1809
|
+
description: `Execute an MCP tool (NOT Skill) with provided arguments. You MUST call describe_tools first to discover the tool's correct arguments. Then to use tool:
|
|
1685
1810
|
- Provide toolName and toolArgs based on the schema
|
|
1686
1811
|
- If multiple servers provide the same tool, specify serverName
|
|
1687
1812
|
`,
|
|
@@ -1720,6 +1845,37 @@ var UseToolTool = class UseToolTool {
|
|
|
1720
1845
|
}] };
|
|
1721
1846
|
}
|
|
1722
1847
|
/**
|
|
1848
|
+
* Finds a prompt-based skill by name from all connected MCP servers.
|
|
1849
|
+
*
|
|
1850
|
+
* @param skillName - The skill name to search for
|
|
1851
|
+
* @returns PromptSkillMatch if found, undefined otherwise
|
|
1852
|
+
*/
|
|
1853
|
+
findPromptSkill(skillName) {
|
|
1854
|
+
if (!skillName) return void 0;
|
|
1855
|
+
const clients = this.clientManager.getAllClients();
|
|
1856
|
+
for (const client of clients) {
|
|
1857
|
+
if (!client.prompts) continue;
|
|
1858
|
+
for (const [promptName, promptConfig] of Object.entries(client.prompts)) if (promptConfig.skill && promptConfig.skill.name === skillName) return {
|
|
1859
|
+
serverName: client.serverName,
|
|
1860
|
+
promptName,
|
|
1861
|
+
skill: promptConfig.skill
|
|
1862
|
+
};
|
|
1863
|
+
}
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Returns guidance message for prompt-based skill invocation.
|
|
1867
|
+
*
|
|
1868
|
+
* @param promptSkill - The prompt skill match that was found
|
|
1869
|
+
* @returns CallToolResult with guidance message
|
|
1870
|
+
*/
|
|
1871
|
+
executePromptSkill(promptSkill) {
|
|
1872
|
+
const location = promptSkill.skill.folder || `prompt:${promptSkill.serverName}/${promptSkill.promptName}`;
|
|
1873
|
+
return { content: [{
|
|
1874
|
+
type: "text",
|
|
1875
|
+
text: `Skill "${promptSkill.skill.name}" found. Skills provide instructions and should not be executed via use_tool.\n\nUse describe_tools to view the skill details at: ${location}\n\nThen follow the skill's instructions directly.`
|
|
1876
|
+
}] };
|
|
1877
|
+
}
|
|
1878
|
+
/**
|
|
1723
1879
|
* Executes a tool or skill based on the provided input.
|
|
1724
1880
|
*
|
|
1725
1881
|
* Handles three invocation patterns:
|
|
@@ -1740,22 +1896,19 @@ var UseToolTool = class UseToolTool {
|
|
|
1740
1896
|
const { toolName: inputToolName, toolArgs = {} } = input;
|
|
1741
1897
|
if (inputToolName.startsWith(SKILL_PREFIX)) {
|
|
1742
1898
|
const skillName = inputToolName.slice(7);
|
|
1743
|
-
if (
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
const skill = await this.skillService.getSkill(skillName);
|
|
1751
|
-
if (!skill) return {
|
|
1899
|
+
if (this.skillService) {
|
|
1900
|
+
const skill = await this.skillService.getSkill(skillName);
|
|
1901
|
+
if (skill) return this.executeSkill(skill);
|
|
1902
|
+
}
|
|
1903
|
+
const promptSkill = this.findPromptSkill(skillName);
|
|
1904
|
+
if (promptSkill) return this.executePromptSkill(promptSkill);
|
|
1905
|
+
return {
|
|
1752
1906
|
content: [{
|
|
1753
1907
|
type: "text",
|
|
1754
1908
|
text: `Skill "${skillName}" not found. Use describe_tools to see available skills.`
|
|
1755
1909
|
}],
|
|
1756
1910
|
isError: true
|
|
1757
1911
|
};
|
|
1758
|
-
return this.executeSkill(skill);
|
|
1759
1912
|
}
|
|
1760
1913
|
const clients = this.clientManager.getAllClients();
|
|
1761
1914
|
const { serverName, actualToolName } = parseToolName(inputToolName);
|
|
@@ -1803,6 +1956,8 @@ var UseToolTool = class UseToolTool {
|
|
|
1803
1956
|
const skill = await this.skillService.getSkill(actualToolName);
|
|
1804
1957
|
if (skill) return this.executeSkill(skill);
|
|
1805
1958
|
}
|
|
1959
|
+
const promptSkill = this.findPromptSkill(actualToolName);
|
|
1960
|
+
if (promptSkill) return this.executePromptSkill(promptSkill);
|
|
1806
1961
|
return {
|
|
1807
1962
|
content: [{
|
|
1808
1963
|
type: "text",
|
|
@@ -1869,7 +2024,10 @@ async function createServer(options) {
|
|
|
1869
2024
|
const server = new __modelcontextprotocol_sdk_server_index_js.Server({
|
|
1870
2025
|
name: "@agiflowai/one-mcp",
|
|
1871
2026
|
version: "0.1.0"
|
|
1872
|
-
}, { capabilities: {
|
|
2027
|
+
}, { capabilities: {
|
|
2028
|
+
tools: {},
|
|
2029
|
+
prompts: {}
|
|
2030
|
+
} });
|
|
1873
2031
|
const clientManager = new McpClientManagerService();
|
|
1874
2032
|
let configSkills;
|
|
1875
2033
|
if (options?.configFilePath) {
|
|
@@ -1920,6 +2078,60 @@ async function createServer(options) {
|
|
|
1920
2078
|
}
|
|
1921
2079
|
throw new Error(`Unknown tool: ${name}`);
|
|
1922
2080
|
});
|
|
2081
|
+
server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListPromptsRequestSchema, async () => {
|
|
2082
|
+
const clients = clientManager.getAllClients();
|
|
2083
|
+
const promptToServers = /* @__PURE__ */ new Map();
|
|
2084
|
+
const serverPromptsMap = /* @__PURE__ */ new Map();
|
|
2085
|
+
await Promise.all(clients.map(async (client) => {
|
|
2086
|
+
try {
|
|
2087
|
+
const prompts = await client.listPrompts();
|
|
2088
|
+
serverPromptsMap.set(client.serverName, prompts);
|
|
2089
|
+
for (const prompt of prompts) {
|
|
2090
|
+
if (!promptToServers.has(prompt.name)) promptToServers.set(prompt.name, []);
|
|
2091
|
+
promptToServers.get(prompt.name).push(client.serverName);
|
|
2092
|
+
}
|
|
2093
|
+
} catch (error) {
|
|
2094
|
+
console.error(`Failed to list prompts from ${client.serverName}:`, error);
|
|
2095
|
+
serverPromptsMap.set(client.serverName, []);
|
|
2096
|
+
}
|
|
2097
|
+
}));
|
|
2098
|
+
const aggregatedPrompts = [];
|
|
2099
|
+
for (const client of clients) {
|
|
2100
|
+
const prompts = serverPromptsMap.get(client.serverName) || [];
|
|
2101
|
+
for (const prompt of prompts) {
|
|
2102
|
+
const hasClash = (promptToServers.get(prompt.name) || []).length > 1;
|
|
2103
|
+
aggregatedPrompts.push({
|
|
2104
|
+
name: hasClash ? `${client.serverName}__${prompt.name}` : prompt.name,
|
|
2105
|
+
description: prompt.description,
|
|
2106
|
+
arguments: prompt.arguments
|
|
2107
|
+
});
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
return { prompts: aggregatedPrompts };
|
|
2111
|
+
});
|
|
2112
|
+
server.setRequestHandler(__modelcontextprotocol_sdk_types_js.GetPromptRequestSchema, async (request) => {
|
|
2113
|
+
const { name, arguments: args } = request.params;
|
|
2114
|
+
const clients = clientManager.getAllClients();
|
|
2115
|
+
const { serverName, actualToolName: actualPromptName } = parseToolName(name);
|
|
2116
|
+
if (serverName) {
|
|
2117
|
+
const client$1 = clientManager.getClient(serverName);
|
|
2118
|
+
if (!client$1) throw new Error(`Server not found: ${serverName}`);
|
|
2119
|
+
return await client$1.getPrompt(actualPromptName, args);
|
|
2120
|
+
}
|
|
2121
|
+
const serversWithPrompt = [];
|
|
2122
|
+
await Promise.all(clients.map(async (client$1) => {
|
|
2123
|
+
try {
|
|
2124
|
+
if ((await client$1.listPrompts()).some((p) => p.name === name)) serversWithPrompt.push(client$1.serverName);
|
|
2125
|
+
} catch (error) {
|
|
2126
|
+
console.error(`Failed to list prompts from ${client$1.serverName}:`, error);
|
|
2127
|
+
}
|
|
2128
|
+
}));
|
|
2129
|
+
if (serversWithPrompt.length === 0) throw new Error(`Prompt not found: ${name}`);
|
|
2130
|
+
if (serversWithPrompt.length > 1) throw new Error(`Prompt "${name}" exists on multiple servers: ${serversWithPrompt.join(", ")}. Use the prefixed format (e.g., "${serversWithPrompt[0]}__${name}") to specify which server to use.`);
|
|
2131
|
+
const client = clientManager.getClient(serversWithPrompt[0]);
|
|
2132
|
+
if (!client) throw new Error(`Server not found: ${serversWithPrompt[0]}`);
|
|
2133
|
+
return await client.getPrompt(name, args);
|
|
2134
|
+
});
|
|
1923
2135
|
return server;
|
|
1924
2136
|
}
|
|
1925
2137
|
|
package/dist/index.cjs
CHANGED
package/dist/index.d.cts
CHANGED
|
@@ -130,6 +130,7 @@ type McpServerTransportConfig = McpStdioConfig | McpHttpConfig | McpSseConfig;
|
|
|
130
130
|
* @property instruction - Optional instruction text describing the server's purpose
|
|
131
131
|
* @property toolBlacklist - Optional list of tool names to exclude from this server
|
|
132
132
|
* @property omitToolDescription - Whether to omit tool descriptions in listings
|
|
133
|
+
* @property prompts - Optional prompts configuration for skill conversion
|
|
133
134
|
* @property transport - The transport type (stdio, http, or sse)
|
|
134
135
|
* @property config - Transport-specific configuration options
|
|
135
136
|
*/
|
|
@@ -138,6 +139,7 @@ interface McpServerConfig {
|
|
|
138
139
|
instruction?: string;
|
|
139
140
|
toolBlacklist?: string[];
|
|
140
141
|
omitToolDescription?: boolean;
|
|
142
|
+
prompts?: Record<string, PromptConfig>;
|
|
141
143
|
transport: McpServerTransportType;
|
|
142
144
|
config: McpServerTransportConfig;
|
|
143
145
|
}
|
|
@@ -148,6 +150,24 @@ interface McpServerConfig {
|
|
|
148
150
|
interface SkillsConfig {
|
|
149
151
|
paths: string[];
|
|
150
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Prompt skill configuration for converting prompts to executable skills
|
|
155
|
+
* @property name - Skill name identifier
|
|
156
|
+
* @property description - Skill description shown in describe_tools
|
|
157
|
+
* @property folder - Optional folder path for skill resources
|
|
158
|
+
*/
|
|
159
|
+
interface PromptSkillConfig {
|
|
160
|
+
name: string;
|
|
161
|
+
description: string;
|
|
162
|
+
folder?: string;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Prompt configuration that can be converted to a skill
|
|
166
|
+
* @property skill - Optional skill conversion configuration
|
|
167
|
+
*/
|
|
168
|
+
interface PromptConfig {
|
|
169
|
+
skill?: PromptSkillConfig;
|
|
170
|
+
}
|
|
151
171
|
/**
|
|
152
172
|
* Remote configuration response containing MCP server definitions
|
|
153
173
|
* @property mcpServers - Map of server names to their configurations
|
|
@@ -202,6 +222,7 @@ interface McpPromptInfo {
|
|
|
202
222
|
* @property serverInstruction - Optional instruction text for the server
|
|
203
223
|
* @property toolBlacklist - Optional list of tool names to exclude
|
|
204
224
|
* @property omitToolDescription - Whether to omit tool descriptions
|
|
225
|
+
* @property prompts - Optional prompts configuration for skill conversion
|
|
205
226
|
* @property transport - The transport type used for this connection
|
|
206
227
|
*/
|
|
207
228
|
interface McpClientConnection {
|
|
@@ -209,6 +230,7 @@ interface McpClientConnection {
|
|
|
209
230
|
serverInstruction?: string;
|
|
210
231
|
toolBlacklist?: string[];
|
|
211
232
|
omitToolDescription?: boolean;
|
|
233
|
+
prompts?: Record<string, PromptConfig>;
|
|
212
234
|
transport: McpServerTransportType;
|
|
213
235
|
/** List available tools from the server */
|
|
214
236
|
listTools(): Promise<McpToolInfo[]>;
|
|
@@ -311,4 +333,4 @@ declare class HttpTransportHandler implements HttpTransportHandler$1 {
|
|
|
311
333
|
getHost(): string;
|
|
312
334
|
}
|
|
313
335
|
//#endregion
|
|
314
|
-
export { HttpTransportHandler, McpClientConnection, McpHttpConfig, McpPromptInfo, McpResourceInfo, McpServerConfig, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolInfo, RemoteMcpConfiguration, type ServerOptions, Skill, SkillMetadata, SkillsConfig, SseTransportHandler, StdioTransportHandler, TRANSPORT_MODE, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode, createServer };
|
|
336
|
+
export { HttpTransportHandler, McpClientConnection, McpHttpConfig, McpPromptInfo, McpResourceInfo, McpServerConfig, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolInfo, PromptConfig, PromptSkillConfig, RemoteMcpConfiguration, type ServerOptions, Skill, SkillMetadata, SkillsConfig, SseTransportHandler, StdioTransportHandler, TRANSPORT_MODE, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode, createServer };
|
package/dist/index.d.mts
CHANGED
|
@@ -130,6 +130,7 @@ type McpServerTransportConfig = McpStdioConfig | McpHttpConfig | McpSseConfig;
|
|
|
130
130
|
* @property instruction - Optional instruction text describing the server's purpose
|
|
131
131
|
* @property toolBlacklist - Optional list of tool names to exclude from this server
|
|
132
132
|
* @property omitToolDescription - Whether to omit tool descriptions in listings
|
|
133
|
+
* @property prompts - Optional prompts configuration for skill conversion
|
|
133
134
|
* @property transport - The transport type (stdio, http, or sse)
|
|
134
135
|
* @property config - Transport-specific configuration options
|
|
135
136
|
*/
|
|
@@ -138,6 +139,7 @@ interface McpServerConfig {
|
|
|
138
139
|
instruction?: string;
|
|
139
140
|
toolBlacklist?: string[];
|
|
140
141
|
omitToolDescription?: boolean;
|
|
142
|
+
prompts?: Record<string, PromptConfig>;
|
|
141
143
|
transport: McpServerTransportType;
|
|
142
144
|
config: McpServerTransportConfig;
|
|
143
145
|
}
|
|
@@ -148,6 +150,24 @@ interface McpServerConfig {
|
|
|
148
150
|
interface SkillsConfig {
|
|
149
151
|
paths: string[];
|
|
150
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* Prompt skill configuration for converting prompts to executable skills
|
|
155
|
+
* @property name - Skill name identifier
|
|
156
|
+
* @property description - Skill description shown in describe_tools
|
|
157
|
+
* @property folder - Optional folder path for skill resources
|
|
158
|
+
*/
|
|
159
|
+
interface PromptSkillConfig {
|
|
160
|
+
name: string;
|
|
161
|
+
description: string;
|
|
162
|
+
folder?: string;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Prompt configuration that can be converted to a skill
|
|
166
|
+
* @property skill - Optional skill conversion configuration
|
|
167
|
+
*/
|
|
168
|
+
interface PromptConfig {
|
|
169
|
+
skill?: PromptSkillConfig;
|
|
170
|
+
}
|
|
151
171
|
/**
|
|
152
172
|
* Remote configuration response containing MCP server definitions
|
|
153
173
|
* @property mcpServers - Map of server names to their configurations
|
|
@@ -202,6 +222,7 @@ interface McpPromptInfo {
|
|
|
202
222
|
* @property serverInstruction - Optional instruction text for the server
|
|
203
223
|
* @property toolBlacklist - Optional list of tool names to exclude
|
|
204
224
|
* @property omitToolDescription - Whether to omit tool descriptions
|
|
225
|
+
* @property prompts - Optional prompts configuration for skill conversion
|
|
205
226
|
* @property transport - The transport type used for this connection
|
|
206
227
|
*/
|
|
207
228
|
interface McpClientConnection {
|
|
@@ -209,6 +230,7 @@ interface McpClientConnection {
|
|
|
209
230
|
serverInstruction?: string;
|
|
210
231
|
toolBlacklist?: string[];
|
|
211
232
|
omitToolDescription?: boolean;
|
|
233
|
+
prompts?: Record<string, PromptConfig>;
|
|
212
234
|
transport: McpServerTransportType;
|
|
213
235
|
/** List available tools from the server */
|
|
214
236
|
listTools(): Promise<McpToolInfo[]>;
|
|
@@ -311,4 +333,4 @@ declare class HttpTransportHandler implements HttpTransportHandler$1 {
|
|
|
311
333
|
getHost(): string;
|
|
312
334
|
}
|
|
313
335
|
//#endregion
|
|
314
|
-
export { HttpTransportHandler, McpClientConnection, McpHttpConfig, McpPromptInfo, McpResourceInfo, McpServerConfig, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolInfo, RemoteMcpConfiguration, type ServerOptions, Skill, SkillMetadata, SkillsConfig, SseTransportHandler, StdioTransportHandler, TRANSPORT_MODE, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode, createServer };
|
|
336
|
+
export { HttpTransportHandler, McpClientConnection, McpHttpConfig, McpPromptInfo, McpResourceInfo, McpServerConfig, McpServerTransportConfig, McpServerTransportType, McpSseConfig, McpStdioConfig, McpToolInfo, PromptConfig, PromptSkillConfig, RemoteMcpConfiguration, type ServerOptions, Skill, SkillMetadata, SkillsConfig, SseTransportHandler, StdioTransportHandler, TRANSPORT_MODE, Tool, ToolDefinition, TransportConfig, TransportHandler, TransportMode, createServer };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as createServer, n as SseTransportHandler, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-
|
|
1
|
+
import { i as createServer, n as SseTransportHandler, r as StdioTransportHandler, t as HttpTransportHandler } from "./http-D9BDXhHn.mjs";
|
|
2
2
|
|
|
3
3
|
export { HttpTransportHandler, SseTransportHandler, StdioTransportHandler, createServer };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agiflowai/one-mcp",
|
|
3
3
|
"description": "One MCP server package",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.6",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mcp",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"README.md"
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@modelcontextprotocol/sdk": "1.
|
|
22
|
+
"@modelcontextprotocol/sdk": "1.24.0",
|
|
23
23
|
"chalk": "5.6.2",
|
|
24
24
|
"commander": "14.0.1",
|
|
25
25
|
"express": "^4.21.2",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"js-yaml": "^4.1.0",
|
|
28
28
|
"liquidjs": "^10.21.0",
|
|
29
29
|
"zod": "^3.24.1",
|
|
30
|
-
"@agiflowai/aicode-utils": "1.0.
|
|
30
|
+
"@agiflowai/aicode-utils": "1.0.9"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/express": "^5.0.0",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"tsdown": "^0.16.4",
|
|
37
37
|
"typescript": "5.9.3",
|
|
38
38
|
"unplugin-raw": "^0.6.3",
|
|
39
|
-
"vitest": "
|
|
39
|
+
"vitest": "4.0.15"
|
|
40
40
|
},
|
|
41
41
|
"type": "module",
|
|
42
42
|
"exports": {
|