superkit-mcp-server 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 +44 -0
- package/build/index.js +191 -0
- package/package.json +23 -0
- package/src/index.ts +219 -0
- package/tsconfig.json +16 -0
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Super-Kit MCP Server
|
|
2
|
+
|
|
3
|
+
This is a Model Context Protocol (MCP) server that exposes the agents, skills, and workflows of **Super-Kit** to any compatible AI assistant (Cline, Cursor, Gemini, etc.).
|
|
4
|
+
|
|
5
|
+
By installing this MCP server, your AI agent can dynamically list, read, and load the specific operational contexts it needs on the fly, without needing massive system prompts.
|
|
6
|
+
|
|
7
|
+
## Available Tools
|
|
8
|
+
|
|
9
|
+
- **`list_superkit_assets`**: Lists all available agents, skills (tech/meta), and workflows in the Super-Kit repository.
|
|
10
|
+
- **`load_superkit_agent`**: Loads the system instructions and guidelines for a specific specialist agent (e.g., `data-engineer`).
|
|
11
|
+
- **`load_superkit_skill`**: Loads the skill instructions (`SKILL.md`) for a specific category and skill (e.g., category: `tech`, name: `react-best-practices`).
|
|
12
|
+
- **`load_superkit_workflow`**: Loads the instructions for a specific slash-command workflow (e.g., `work`, `explore`).
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
cd super-kit/mcp-server
|
|
18
|
+
npm install
|
|
19
|
+
npm run build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Configuring in AI Platforms
|
|
23
|
+
|
|
24
|
+
### Cline (VS Code)
|
|
25
|
+
Add the following to your `cline_mcp_settings.json`:
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"superkit": {
|
|
30
|
+
"command": "node",
|
|
31
|
+
"args": ["/absolute/path/to/super-kit/mcp-server/build/index.js"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Cursor / Windsurf
|
|
38
|
+
Go to Settings -> Features -> MCP Servers.
|
|
39
|
+
Add a new stdio server:
|
|
40
|
+
- Name: `superkit`
|
|
41
|
+
- Command: `node /absolute/path/to/super-kit/mcp-server/build/index.js`
|
|
42
|
+
|
|
43
|
+
## How it works
|
|
44
|
+
The server reads directly from the parent `super-kit` directory, resolving paths safely to prevent traversal attacks. It automatically parses and returns the Markdown contents of the structural elements.
|
package/build/index.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as fs from "fs/promises";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
// Assuming __dirname is super-kit/mcp-server/build
|
|
11
|
+
const IS_BUILD = __dirname.endsWith("build");
|
|
12
|
+
const superKitRoot = IS_BUILD ? path.resolve(__dirname, "../../") : path.resolve(__dirname, "../");
|
|
13
|
+
const server = new Server({
|
|
14
|
+
name: "superkit-mcp-server",
|
|
15
|
+
version: "1.0.0",
|
|
16
|
+
}, {
|
|
17
|
+
capabilities: {
|
|
18
|
+
tools: {},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
// Helper function to read directory contents, tracking if they are directories or files
|
|
22
|
+
async function listDirectorySafe(dirPath) {
|
|
23
|
+
try {
|
|
24
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
25
|
+
return entries.map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name));
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Ensure safe path resolution to prevent traversal
|
|
32
|
+
function getSafePath(basePath, relativePath) {
|
|
33
|
+
// Normalize and resolve
|
|
34
|
+
const resolvedPath = path.resolve(basePath, relativePath);
|
|
35
|
+
// Check if it starts with the basePath
|
|
36
|
+
if (!resolvedPath.startsWith(basePath)) {
|
|
37
|
+
return null; // Path traversal detected
|
|
38
|
+
}
|
|
39
|
+
return resolvedPath;
|
|
40
|
+
}
|
|
41
|
+
const TOOLS = [
|
|
42
|
+
{
|
|
43
|
+
name: "list_superkit_assets",
|
|
44
|
+
description: "Lists all available agents, skills, and workflows in the Super-Kit repository.",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {},
|
|
48
|
+
required: [],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "load_superkit_agent",
|
|
53
|
+
description: "Loads the instruction markdown for a specific specialist agent.",
|
|
54
|
+
inputSchema: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: {
|
|
57
|
+
agentName: {
|
|
58
|
+
type: "string",
|
|
59
|
+
description: "The name of the agent to load (e.g., 'data-engineer'). Do not include .md.",
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
required: ["agentName"],
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "load_superkit_skill",
|
|
67
|
+
description: "Loads the skill index (SKILL.md) or specific reference file for a skill.",
|
|
68
|
+
inputSchema: {
|
|
69
|
+
type: "object",
|
|
70
|
+
properties: {
|
|
71
|
+
category: {
|
|
72
|
+
type: "string",
|
|
73
|
+
description: "The category of the skill (e.g., 'tech', 'meta', 'workflows').",
|
|
74
|
+
},
|
|
75
|
+
skillName: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "The name of the skill directory (e.g., 'react-best-practices').",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
required: ["category", "skillName"],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: "load_superkit_workflow",
|
|
85
|
+
description: "Loads the instructions for a specific workflow.",
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
workflowName: {
|
|
90
|
+
type: "string",
|
|
91
|
+
description: "The name of the workflow (e.g., 'plan', 'explore'). Do not include .md.",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ["workflowName"],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
];
|
|
98
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
99
|
+
return { tools: TOOLS };
|
|
100
|
+
});
|
|
101
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
102
|
+
try {
|
|
103
|
+
if (request.params.name === "list_superkit_assets") {
|
|
104
|
+
const agentsPath = path.join(superKitRoot, "agents");
|
|
105
|
+
const skillsTechPath = path.join(superKitRoot, "skills", "tech");
|
|
106
|
+
const skillsMetaPath = path.join(superKitRoot, "skills", "meta");
|
|
107
|
+
const workflowsPath = path.join(superKitRoot, "workflows");
|
|
108
|
+
const agents = await listDirectorySafe(agentsPath);
|
|
109
|
+
const techSkills = await listDirectorySafe(skillsTechPath);
|
|
110
|
+
const metaSkills = await listDirectorySafe(skillsMetaPath);
|
|
111
|
+
const workflows = await listDirectorySafe(workflowsPath);
|
|
112
|
+
return {
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
type: "text",
|
|
116
|
+
text: JSON.stringify({
|
|
117
|
+
agents: agents.map((a) => a.replace(".md", "")),
|
|
118
|
+
skills: {
|
|
119
|
+
tech: techSkills.map((s) => s.replace("/", "")),
|
|
120
|
+
meta: metaSkills.map((s) => s.replace("/", "")),
|
|
121
|
+
},
|
|
122
|
+
workflows: workflows.map((w) => w.replace(".md", "")),
|
|
123
|
+
}, null, 2),
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (request.params.name === "load_superkit_agent") {
|
|
129
|
+
const args = request.params.arguments;
|
|
130
|
+
if (!args.agentName)
|
|
131
|
+
throw new Error("Missing agentName");
|
|
132
|
+
const agentFile = `${args.agentName}.md`;
|
|
133
|
+
const baseDir = path.join(superKitRoot, "agents");
|
|
134
|
+
const safePath = getSafePath(baseDir, agentFile);
|
|
135
|
+
if (!safePath)
|
|
136
|
+
throw new Error("Invalid agent path");
|
|
137
|
+
const content = await fs.readFile(safePath, "utf-8");
|
|
138
|
+
return { content: [{ type: "text", text: content }] };
|
|
139
|
+
}
|
|
140
|
+
if (request.params.name === "load_superkit_skill") {
|
|
141
|
+
const args = request.params.arguments;
|
|
142
|
+
if (!args.category || !args.skillName)
|
|
143
|
+
throw new Error("Missing category or skillName");
|
|
144
|
+
const baseDir = path.join(superKitRoot, "skills", args.category, args.skillName);
|
|
145
|
+
const safePath = getSafePath(path.join(superKitRoot, "skills"), path.join(args.category, args.skillName, "SKILL.md"));
|
|
146
|
+
if (!safePath)
|
|
147
|
+
throw new Error("Invalid skill path");
|
|
148
|
+
try {
|
|
149
|
+
const content = await fs.readFile(safePath, "utf-8");
|
|
150
|
+
return { content: [{ type: "text", text: content }] };
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
// If SKILL.md isn't there, just return the directory context if we can.
|
|
154
|
+
const fallbackSafePath = getSafePath(path.join(superKitRoot, "skills"), path.join(args.category, args.skillName));
|
|
155
|
+
if (fallbackSafePath) {
|
|
156
|
+
const items = await listDirectorySafe(fallbackSafePath);
|
|
157
|
+
return { content: [{ type: "text", text: `SKILL.md not found. Directory contains: ${items.join(', ')}` }] };
|
|
158
|
+
}
|
|
159
|
+
throw e;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (request.params.name === "load_superkit_workflow") {
|
|
163
|
+
const args = request.params.arguments;
|
|
164
|
+
if (!args.workflowName)
|
|
165
|
+
throw new Error("Missing workflowName");
|
|
166
|
+
const workflowFile = `${args.workflowName}.md`;
|
|
167
|
+
const baseDir = path.join(superKitRoot, "workflows");
|
|
168
|
+
const safePath = getSafePath(baseDir, workflowFile);
|
|
169
|
+
if (!safePath)
|
|
170
|
+
throw new Error("Invalid workflow path");
|
|
171
|
+
const content = await fs.readFile(safePath, "utf-8");
|
|
172
|
+
return { content: [{ type: "text", text: content }] };
|
|
173
|
+
}
|
|
174
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
return {
|
|
178
|
+
content: [{ type: "text", text: `Error executing tool: ${error.message}` }],
|
|
179
|
+
isError: true,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
async function main() {
|
|
184
|
+
const transport = new StdioServerTransport();
|
|
185
|
+
await server.connect(transport);
|
|
186
|
+
console.error("Super-Kit MCP Server running on stdio");
|
|
187
|
+
}
|
|
188
|
+
main().catch((error) => {
|
|
189
|
+
console.error("Server error:", error);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "superkit-mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "An MCP server for exploring and loading Super-Kit AI agent resources.",
|
|
6
|
+
"main": "build/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"superkit-mcp-server": "./build/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node build/index.js",
|
|
13
|
+
"dev": "tsc --watch"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@modelcontextprotocol/sdk": "^1.4.1",
|
|
17
|
+
"zod": "^3.23.8"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^22.10.1",
|
|
21
|
+
"typescript": "^5.7.2"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
Tool,
|
|
9
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
10
|
+
import * as path from "path";
|
|
11
|
+
import * as fs from "fs/promises";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
13
|
+
import { z } from "zod";
|
|
14
|
+
|
|
15
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
16
|
+
const __dirname = path.dirname(__filename);
|
|
17
|
+
// Assuming __dirname is super-kit/mcp-server/build
|
|
18
|
+
const IS_BUILD = __dirname.endsWith("build");
|
|
19
|
+
const superKitRoot = IS_BUILD ? path.resolve(__dirname, "../../") : path.resolve(__dirname, "../");
|
|
20
|
+
|
|
21
|
+
const server = new Server(
|
|
22
|
+
{
|
|
23
|
+
name: "superkit-mcp-server",
|
|
24
|
+
version: "1.0.0",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
capabilities: {
|
|
28
|
+
tools: {},
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Helper function to read directory contents, tracking if they are directories or files
|
|
34
|
+
async function listDirectorySafe(dirPath: string): Promise<string[]> {
|
|
35
|
+
try {
|
|
36
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
37
|
+
return entries.map((entry) => (entry.isDirectory() ? `${entry.name}/` : entry.name));
|
|
38
|
+
} catch (err) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Ensure safe path resolution to prevent traversal
|
|
44
|
+
function getSafePath(basePath: string, relativePath: string): string | null {
|
|
45
|
+
// Normalize and resolve
|
|
46
|
+
const resolvedPath = path.resolve(basePath, relativePath);
|
|
47
|
+
// Check if it starts with the basePath
|
|
48
|
+
if (!resolvedPath.startsWith(basePath)) {
|
|
49
|
+
return null; // Path traversal detected
|
|
50
|
+
}
|
|
51
|
+
return resolvedPath;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const TOOLS: Tool[] = [
|
|
55
|
+
{
|
|
56
|
+
name: "list_superkit_assets",
|
|
57
|
+
description: "Lists all available agents, skills, and workflows in the Super-Kit repository.",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {},
|
|
61
|
+
required: [],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "load_superkit_agent",
|
|
66
|
+
description: "Loads the instruction markdown for a specific specialist agent.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
agentName: {
|
|
71
|
+
type: "string",
|
|
72
|
+
description: "The name of the agent to load (e.g., 'data-engineer'). Do not include .md.",
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ["agentName"],
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "load_superkit_skill",
|
|
80
|
+
description: "Loads the skill index (SKILL.md) or specific reference file for a skill.",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
category: {
|
|
85
|
+
type: "string",
|
|
86
|
+
description: "The category of the skill (e.g., 'tech', 'meta', 'workflows').",
|
|
87
|
+
},
|
|
88
|
+
skillName: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "The name of the skill directory (e.g., 'react-best-practices').",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
required: ["category", "skillName"],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "load_superkit_workflow",
|
|
98
|
+
description: "Loads the instructions for a specific workflow.",
|
|
99
|
+
inputSchema: {
|
|
100
|
+
type: "object",
|
|
101
|
+
properties: {
|
|
102
|
+
workflowName: {
|
|
103
|
+
type: "string",
|
|
104
|
+
description: "The name of the workflow (e.g., 'plan', 'explore'). Do not include .md.",
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
required: ["workflowName"],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
113
|
+
return { tools: TOOLS };
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
117
|
+
try {
|
|
118
|
+
if (request.params.name === "list_superkit_assets") {
|
|
119
|
+
const agentsPath = path.join(superKitRoot, "agents");
|
|
120
|
+
const skillsTechPath = path.join(superKitRoot, "skills", "tech");
|
|
121
|
+
const skillsMetaPath = path.join(superKitRoot, "skills", "meta");
|
|
122
|
+
const workflowsPath = path.join(superKitRoot, "workflows");
|
|
123
|
+
|
|
124
|
+
const agents = await listDirectorySafe(agentsPath);
|
|
125
|
+
const techSkills = await listDirectorySafe(skillsTechPath);
|
|
126
|
+
const metaSkills = await listDirectorySafe(skillsMetaPath);
|
|
127
|
+
const workflows = await listDirectorySafe(workflowsPath);
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
content: [
|
|
131
|
+
{
|
|
132
|
+
type: "text",
|
|
133
|
+
text: JSON.stringify(
|
|
134
|
+
{
|
|
135
|
+
agents: agents.map((a) => a.replace(".md", "")),
|
|
136
|
+
skills: {
|
|
137
|
+
tech: techSkills.map((s) => s.replace("/", "")),
|
|
138
|
+
meta: metaSkills.map((s) => s.replace("/", "")),
|
|
139
|
+
},
|
|
140
|
+
workflows: workflows.map((w) => w.replace(".md", "")),
|
|
141
|
+
},
|
|
142
|
+
null,
|
|
143
|
+
2
|
|
144
|
+
),
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (request.params.name === "load_superkit_agent") {
|
|
151
|
+
const args = request.params.arguments as { agentName: string };
|
|
152
|
+
if (!args.agentName) throw new Error("Missing agentName");
|
|
153
|
+
|
|
154
|
+
const agentFile = `${args.agentName}.md`;
|
|
155
|
+
const baseDir = path.join(superKitRoot, "agents");
|
|
156
|
+
const safePath = getSafePath(baseDir, agentFile);
|
|
157
|
+
|
|
158
|
+
if (!safePath) throw new Error("Invalid agent path");
|
|
159
|
+
|
|
160
|
+
const content = await fs.readFile(safePath, "utf-8");
|
|
161
|
+
return { content: [{ type: "text", text: content }] };
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (request.params.name === "load_superkit_skill") {
|
|
165
|
+
const args = request.params.arguments as { category: string; skillName: string };
|
|
166
|
+
if (!args.category || !args.skillName) throw new Error("Missing category or skillName");
|
|
167
|
+
|
|
168
|
+
const baseDir = path.join(superKitRoot, "skills", args.category, args.skillName);
|
|
169
|
+
const safePath = getSafePath(path.join(superKitRoot, "skills"), path.join(args.category, args.skillName, "SKILL.md"));
|
|
170
|
+
|
|
171
|
+
if (!safePath) throw new Error("Invalid skill path");
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
const content = await fs.readFile(safePath, "utf-8");
|
|
175
|
+
return { content: [{ type: "text", text: content }] };
|
|
176
|
+
} catch (e) {
|
|
177
|
+
// If SKILL.md isn't there, just return the directory context if we can.
|
|
178
|
+
const fallbackSafePath = getSafePath(path.join(superKitRoot, "skills"), path.join(args.category, args.skillName));
|
|
179
|
+
if (fallbackSafePath) {
|
|
180
|
+
const items = await listDirectorySafe(fallbackSafePath);
|
|
181
|
+
return { content: [{ type: "text", text: `SKILL.md not found. Directory contains: ${items.join(', ')}` }] };
|
|
182
|
+
}
|
|
183
|
+
throw e;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (request.params.name === "load_superkit_workflow") {
|
|
188
|
+
const args = request.params.arguments as { workflowName: string };
|
|
189
|
+
if (!args.workflowName) throw new Error("Missing workflowName");
|
|
190
|
+
|
|
191
|
+
const workflowFile = `${args.workflowName}.md`;
|
|
192
|
+
const baseDir = path.join(superKitRoot, "workflows");
|
|
193
|
+
const safePath = getSafePath(baseDir, workflowFile);
|
|
194
|
+
|
|
195
|
+
if (!safePath) throw new Error("Invalid workflow path");
|
|
196
|
+
|
|
197
|
+
const content = await fs.readFile(safePath, "utf-8");
|
|
198
|
+
return { content: [{ type: "text", text: content }] };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
202
|
+
} catch (error: any) {
|
|
203
|
+
return {
|
|
204
|
+
content: [{ type: "text", text: `Error executing tool: ${error.message}` }],
|
|
205
|
+
isError: true,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
async function main() {
|
|
211
|
+
const transport = new StdioServerTransport();
|
|
212
|
+
await server.connect(transport);
|
|
213
|
+
console.error("Super-Kit MCP Server running on stdio");
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
main().catch((error) => {
|
|
217
|
+
console.error("Server error:", error);
|
|
218
|
+
process.exit(1);
|
|
219
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "./build",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true
|
|
12
|
+
},
|
|
13
|
+
"include": [
|
|
14
|
+
"src/**/*"
|
|
15
|
+
]
|
|
16
|
+
}
|