codex-skills-mcp 1.0.0
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 +221 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +95 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +160 -0
- package/dist/index.js.map +1 -0
- package/dist/loader/index.d.ts +68 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/index.js +246 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/remote/github.d.ts +14 -0
- package/dist/remote/github.d.ts.map +1 -0
- package/dist/remote/github.js +90 -0
- package/dist/remote/github.js.map +1 -0
- package/dist/search/index.d.ts +45 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +149 -0
- package/dist/search/index.js.map +1 -0
- package/dist/tools/list-categories.d.ts +4 -0
- package/dist/tools/list-categories.d.ts.map +1 -0
- package/dist/tools/list-categories.js +18 -0
- package/dist/tools/list-categories.js.map +1 -0
- package/dist/tools/list-skill-files.d.ts +5 -0
- package/dist/tools/list-skill-files.d.ts.map +1 -0
- package/dist/tools/list-skill-files.js +61 -0
- package/dist/tools/list-skill-files.js.map +1 -0
- package/dist/tools/load-skill-file.d.ts +5 -0
- package/dist/tools/load-skill-file.d.ts.map +1 -0
- package/dist/tools/load-skill-file.js +41 -0
- package/dist/tools/load-skill-file.js.map +1 -0
- package/dist/tools/plan-workflow.d.ts +4 -0
- package/dist/tools/plan-workflow.d.ts.map +1 -0
- package/dist/tools/plan-workflow.js +53 -0
- package/dist/tools/plan-workflow.js.map +1 -0
- package/dist/tools/read-skill.d.ts +5 -0
- package/dist/tools/read-skill.d.ts.map +1 -0
- package/dist/tools/read-skill.js +100 -0
- package/dist/tools/read-skill.js.map +1 -0
- package/dist/tools/search-skills.d.ts +4 -0
- package/dist/tools/search-skills.d.ts.map +1 -0
- package/dist/tools/search-skills.js +32 -0
- package/dist/tools/search-skills.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerListSkillFiles(server, searchEngine, loader) {
|
|
3
|
+
server.tool("list_skill_files", "List the file tree of a skill or a subdirectory within it. Use this to understand a large skill's structure before deciding which files to load.", {
|
|
4
|
+
skill_name: z.string().describe("Skill name, e.g. 'KrillinAI'"),
|
|
5
|
+
path: z.string().optional().default("").describe("Subdirectory path within the skill (default: root)"),
|
|
6
|
+
max_depth: z.number().optional().default(2).describe("Directory scan depth (default: 2)"),
|
|
7
|
+
}, async ({ skill_name, path, max_depth }) => {
|
|
8
|
+
const entry = searchEngine.findByName(skill_name);
|
|
9
|
+
if (!entry) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `Skill "${skill_name}" not found.`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const files = await loader.listSkillFiles(entry, path, max_depth);
|
|
21
|
+
const treeStr = formatFileTree(files, "");
|
|
22
|
+
return {
|
|
23
|
+
content: [
|
|
24
|
+
{
|
|
25
|
+
type: "text",
|
|
26
|
+
text: `## ${skill_name}${path ? "/" + path : ""} file tree\n\n\`\`\`\n${treeStr}\n\`\`\`\n\nUse load_skill_file(skill_name, file_path) to read any file.`,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function formatFileTree(nodes, indent) {
|
|
44
|
+
const lines = [];
|
|
45
|
+
for (const node of nodes) {
|
|
46
|
+
if (node.type === "directory") {
|
|
47
|
+
lines.push(`${indent}📁 ${node.name}/`);
|
|
48
|
+
if (node.children) {
|
|
49
|
+
lines.push(formatFileTree(node.children, indent + " "));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const size = node.size_bytes
|
|
54
|
+
? ` (${node.size_bytes > 1024 ? Math.round(node.size_bytes / 1024) + "KB" : node.size_bytes + "B"})`
|
|
55
|
+
: "";
|
|
56
|
+
lines.push(`${indent}📄 ${node.name}${size}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return lines.join("\n");
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=list-skill-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-skill-files.js","sourceRoot":"","sources":["../../src/tools/list-skill-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { SkillSearchEngine } from "../search/index.js";
|
|
3
|
+
import type { SkillLoader } from "../loader/index.js";
|
|
4
|
+
export declare function registerLoadSkillFile(server: McpServer, searchEngine: SkillSearchEngine, loader: SkillLoader): void;
|
|
5
|
+
//# sourceMappingURL=load-skill-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-skill-file.d.ts","sourceRoot":"","sources":["../../src/tools/load-skill-file.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,iBAAiB,EAC/B,MAAM,EAAE,WAAW,GAClB,IAAI,CA4CN"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerLoadSkillFile(server, searchEngine, loader) {
|
|
3
|
+
server.tool("load_skill_file", "Read a specific file from within a skill's directory. Use this after read_skill when you need to access scripts, configs, README, or other resources referenced in the skill instructions.", {
|
|
4
|
+
skill_name: z.string().describe("Skill name, e.g. 'MediaCrawler'"),
|
|
5
|
+
file_path: z.string().describe("Relative path within the skill directory, e.g. 'README.md' or 'scripts/run.py'"),
|
|
6
|
+
}, async ({ skill_name, file_path }) => {
|
|
7
|
+
const entry = searchEngine.findByName(skill_name);
|
|
8
|
+
if (!entry) {
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: `Skill "${skill_name}" not found.`,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const { content, size_bytes } = await loader.loadSkillFile(entry, file_path);
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
type: "text",
|
|
24
|
+
text: `## ${skill_name} / ${file_path} (${size_bytes} bytes)\n\n${content}`,
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: "text",
|
|
34
|
+
text: `Error loading file: ${err instanceof Error ? err.message : String(err)}`,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=load-skill-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-skill-file.js","sourceRoot":"","sources":["../../src/tools/load-skill-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,YAA+B,EAC/B,MAAmB;IAEnB,MAAM,CAAC,IAAI,CACT,iBAAiB,EACjB,4LAA4L,EAC5L;QACE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;QAClE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gFAAgF,CAAC;KACjH,EACD,KAAK,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE;QAClC,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,UAAU,UAAU,cAAc;qBACzC;iBACF;aACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAE7E,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,MAAM,UAAU,MAAM,SAAS,KAAK,UAAU,cAAc,OAAO,EAAE;qBAC5E;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;qBAChF;iBACF;aACF,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { SkillSearchEngine } from "../search/index.js";
|
|
3
|
+
export declare function registerPlanWorkflow(server: McpServer, searchEngine: SkillSearchEngine): void;
|
|
4
|
+
//# sourceMappingURL=plan-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-workflow.d.ts","sourceRoot":"","sources":["../../src/tools/plan-workflow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,iBAAiB,GAC9B,IAAI,CA8DN"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerPlanWorkflow(server, searchEngine) {
|
|
3
|
+
server.tool("plan_workflow", "Given a task description, suggest relevant skills that could be combined to accomplish it. Returns a list of recommended skills — the actual orchestration and execution order should be decided by you (the Agent).", {
|
|
4
|
+
task_description: z.string().describe("Full description of the task to accomplish, e.g. '把技术博客文章转换成小红书图文并发布'"),
|
|
5
|
+
}, async ({ task_description }) => {
|
|
6
|
+
// Use a broader search to find related skills
|
|
7
|
+
const results = searchEngine.search(task_description, { limit: 15 });
|
|
8
|
+
if (results.length === 0) {
|
|
9
|
+
return {
|
|
10
|
+
content: [
|
|
11
|
+
{
|
|
12
|
+
type: "text",
|
|
13
|
+
text: `No skills found for this task. Consider breaking it down into smaller sub-tasks and searching individually.`,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
// Group by category for better overview
|
|
19
|
+
const byCategory = new Map();
|
|
20
|
+
for (const r of results) {
|
|
21
|
+
const list = byCategory.get(r.category) || [];
|
|
22
|
+
list.push(r);
|
|
23
|
+
byCategory.set(r.category, list);
|
|
24
|
+
}
|
|
25
|
+
let output = `## Workflow Suggestions for:\n> ${task_description}\n\n`;
|
|
26
|
+
output += `Found ${results.length} potentially relevant skills:\n\n`;
|
|
27
|
+
// Top recommendations (score > 3)
|
|
28
|
+
const topSkills = results.filter((r) => r.score > 3);
|
|
29
|
+
if (topSkills.length > 0) {
|
|
30
|
+
output += "### 🎯 Top Recommendations\n";
|
|
31
|
+
for (const s of topSkills) {
|
|
32
|
+
output += `- **${s.name}** (score: ${s.score}) — ${s.description.substring(0, 150)}...\n`;
|
|
33
|
+
}
|
|
34
|
+
output += "\n";
|
|
35
|
+
}
|
|
36
|
+
// All by category
|
|
37
|
+
output += "### 📂 By Category\n";
|
|
38
|
+
for (const [category, skills] of byCategory) {
|
|
39
|
+
output += `\n**${category}**:\n`;
|
|
40
|
+
for (const s of skills) {
|
|
41
|
+
output += ` - ${s.name} (score: ${s.score})\n`;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
output += "\n---\n";
|
|
45
|
+
output +=
|
|
46
|
+
"Use read_skill(name) to load each skill's instructions. " +
|
|
47
|
+
"You should determine the execution order and how to chain the skills based on your task analysis.";
|
|
48
|
+
return {
|
|
49
|
+
content: [{ type: "text", text: output }],
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=plan-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-workflow.js","sourceRoot":"","sources":["../../src/tools/plan-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,YAA+B;IAE/B,MAAM,CAAC,IAAI,CACT,eAAe,EACf,sNAAsN,EACtN;QACE,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uEAAuE,CAAC;KAC/G,EACD,KAAK,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE;QAC7B,8CAA8C;QAC9C,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAErE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,6GAA6G;qBACpH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,wCAAwC;QACxC,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACb,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,IAAI,MAAM,GAAG,mCAAmC,gBAAgB,MAAM,CAAC;QACvE,MAAM,IAAI,SAAS,OAAO,CAAC,MAAM,mCAAmC,CAAC;QAErE,kCAAkC;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACrD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,8BAA8B,CAAC;YACzC,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1B,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;YAC5F,CAAC;YACD,MAAM,IAAI,IAAI,CAAC;QACjB,CAAC;QAED,kBAAkB;QAClB,MAAM,IAAI,sBAAsB,CAAC;QACjC,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC5C,MAAM,IAAI,OAAO,QAAQ,OAAO,CAAC;YACjC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,YAAY,CAAC,CAAC,KAAK,KAAK,CAAC;YAClD,CAAC;QACH,CAAC;QAED,MAAM,IAAI,SAAS,CAAC;QACpB,MAAM;YACJ,0DAA0D;gBAC1D,mGAAmG,CAAC;QAEtG,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { SkillSearchEngine } from "../search/index.js";
|
|
3
|
+
import type { SkillLoader } from "../loader/index.js";
|
|
4
|
+
export declare function registerReadSkill(server: McpServer, searchEngine: SkillSearchEngine, loader: SkillLoader): void;
|
|
5
|
+
//# sourceMappingURL=read-skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-skill.d.ts","sourceRoot":"","sources":["../../src/tools/read-skill.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,iBAAiB,EAC/B,MAAM,EAAE,WAAW,GAClB,IAAI,CAwFN"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerReadSkill(server, searchEngine, loader) {
|
|
3
|
+
server.tool("read_skill", "Read a skill's full instructions (SKILL.md), file structure, and dependency info. Call this after search_skills to load a skill you want to use. The instructions contain the role and execution rules you should follow.", {
|
|
4
|
+
name: z.string().describe("Exact skill name from search results, e.g. 'MediaCrawler'"),
|
|
5
|
+
}, async ({ name }) => {
|
|
6
|
+
const entry = searchEngine.findByName(name);
|
|
7
|
+
if (!entry) {
|
|
8
|
+
return {
|
|
9
|
+
content: [
|
|
10
|
+
{
|
|
11
|
+
type: "text",
|
|
12
|
+
text: `Skill "${name}" not found. Use search_skills to find available skills.`,
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const result = await loader.readSkill(entry);
|
|
19
|
+
// Format structure as a compact tree
|
|
20
|
+
const structureStr = formatTree(result.structure.files, "");
|
|
21
|
+
// Format sub-skills if any
|
|
22
|
+
let subSkillsStr = "";
|
|
23
|
+
if (result.structure.sub_skills.length > 0) {
|
|
24
|
+
subSkillsStr =
|
|
25
|
+
"\n\n## Sub-Skills\n" +
|
|
26
|
+
result.structure.sub_skills
|
|
27
|
+
.map((s) => `- **${s.name}** (${s.path}): ${s.description}`)
|
|
28
|
+
.join("\n");
|
|
29
|
+
subSkillsStr +=
|
|
30
|
+
"\n\nUse read_skill or load_skill_file to access sub-skill instructions.";
|
|
31
|
+
}
|
|
32
|
+
// Format dependencies
|
|
33
|
+
const depsStr = [
|
|
34
|
+
`Language: ${result.dependencies.language}`,
|
|
35
|
+
result.dependencies.package_manager
|
|
36
|
+
? `Package Manager: ${result.dependencies.package_manager}`
|
|
37
|
+
: null,
|
|
38
|
+
result.dependencies.setup_command
|
|
39
|
+
? `Setup: \`${result.dependencies.setup_command}\``
|
|
40
|
+
: null,
|
|
41
|
+
]
|
|
42
|
+
.filter(Boolean)
|
|
43
|
+
.join(" | ");
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: [
|
|
49
|
+
`# Skill: ${entry.name}`,
|
|
50
|
+
`**Category**: ${entry.category}`,
|
|
51
|
+
`**Dependencies**: ${depsStr}`,
|
|
52
|
+
"",
|
|
53
|
+
"## Instructions",
|
|
54
|
+
"",
|
|
55
|
+
result.instructions,
|
|
56
|
+
"",
|
|
57
|
+
"## File Structure",
|
|
58
|
+
"```",
|
|
59
|
+
structureStr,
|
|
60
|
+
"```",
|
|
61
|
+
subSkillsStr,
|
|
62
|
+
"",
|
|
63
|
+
"---",
|
|
64
|
+
"Use load_skill_file(skill_name, file_path) to read any file shown above.",
|
|
65
|
+
].join("\n"),
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: `Error reading skill "${name}": ${err instanceof Error ? err.message : String(err)}`,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function formatTree(nodes, indent) {
|
|
83
|
+
const lines = [];
|
|
84
|
+
for (const node of nodes) {
|
|
85
|
+
if (node.type === "directory") {
|
|
86
|
+
lines.push(`${indent}📁 ${node.name}/`);
|
|
87
|
+
if (node.children) {
|
|
88
|
+
lines.push(formatTree(node.children, indent + " "));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const size = node.size_bytes
|
|
93
|
+
? ` (${node.size_bytes > 1024 ? Math.round(node.size_bytes / 1024) + "KB" : node.size_bytes + "B"})`
|
|
94
|
+
: "";
|
|
95
|
+
lines.push(`${indent}📄 ${node.name}${size}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return lines.join("\n");
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=read-skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-skill.js","sourceRoot":"","sources":["../../src/tools/read-skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { SkillSearchEngine } from "../search/index.js";
|
|
3
|
+
export declare function registerSearchSkills(server: McpServer, searchEngine: SkillSearchEngine): void;
|
|
4
|
+
//# sourceMappingURL=search-skills.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-skills.d.ts","sourceRoot":"","sources":["../../src/tools/search-skills.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,iBAAiB,GAC9B,IAAI,CAwCN"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export function registerSearchSkills(server, searchEngine) {
|
|
3
|
+
server.tool("search_skills", "Search the codex-skills library by natural language query. Returns matching skills ranked by relevance. Use this as the primary entry point to discover skills for a task.", {
|
|
4
|
+
query: z.string().describe("Natural language description of what you need, e.g. '前端性能优化' or 'video subtitle translation'"),
|
|
5
|
+
category: z.string().optional().describe("Optional category filter, e.g. '05_多媒体与设计资产'"),
|
|
6
|
+
limit: z.number().optional().default(8).describe("Max number of results to return (default: 8)"),
|
|
7
|
+
}, async ({ query, category, limit }) => {
|
|
8
|
+
const results = searchEngine.search(query, { category, limit });
|
|
9
|
+
if (results.length === 0) {
|
|
10
|
+
return {
|
|
11
|
+
content: [
|
|
12
|
+
{
|
|
13
|
+
type: "text",
|
|
14
|
+
text: `No skills found matching "${query}". Try broader keywords or use list_categories to browse available skills.`,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const formatted = results
|
|
20
|
+
.map((r, i) => `${i + 1}. **${r.name}** [${r.category}] (score: ${r.score})\n ${r.description.substring(0, 200)}${r.description.length > 200 ? "..." : ""}`)
|
|
21
|
+
.join("\n\n");
|
|
22
|
+
return {
|
|
23
|
+
content: [
|
|
24
|
+
{
|
|
25
|
+
type: "text",
|
|
26
|
+
text: `Found ${results.length} matching skills:\n\n${formatted}\n\nUse read_skill(name) to load a skill's full instructions.`,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=search-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-skills.js","sourceRoot":"","sources":["../../src/tools/search-skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,YAA+B;IAE/B,MAAM,CAAC,IAAI,CACT,eAAe,EACf,4KAA4K,EAC5K;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8FAA8F,CAAC;QAC1H,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QACxF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;KACjG,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,EAAE;QACnC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAEhE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,6BAA6B,KAAK,4EAA4E;qBACrH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CACF,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,QAAQ,aAAa,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CACjJ;aACA,IAAI,CAAC,MAAM,CAAC,CAAC;QAEhB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,wBAAwB,SAAS,+DAA+D;iBAC9H;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codex-skills-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP Server for Codex-Skills - Intelligent skill library search, read and orchestration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"codex-skills-mcp": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"start": "node dist/index.js",
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"mcp",
|
|
21
|
+
"codex-skills",
|
|
22
|
+
"ai-skills",
|
|
23
|
+
"model-context-protocol"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
28
|
+
"express": "^5.2.1",
|
|
29
|
+
"zod": "^3.25.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/express": "^5.0.6",
|
|
33
|
+
"@types/node": "^22.0.0",
|
|
34
|
+
"typescript": "^5.8.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|