staff-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/LICENSE +21 -0
- package/README.md +89 -0
- package/README_zh.md +89 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/security.d.ts +16 -0
- package/dist/security.js +43 -0
- package/dist/security.js.map +1 -0
- package/dist/server.d.ts +9 -0
- package/dist/server.js +25 -0
- package/dist/server.js.map +1 -0
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.js +3 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +29 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/security.d.ts +21 -0
- package/dist/src/security.js +51 -0
- package/dist/src/security.js.map +1 -0
- package/dist/src/server.d.ts +10 -0
- package/dist/src/server.js +34 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/tools/file-tools.d.ts +6 -0
- package/dist/src/tools/file-tools.js +230 -0
- package/dist/src/tools/file-tools.js.map +1 -0
- package/dist/src/tools/lsp-tools.d.ts +10 -0
- package/dist/src/tools/lsp-tools.js +124 -0
- package/dist/src/tools/lsp-tools.js.map +1 -0
- package/dist/src/tools/shell-tools.d.ts +6 -0
- package/dist/src/tools/shell-tools.js +138 -0
- package/dist/src/tools/shell-tools.js.map +1 -0
- package/dist/src/tools/skill-manager.d.ts +14 -0
- package/dist/src/tools/skill-manager.js +97 -0
- package/dist/src/tools/skill-manager.js.map +1 -0
- package/dist/src/tools/skill-tools.d.ts +3 -0
- package/dist/src/tools/skill-tools.js +117 -0
- package/dist/src/tools/skill-tools.js.map +1 -0
- package/dist/src/tools/system-tools.d.ts +6 -0
- package/dist/src/tools/system-tools.js +36 -0
- package/dist/src/tools/system-tools.js.map +1 -0
- package/dist/src/transports/http.d.ts +5 -0
- package/dist/src/transports/http.js +58 -0
- package/dist/src/transports/http.js.map +1 -0
- package/dist/src/transports/stdio.d.ts +2 -0
- package/dist/src/transports/stdio.js +18 -0
- package/dist/src/transports/stdio.js.map +1 -0
- package/dist/tests/security.test.d.ts +1 -0
- package/dist/tests/security.test.js +21 -0
- package/dist/tests/security.test.js.map +1 -0
- package/dist/tools/file-tools.d.ts +6 -0
- package/dist/tools/file-tools.js +102 -0
- package/dist/tools/file-tools.js.map +1 -0
- package/dist/tools/lsp-tools.d.ts +6 -0
- package/dist/tools/lsp-tools.js +70 -0
- package/dist/tools/lsp-tools.js.map +1 -0
- package/dist/tools/shell-tools.d.ts +6 -0
- package/dist/tools/shell-tools.js +39 -0
- package/dist/tools/shell-tools.js.map +1 -0
- package/dist/transports/http.d.ts +5 -0
- package/dist/transports/http.js +58 -0
- package/dist/transports/http.js.map +1 -0
- package/dist/transports/stdio.d.ts +2 -0
- package/dist/transports/stdio.js +18 -0
- package/dist/transports/stdio.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import * as fs from "fs/promises";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { CHARACTER_LIMIT } from "../constants.js";
|
|
5
|
+
import { getPathDiagnostics } from "./lsp-tools.js";
|
|
6
|
+
/**
|
|
7
|
+
* Registers file-related tools using the latest registerTool API.
|
|
8
|
+
*/
|
|
9
|
+
export function registerFileTools(server, security) {
|
|
10
|
+
// read_file
|
|
11
|
+
server.registerTool("read_file", {
|
|
12
|
+
description: "Read the content of a file from the allowed workspace.",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
path: z.string().describe("Relative path from the workspace to the file to read."),
|
|
15
|
+
startLine: z.number().optional().describe("1-based line number to start reading from."),
|
|
16
|
+
endLine: z.number().optional().describe("1-based line number to end reading at (inclusive)."),
|
|
17
|
+
}).strict(),
|
|
18
|
+
}, async ({ path: filePath, startLine, endLine }) => {
|
|
19
|
+
try {
|
|
20
|
+
const validatedPath = security.resolveAndValidatePath(filePath);
|
|
21
|
+
const fullContent = await fs.readFile(validatedPath, "utf-8");
|
|
22
|
+
const lines = fullContent.split(/\r?\n/);
|
|
23
|
+
let contentLines = lines;
|
|
24
|
+
let prefix = "";
|
|
25
|
+
if (startLine !== undefined || endLine !== undefined) {
|
|
26
|
+
const start = startLine ? Math.max(0, startLine - 1) : 0;
|
|
27
|
+
const end = endLine ? Math.min(lines.length, endLine) : lines.length;
|
|
28
|
+
contentLines = lines.slice(start, end);
|
|
29
|
+
prefix = `Showing lines ${start + 1}-${end} of ${lines.length}:\n`;
|
|
30
|
+
}
|
|
31
|
+
let content = contentLines.join("\n");
|
|
32
|
+
if (content.length > CHARACTER_LIMIT) {
|
|
33
|
+
content = content.substring(0, CHARACTER_LIMIT) + "\n\n...[Content truncated for brevity]";
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
content: [{ type: "text", text: prefix + content }],
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return {
|
|
41
|
+
content: [{ type: "text", text: `Error reading file: ${error.message}` }],
|
|
42
|
+
isError: true,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
// edit_file_by_replace
|
|
47
|
+
server.registerTool("edit_file_by_replace", {
|
|
48
|
+
description: "Replace a specific block of text in a file with new content. Use this for precise edits.",
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
path: z.string().describe("Path to the file to edit."),
|
|
51
|
+
oldText: z.string().describe("The exact text block to be replaced. Be as specific as possible to avoid wrong matches."),
|
|
52
|
+
newText: z.string().describe("The new text content to replace with."),
|
|
53
|
+
}).strict(),
|
|
54
|
+
}, async ({ path: filePath, oldText, newText }) => {
|
|
55
|
+
try {
|
|
56
|
+
const validatedPath = security.resolveAndValidatePath(filePath);
|
|
57
|
+
const content = await fs.readFile(validatedPath, "utf-8");
|
|
58
|
+
// Simple fuzzy match: try exact first, then trimmed
|
|
59
|
+
let index = content.indexOf(oldText);
|
|
60
|
+
if (index === -1) {
|
|
61
|
+
// Try fuzzy: trim and normalize line endings
|
|
62
|
+
const normalize = (s) => s.replace(/\r\n/g, "\n").trim();
|
|
63
|
+
const normalizedContent = normalize(content);
|
|
64
|
+
const normalizedOld = normalize(oldText);
|
|
65
|
+
if (normalizedContent.includes(normalizedOld)) {
|
|
66
|
+
// If normalized matches, we need to find the actual position in the original content
|
|
67
|
+
// For simplicity, if exact match fails but normalized would work, we warn the model
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: "text", text: `Error: The oldText provided did not match exactly. Please ensure whitespace and line endings match or provide more context.` }],
|
|
70
|
+
isError: true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: "text", text: `Error: Could not find the text block to replace in ${filePath}. Check for typos or provide more context.` }],
|
|
75
|
+
isError: true,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const updatedContent = content.slice(0, index) + newText + content.slice(index + oldText.length);
|
|
79
|
+
await fs.writeFile(validatedPath, updatedContent, "utf-8");
|
|
80
|
+
let response = `Successfully updated ${filePath}`;
|
|
81
|
+
// Add diagnostics feedback for TS files
|
|
82
|
+
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
|
|
83
|
+
const diagnostics = await getPathDiagnostics(filePath, security);
|
|
84
|
+
if (diagnostics) {
|
|
85
|
+
response += `\n\nWarning: TypeScript diagnostics found after editing:\n${diagnostics}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
content: [{ type: "text", text: response }],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
content: [{ type: "text", text: `Error editing file: ${error.message}` }],
|
|
95
|
+
isError: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// write_file
|
|
100
|
+
server.registerTool("write_file", {
|
|
101
|
+
description: "Write or overwrite a file in the allowed workspace.",
|
|
102
|
+
inputSchema: z.object({
|
|
103
|
+
path: z.string().describe("Path to the file to write."),
|
|
104
|
+
content: z.string().describe("Content to write into the file."),
|
|
105
|
+
}).strict(),
|
|
106
|
+
}, async ({ path: filePath, content }) => {
|
|
107
|
+
try {
|
|
108
|
+
const validatedPath = security.resolveAndValidatePath(filePath);
|
|
109
|
+
await fs.mkdir(path.dirname(validatedPath), { recursive: true });
|
|
110
|
+
await fs.writeFile(validatedPath, content, "utf-8");
|
|
111
|
+
let response = `Successfully wrote file: ${filePath}`;
|
|
112
|
+
// Add diagnostics feedback for TS files
|
|
113
|
+
if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
|
|
114
|
+
const diagnostics = await getPathDiagnostics(filePath, security);
|
|
115
|
+
if (diagnostics) {
|
|
116
|
+
response += `\n\nWarning: TypeScript diagnostics found after writing:\n${diagnostics}`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
content: [{ type: "text", text: response }],
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
return {
|
|
125
|
+
content: [{ type: "text", text: `Error writing file: ${error.message}` }],
|
|
126
|
+
isError: true,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
// delete_file
|
|
131
|
+
server.registerTool("delete_file", {
|
|
132
|
+
description: "Delete a file from the allowed workspace.",
|
|
133
|
+
inputSchema: z.object({
|
|
134
|
+
path: z.string().describe("Path to the file to delete."),
|
|
135
|
+
}).strict(),
|
|
136
|
+
}, async ({ path: filePath }) => {
|
|
137
|
+
try {
|
|
138
|
+
const validatedPath = security.resolveAndValidatePath(filePath);
|
|
139
|
+
await fs.unlink(validatedPath);
|
|
140
|
+
return {
|
|
141
|
+
content: [{ type: "text", text: `Successfully deleted file: ${filePath}` }],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
return {
|
|
146
|
+
content: [{ type: "text", text: `Error deleting file: ${error.message}` }],
|
|
147
|
+
isError: true,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// list_dir
|
|
152
|
+
server.registerTool("list_dir", {
|
|
153
|
+
description: "List files and directories within a specific path.",
|
|
154
|
+
inputSchema: z.object({
|
|
155
|
+
path: z.string().default(".").describe("Path to list (defaults to workspace root)."),
|
|
156
|
+
}).strict(),
|
|
157
|
+
}, async ({ path: dirPath }) => {
|
|
158
|
+
try {
|
|
159
|
+
const validatedPath = security.resolveAndValidatePath(dirPath);
|
|
160
|
+
const entries = await fs.readdir(validatedPath, { withFileTypes: true });
|
|
161
|
+
const result = entries.map(entry => {
|
|
162
|
+
return `${entry.isDirectory() ? "[DIR]" : "[FILE]"} ${entry.name}`;
|
|
163
|
+
}).join("\n");
|
|
164
|
+
return {
|
|
165
|
+
content: [{ type: "text", text: result || "(Directory is empty)" }],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
return {
|
|
170
|
+
content: [{ type: "text", text: `Error listing directory: ${error.message}` }],
|
|
171
|
+
isError: true,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
// search_file_content
|
|
176
|
+
server.registerTool("search_file_content", {
|
|
177
|
+
description: "Perform a global regex search for a specific string across all files in the project.",
|
|
178
|
+
inputSchema: z.object({
|
|
179
|
+
regex: z.string().describe("The regular expression pattern to search for."),
|
|
180
|
+
includeGlob: z.string().optional().describe("Glob pattern to limit the search (e.g. src/**/*.ts)."),
|
|
181
|
+
}).strict(),
|
|
182
|
+
}, async ({ regex, includeGlob }) => {
|
|
183
|
+
try {
|
|
184
|
+
const searchRegex = new RegExp(regex, "g");
|
|
185
|
+
const results = [];
|
|
186
|
+
const baseDir = security.resolveAndValidatePath(".");
|
|
187
|
+
async function searchRecursively(currentDir) {
|
|
188
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
189
|
+
for (const entry of entries) {
|
|
190
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
191
|
+
// Simple check to skip node_modules and .git
|
|
192
|
+
if (entry.name === "node_modules" || entry.name === ".git")
|
|
193
|
+
continue;
|
|
194
|
+
if (entry.isDirectory()) {
|
|
195
|
+
await searchRecursively(fullPath);
|
|
196
|
+
}
|
|
197
|
+
else if (entry.isFile()) {
|
|
198
|
+
const relPath = path.relative(baseDir, fullPath);
|
|
199
|
+
// Basic glob matching (simple version)
|
|
200
|
+
if (includeGlob && !relPath.includes(includeGlob.replace(/\*/g, "")))
|
|
201
|
+
continue;
|
|
202
|
+
const content = await fs.readFile(fullPath, "utf-8");
|
|
203
|
+
let match;
|
|
204
|
+
while ((match = searchRegex.exec(content)) !== null) {
|
|
205
|
+
// Find line number using cross-platform line endings
|
|
206
|
+
const lineNum = content.substring(0, match.index).split(/\r?\n/).length;
|
|
207
|
+
const context = content.split(/\r?\n/)[lineNum - 1];
|
|
208
|
+
results.push(`${relPath}:${lineNum} - ${context.trim()}`);
|
|
209
|
+
if (results.length > 100) {
|
|
210
|
+
results.push("... [Search results truncated after 100 matches]");
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
await searchRecursively(baseDir);
|
|
218
|
+
return {
|
|
219
|
+
content: [{ type: "text", text: results.join("\n") || "No matches found." }],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
return {
|
|
224
|
+
content: [{ type: "text", text: `Error during search: ${error.message}` }],
|
|
225
|
+
isError: true,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=file-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-tools.js","sourceRoot":"","sources":["../../../src/tools/file-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { SecurityManager } from "../security.js";
|
|
3
|
+
/**
|
|
4
|
+
* Internal helper to get diagnostics for a specific path.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getPathDiagnostics(checkPath: string, security: SecurityManager): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Registers LSP-related tools using the latest registerTool API.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerLspTools(server: McpServer, security: SecurityManager): void;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Project } from "ts-morph";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* Internal helper to get diagnostics for a specific path.
|
|
5
|
+
*/
|
|
6
|
+
export async function getPathDiagnostics(checkPath, security) {
|
|
7
|
+
const validatedPath = security.resolveAndValidatePath(checkPath);
|
|
8
|
+
const project = new Project();
|
|
9
|
+
project.addSourceFilesAtPaths([
|
|
10
|
+
validatedPath.endsWith(".ts") || validatedPath.endsWith(".js")
|
|
11
|
+
? validatedPath
|
|
12
|
+
: `${validatedPath}/**/*.{ts,js,tsx,jsx}`
|
|
13
|
+
]);
|
|
14
|
+
const diagnostics = project.getPreEmitDiagnostics();
|
|
15
|
+
return diagnostics.map(diag => {
|
|
16
|
+
const messageText = diag.getMessageText();
|
|
17
|
+
const line = diag.getLineNumber();
|
|
18
|
+
const file = diag.getSourceFile()?.getFilePath() || "Unknown file";
|
|
19
|
+
const formattedMessage = typeof messageText === "string" ? messageText : messageText.getMessageText();
|
|
20
|
+
return `[${file}:${line}] ${formattedMessage}`;
|
|
21
|
+
}).join("\n");
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Registers LSP-related tools using the latest registerTool API.
|
|
25
|
+
*/
|
|
26
|
+
export function registerLspTools(server, security) {
|
|
27
|
+
// get_document_symbols
|
|
28
|
+
server.registerTool("get_document_symbols", {
|
|
29
|
+
description: "Extract high-level symbols (classes, functions, interfaces) from a TypeScript file.",
|
|
30
|
+
inputSchema: z.object({
|
|
31
|
+
path: z.string().describe("TypeScript/JavaScript file path to analyze."),
|
|
32
|
+
}).strict(),
|
|
33
|
+
}, async ({ path: filePath }) => {
|
|
34
|
+
try {
|
|
35
|
+
const validatedPath = security.resolveAndValidatePath(filePath);
|
|
36
|
+
const project = new Project();
|
|
37
|
+
const sourceFile = project.addSourceFileAtPath(validatedPath);
|
|
38
|
+
const symbols = [];
|
|
39
|
+
sourceFile.getClasses().forEach(c => symbols.push(`[Class] ${c.getName()} (Line ${c.getStartLineNumber()})`));
|
|
40
|
+
sourceFile.getInterfaces().forEach(i => symbols.push(`[Interface] ${i.getName()} (Line ${i.getStartLineNumber()})`));
|
|
41
|
+
sourceFile.getFunctions().forEach(f => symbols.push(`[Function] ${f.getName()} (Line ${f.getStartLineNumber()})`));
|
|
42
|
+
sourceFile.getEnums().forEach(e => symbols.push(`[Enum] ${e.getName()} (Line ${e.getStartLineNumber()})`));
|
|
43
|
+
sourceFile.getTypeAliases().forEach(t => symbols.push(`[TypeAlias] ${t.getName()} (Line ${t.getStartLineNumber()})`));
|
|
44
|
+
return {
|
|
45
|
+
content: [{ type: "text", text: symbols.join("\n") || "(No significant symbols found)" }],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
content: [{ type: "text", text: `LSP Error: ${error.message}` }],
|
|
51
|
+
isError: true,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// get_diagnostics
|
|
56
|
+
server.registerTool("get_diagnostics", {
|
|
57
|
+
description: "Get TypeScript diagnostics/errors for a file or directory.",
|
|
58
|
+
inputSchema: z.object({
|
|
59
|
+
path: z.string().describe("File or directory path to check for TypeScript diagnostics."),
|
|
60
|
+
}).strict(),
|
|
61
|
+
}, async ({ path: checkPath }) => {
|
|
62
|
+
try {
|
|
63
|
+
const output = await getPathDiagnostics(checkPath, security);
|
|
64
|
+
return {
|
|
65
|
+
content: [{ type: "text", text: output || "No TypeScript diagnostics found." }],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return {
|
|
70
|
+
content: [{ type: "text", text: `LSP Error: ${error.message}` }],
|
|
71
|
+
isError: true,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
// find_references
|
|
76
|
+
server.registerTool("find_references", {
|
|
77
|
+
description: "Find all references to a symbol (function, class, variable) in the project.",
|
|
78
|
+
inputSchema: z.object({
|
|
79
|
+
path: z.string().describe("File path where the symbol is defined."),
|
|
80
|
+
symbolName: z.string().describe("The name of the symbol to find references for."),
|
|
81
|
+
}).strict(),
|
|
82
|
+
}, async ({ path: filePath, symbolName }) => {
|
|
83
|
+
try {
|
|
84
|
+
const validatedPath = security.resolveAndValidatePath(filePath);
|
|
85
|
+
const project = new Project();
|
|
86
|
+
project.addSourceFilesAtPaths("**/*.ts");
|
|
87
|
+
const sourceFile = project.getSourceFile(validatedPath);
|
|
88
|
+
if (!sourceFile) {
|
|
89
|
+
throw new Error(`File not found: ${filePath}`);
|
|
90
|
+
}
|
|
91
|
+
// Search for the symbol
|
|
92
|
+
let node;
|
|
93
|
+
// Simple search by name in classes, functions, etc.
|
|
94
|
+
const allNodes = sourceFile.getDescendantsOfKind(1 /* Identifier */);
|
|
95
|
+
node = allNodes.find(n => n.getText() === symbolName);
|
|
96
|
+
if (!node) {
|
|
97
|
+
return {
|
|
98
|
+
content: [{ type: "text", text: `Could not find symbol "${symbolName}" in ${filePath}` }],
|
|
99
|
+
isError: true,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const references = node.findReferences();
|
|
103
|
+
const results = [];
|
|
104
|
+
for (const reference of references) {
|
|
105
|
+
for (const ref of reference.getReferences()) {
|
|
106
|
+
const refSourceFile = ref.getSourceFile();
|
|
107
|
+
const line = refSourceFile.getLineAndColumnAtPos(ref.getTextSpan().getStart()).line;
|
|
108
|
+
const relPath = security.resolveAndValidatePath(refSourceFile.getFilePath()); // Re-validate or just use relative
|
|
109
|
+
results.push(`${refSourceFile.getFilePath()}:${line}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
content: [{ type: "text", text: results.join("\n") || "No references found." }],
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
content: [{ type: "text", text: `LSP Error: ${error.message}` }],
|
|
119
|
+
isError: true,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=lsp-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lsp-tools.js","sourceRoot":"","sources":["../../../src/tools/lsp-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { SecurityManager } from "../security.js";
|
|
3
|
+
/**
|
|
4
|
+
* Registers shell-related tools using the latest registerTool API.
|
|
5
|
+
*/
|
|
6
|
+
export declare function registerShellTools(server: McpServer, security: SecurityManager): void;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { exec, spawn } from "child_process";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { DEFAULT_TIMEOUT } from "../constants.js";
|
|
5
|
+
const execAsync = promisify(exec);
|
|
6
|
+
// Store for background tasks
|
|
7
|
+
const backgroundTasks = new Map();
|
|
8
|
+
/**
|
|
9
|
+
* Registers shell-related tools using the latest registerTool API.
|
|
10
|
+
*/
|
|
11
|
+
export function registerShellTools(server, security) {
|
|
12
|
+
server.registerTool("execute_command", {
|
|
13
|
+
description: "Execute a shell command in a specified directory (sandboxed).",
|
|
14
|
+
inputSchema: z.object({
|
|
15
|
+
command: z.string().describe("The shell command to execute."),
|
|
16
|
+
cwd: z.string().optional().describe("Directory to execute command from (must be allowed). Defaults to the workspace root."),
|
|
17
|
+
}).strict(),
|
|
18
|
+
}, async ({ command, cwd }) => {
|
|
19
|
+
try {
|
|
20
|
+
const validatedCwd = security.validateDirectory(cwd || ".");
|
|
21
|
+
const { stdout, stderr } = await execAsync(command, {
|
|
22
|
+
cwd: validatedCwd,
|
|
23
|
+
timeout: DEFAULT_TIMEOUT,
|
|
24
|
+
});
|
|
25
|
+
// Truncate output if too long
|
|
26
|
+
const formatOutput = (out) => {
|
|
27
|
+
const lines = out.split(/\r?\n/);
|
|
28
|
+
if (lines.length > 500) {
|
|
29
|
+
return lines.slice(0, 100).join("\n") +
|
|
30
|
+
`\n\n...[${lines.length - 200} lines truncated for brevity]...\n\n` +
|
|
31
|
+
lines.slice(-100).join("\n");
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
};
|
|
35
|
+
const output = [
|
|
36
|
+
stdout ? `STDOUT:\n${formatOutput(stdout)}` : "",
|
|
37
|
+
stderr ? `STDERR:\n${formatOutput(stderr)}` : "",
|
|
38
|
+
].filter(Boolean).join("\n\n");
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: "text", text: output || "(No output from command)" }],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
// If timed out or error occurred, still try to return what we have or a meaningful error
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: "text", text: `Command execution failed or timed out: ${error.message}` }],
|
|
47
|
+
isError: true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
// start_background_task
|
|
52
|
+
server.registerTool("start_background_task", {
|
|
53
|
+
description: "Start a background process (e.g. dev server) in the workspace.",
|
|
54
|
+
inputSchema: z.object({
|
|
55
|
+
command: z.string().describe("The shell command to start."),
|
|
56
|
+
cwd: z.string().optional().describe("Directory to start from (defaults to workspace root)."),
|
|
57
|
+
}).strict(),
|
|
58
|
+
}, async ({ command, cwd }) => {
|
|
59
|
+
try {
|
|
60
|
+
const validatedCwd = security.validateDirectory(cwd || ".");
|
|
61
|
+
// Use a single string for spawn when shell: true is enabled.
|
|
62
|
+
// This is more cross-platform and handles arguments/quotes better.
|
|
63
|
+
const child = spawn(command, {
|
|
64
|
+
cwd: validatedCwd,
|
|
65
|
+
shell: true,
|
|
66
|
+
// On Windows, shell: true uses cmd.exe /c.
|
|
67
|
+
// On Unix, shell: true uses /bin/sh -c.
|
|
68
|
+
});
|
|
69
|
+
const taskId = `task_${Math.random().toString(36).substring(2, 9)}`;
|
|
70
|
+
const logs = [];
|
|
71
|
+
child.stdout?.on("data", (data) => {
|
|
72
|
+
logs.push(data.toString());
|
|
73
|
+
if (logs.length > 1000)
|
|
74
|
+
logs.shift(); // Keep last 1000 lines
|
|
75
|
+
});
|
|
76
|
+
child.stderr?.on("data", (data) => {
|
|
77
|
+
logs.push(`ERR: ${data.toString()}`);
|
|
78
|
+
if (logs.length > 1000)
|
|
79
|
+
logs.shift();
|
|
80
|
+
});
|
|
81
|
+
backgroundTasks.set(taskId, { process: child, logs });
|
|
82
|
+
child.on("exit", (code) => {
|
|
83
|
+
logs.push(`[Process exited with code ${code}]`);
|
|
84
|
+
// Note: We don't remove from map yet so logs can be read
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
content: [{ type: "text", text: `Task started with ID: ${taskId}` }],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return {
|
|
92
|
+
content: [{ type: "text", text: `Error starting task: ${error.message}` }],
|
|
93
|
+
isError: true,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
// get_background_task_logs
|
|
98
|
+
server.registerTool("get_background_task_logs", {
|
|
99
|
+
description: "Read the latest logs from a running or recently exited background task.",
|
|
100
|
+
inputSchema: z.object({
|
|
101
|
+
taskId: z.string().describe("The ID of the task."),
|
|
102
|
+
tail: z.number().optional().default(100).describe("Number of lines to return from the end."),
|
|
103
|
+
}).strict(),
|
|
104
|
+
}, async ({ taskId, tail }) => {
|
|
105
|
+
const task = backgroundTasks.get(taskId);
|
|
106
|
+
if (!task) {
|
|
107
|
+
return {
|
|
108
|
+
content: [{ type: "text", text: `Task ${taskId} not found.` }],
|
|
109
|
+
isError: true,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const logs = task.logs.slice(-tail);
|
|
113
|
+
return {
|
|
114
|
+
content: [{ type: "text", text: logs.join("") || "(No logs yet)" }],
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
// kill_background_task
|
|
118
|
+
server.registerTool("kill_background_task", {
|
|
119
|
+
description: "Terminate a background task by its ID.",
|
|
120
|
+
inputSchema: z.object({
|
|
121
|
+
taskId: z.string().describe("The ID of the task to kill."),
|
|
122
|
+
}).strict(),
|
|
123
|
+
}, async ({ taskId }) => {
|
|
124
|
+
const task = backgroundTasks.get(taskId);
|
|
125
|
+
if (!task) {
|
|
126
|
+
return {
|
|
127
|
+
content: [{ type: "text", text: `Task ${taskId} not found.` }],
|
|
128
|
+
isError: true,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
task.process.kill();
|
|
132
|
+
backgroundTasks.delete(taskId);
|
|
133
|
+
return {
|
|
134
|
+
content: [{ type: "text", text: `Task ${taskId} killed.` }],
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=shell-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-tools.js","sourceRoot":"","sources":["../../../src/tools/shell-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,6BAA6B;AAC7B,MAAM,eAAe,GAAG,IAAI,GAAG,EAAqD,CAAC;AAErF;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,QAAyB;IAC7E,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;QACE,WAAW,EAAE,+DAA+D;QAC5E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAC7D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sFAAsF,CAAC;SAC5H,CAAC,CAAC,MAAM,EAAE;KACZ,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,QAAQ,CAAC,iBAAiB,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YAE5D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE;gBAClD,GAAG,EAAE,YAAY;gBACjB,OAAO,EAAE,eAAe;aACzB,CAAC,CAAC;YAEH,8BAA8B;YAC9B,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,EAAE;gBACnC,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACjC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;oBACvB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;wBAC9B,WAAW,KAAK,CAAC,MAAM,GAAG,GAAG,sCAAsC;wBACnE,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtC,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC;YAEF,MAAM,MAAM,GAAG;gBACb,MAAM,CAAC,CAAC,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;gBAChD,MAAM,CAAC,CAAC,CAAC,YAAY,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;aACjD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE/B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,0BAA0B,EAAE,CAAC;aACxE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,yFAAyF;YACzF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,0CAA0C,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC5F,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,wBAAwB;IACxB,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EAAE,gEAAgE;QAC7E,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YAC3D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;SAC7F,CAAC,CAAC,MAAM,EAAE;KACZ,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE;QACzB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,QAAQ,CAAC,iBAAiB,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YAE5D,6DAA6D;YAC7D,mEAAmE;YACnE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE;gBAC3B,GAAG,EAAE,YAAY;gBACjB,KAAK,EAAE,IAAI;gBACX,2CAA2C;gBAC3C,wCAAwC;aACzC,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,GAAa,EAAE,CAAC;YAE1B,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAChC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI;oBAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,uBAAuB;YAC/D,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACrC,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI;oBAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YACvC,CAAC,CAAC,CAAC;YAEH,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAEtD,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,IAAI,CAAC,IAAI,CAAC,6BAA6B,IAAI,GAAG,CAAC,CAAC;gBAChD,yDAAyD;YAC3D,CAAC,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,MAAM,EAAE,EAAE,CAAC;aACrE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,wBAAwB,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC1E,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,YAAY,CACjB,0BAA0B,EAC1B;QACE,WAAW,EAAE,yEAAyE;QACtF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YAClD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,yCAAyC,CAAC;SAC7F,CAAC,CAAC,MAAM,EAAE;KACZ,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;QACzB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,MAAM,aAAa,EAAE,CAAC;gBAC9D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,eAAe,EAAE,CAAC;SACpE,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EAAE,wCAAwC;QACrD,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;SAC3D,CAAC,CAAC,MAAM,EAAE;KACZ,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,MAAM,aAAa,EAAE,CAAC;gBAC9D,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACpB,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC/B,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,MAAM,UAAU,EAAE,CAAC;SAC5D,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SkillInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
location: string;
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class SkillManager {
|
|
8
|
+
private static readonly SEARCH_DIRS;
|
|
9
|
+
private static readonly SKILL_SUBDIRS;
|
|
10
|
+
static loadSkills(workingDir: string): Record<string, SkillInfo>;
|
|
11
|
+
private static scanDirSync;
|
|
12
|
+
private static addSkillSync;
|
|
13
|
+
private static parseMarkdown;
|
|
14
|
+
}
|