mcp-test-generator 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.
Files changed (53) hide show
  1. package/README.md +123 -0
  2. package/dist/analyzers/function-extractor.d.ts +3 -0
  3. package/dist/analyzers/function-extractor.js +18 -0
  4. package/dist/analyzers/function-extractor.js.map +1 -0
  5. package/dist/analyzers/project-analyzer.d.ts +2 -0
  6. package/dist/analyzers/project-analyzer.js +70 -0
  7. package/dist/analyzers/project-analyzer.js.map +1 -0
  8. package/dist/analyzers/python-analyzer.d.ts +2 -0
  9. package/dist/analyzers/python-analyzer.js +259 -0
  10. package/dist/analyzers/python-analyzer.js.map +1 -0
  11. package/dist/analyzers/typescript-analyzer.d.ts +2 -0
  12. package/dist/analyzers/typescript-analyzer.js +386 -0
  13. package/dist/analyzers/typescript-analyzer.js.map +1 -0
  14. package/dist/generators/test-generator.d.ts +4 -0
  15. package/dist/generators/test-generator.js +223 -0
  16. package/dist/generators/test-generator.js.map +1 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +14 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/models/function-info.d.ts +66 -0
  21. package/dist/models/function-info.js +2 -0
  22. package/dist/models/function-info.js.map +1 -0
  23. package/dist/models/project-info.d.ts +53 -0
  24. package/dist/models/project-info.js +2 -0
  25. package/dist/models/project-info.js.map +1 -0
  26. package/dist/models/test-case.d.ts +32 -0
  27. package/dist/models/test-case.js +2 -0
  28. package/dist/models/test-case.js.map +1 -0
  29. package/dist/server.d.ts +2 -0
  30. package/dist/server.js +159 -0
  31. package/dist/server.js.map +1 -0
  32. package/dist/tools/analyze-project.d.ts +9 -0
  33. package/dist/tools/analyze-project.js +24 -0
  34. package/dist/tools/analyze-project.js.map +1 -0
  35. package/dist/tools/generate-single-test.d.ts +12 -0
  36. package/dist/tools/generate-single-test.js +58 -0
  37. package/dist/tools/generate-single-test.js.map +1 -0
  38. package/dist/tools/generate-tests.d.ts +17 -0
  39. package/dist/tools/generate-tests.js +82 -0
  40. package/dist/tools/generate-tests.js.map +1 -0
  41. package/dist/utils/config-parser.d.ts +8 -0
  42. package/dist/utils/config-parser.js +27 -0
  43. package/dist/utils/config-parser.js.map +1 -0
  44. package/dist/utils/file-utils.d.ts +7 -0
  45. package/dist/utils/file-utils.js +157 -0
  46. package/dist/utils/file-utils.js.map +1 -0
  47. package/dist/utils/language-detector.d.ts +6 -0
  48. package/dist/utils/language-detector.js +148 -0
  49. package/dist/utils/language-detector.js.map +1 -0
  50. package/dist/utils/test-suite-renderer.d.ts +3 -0
  51. package/dist/utils/test-suite-renderer.js +62 -0
  52. package/dist/utils/test-suite-renderer.js.map +1 -0
  53. package/package.json +49 -0
package/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # MCP Test Generator
2
+
3
+ An [MCP](https://modelcontextprotocol.io/) (Model Context Protocol) server that **generates test cases** for your project. Supports TypeScript, JavaScript, Python, and Java. Works with Cursor, Claude Desktop, Google Antigravity Studio, and any MCP client.
4
+
5
+ **Note:** This tool only **generates** test files; it does not run them. Use your usual test runner (Jest, Vitest, pytest, etc.) to execute tests.
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install -g mcp-test-generator
13
+ ```
14
+
15
+ Or use without global install:
16
+
17
+ ```bash
18
+ npx mcp-test-generator
19
+ ```
20
+
21
+ ---
22
+
23
+ ## Configure your MCP client
24
+
25
+ Add the server to your client’s MCP config. Use **one** of the following.
26
+
27
+ ### If installed globally
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "mcp-test-generator": {
33
+ "command": "mcp-test-generator"
34
+ }
35
+ }
36
+ }
37
+ ```
38
+
39
+ ### Using npx (no global install)
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "mcp-test-generator": {
45
+ "command": "npx",
46
+ "args": ["-y", "mcp-test-generator"]
47
+ }
48
+ }
49
+ }
50
+ ```
51
+
52
+ ### Config file locations
53
+
54
+ - **Cursor:** `~/.cursor/mcp.json` (macOS/Linux) or `%USERPROFILE%\.cursor\mcp.json` (Windows)
55
+ - **Claude Desktop:** See [Claude MCP docs](https://docs.anthropic.com/en/docs/build-with-claude/mcp)
56
+ - **Other clients:** Check your client’s docs for “MCP” or “Model Context Protocol” configuration.
57
+
58
+ Restart (or reload) your client after changing the config.
59
+
60
+ ---
61
+
62
+ ## Tools
63
+
64
+ | Tool | Description |
65
+ |------|-------------|
66
+ | **`analyze_project`** | Analyzes a project and returns structure, language, framework, and testable files. Does not generate tests. |
67
+ | **`generate_single_test`** | Generates a test file for one source file. |
68
+ | **`generate_all_tests`** | Analyzes the project and generates test files for all testable source files. |
69
+
70
+ All paths must be **absolute** (e.g. `/Users/me/my-project` or `C:\Users\me\my-project`).
71
+
72
+ ### Example usage (in chat)
73
+
74
+ - “Analyze the project at `/path/to/my-app`”
75
+ - “Generate a test for `/path/to/my-app/src/utils.ts`”
76
+ - “Generate tests for the whole project at `/path/to/my-app`”
77
+
78
+ ---
79
+
80
+ ## Build from source
81
+
82
+ If you prefer to run from the repo instead of npm:
83
+
84
+ ```bash
85
+ git clone https://github.com/your-username/mcp-test-generator.git
86
+ cd mcp-test-generator
87
+ npm install
88
+ npm run build
89
+ ```
90
+
91
+ Then point your MCP config at the built entrypoint:
92
+
93
+ ```json
94
+ {
95
+ "mcpServers": {
96
+ "mcp-test-generator": {
97
+ "command": "node",
98
+ "args": ["/absolute/path/to/mcp-test-generator/dist/index.js"]
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ See [TESTING.md](./TESTING.md) for more detailed testing steps.
105
+
106
+ ---
107
+
108
+ ## Publish to npm (for maintainers)
109
+
110
+ 1. Create an [npm account](https://www.npmjs.com/signup) if needed.
111
+ 2. Log in: `npm login`
112
+ 3. Update `repository.url` in `package.json` to your GitHub repo (e.g. `https://github.com/your-username/mcp-test-generator.git`).
113
+ 4. Publish: `npm publish`
114
+
115
+ The `prepublishOnly` script runs `npm run build` automatically, so the published package includes the built `dist/` folder.
116
+
117
+ If the name `mcp-test-generator` is taken, use a scoped package: set `"name": "@your-username/mcp-test-generator"` and publish with `npm publish --access public`.
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ MIT
@@ -0,0 +1,3 @@
1
+ import { FileAnalysis } from "../models/function-info.js";
2
+ import { ProgrammingLanguage } from "../models/project-info.js";
3
+ export declare function analyzeFile(filePath: string, language: ProgrammingLanguage): FileAnalysis;
@@ -0,0 +1,18 @@
1
+ import { analyzeTypeScriptFile } from "./typescript-analyzer.js";
2
+ import { analyzePythonFile } from "./python-analyzer.js";
3
+ export function analyzeFile(filePath, language) {
4
+ switch (language) {
5
+ case "typescript":
6
+ case "javascript":
7
+ return analyzeTypeScriptFile(filePath);
8
+ case "python":
9
+ return analyzePythonFile(filePath);
10
+ case "java":
11
+ // For Java, we'd use java-analyzer.ts
12
+ // Simplified for now - returning basic structure
13
+ return analyzeTypeScriptFile(filePath); // Simplified fallback
14
+ default:
15
+ throw new Error(`Unsupported language: ${language}`);
16
+ }
17
+ }
18
+ //# sourceMappingURL=function-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function-extractor.js","sourceRoot":"","sources":["../../src/analyzers/function-extractor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,UAAU,WAAW,CACzB,QAAgB,EAChB,QAA6B;IAE7B,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,YAAY,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QACzC,KAAK,QAAQ;YACX,OAAO,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACrC,KAAK,MAAM;YACT,sCAAsC;YACtC,iDAAiD;YACjD,OAAO,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,sBAAsB;QAChE;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { ProjectInfo } from "../models/project-info.js";
2
+ export declare function analyzeProject(projectPath: string, includePatterns?: string[], excludePatterns?: string[]): Promise<ProjectInfo>;
@@ -0,0 +1,70 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { detectLanguage, detectFramework, detectTestFramework, } from "../utils/language-detector.js";
4
+ import { findSourceFiles } from "../utils/file-utils.js";
5
+ export async function analyzeProject(projectPath, includePatterns, excludePatterns) {
6
+ // Validate project path
7
+ if (!fs.existsSync(projectPath)) {
8
+ throw new Error(`Project path does not exist: ${projectPath}`);
9
+ }
10
+ if (!fs.statSync(projectPath).isDirectory()) {
11
+ throw new Error(`Project path is not a directory: ${projectPath}`);
12
+ }
13
+ const language = detectLanguage(projectPath);
14
+ const framework = detectFramework(projectPath);
15
+ const testFramework = detectTestFramework(projectPath, language);
16
+ const sourceFiles = await findSourceFiles(projectPath, language, includePatterns, excludePatterns);
17
+ // Find config files
18
+ const configFiles = findConfigFiles(projectPath);
19
+ // Detect package manager
20
+ const packageManager = detectPackageManager(projectPath);
21
+ return {
22
+ rootPath: projectPath,
23
+ language,
24
+ framework,
25
+ testFramework,
26
+ sourceFiles,
27
+ packageManager,
28
+ configFiles,
29
+ };
30
+ }
31
+ function findConfigFiles(projectPath) {
32
+ const configFileNames = [
33
+ "package.json",
34
+ "tsconfig.json",
35
+ "jest.config.js",
36
+ "jest.config.ts",
37
+ "vitest.config.ts",
38
+ ".babelrc",
39
+ "babel.config.js",
40
+ "pyproject.toml",
41
+ "setup.py",
42
+ "setup.cfg",
43
+ "pytest.ini",
44
+ "pom.xml",
45
+ "build.gradle",
46
+ ];
47
+ return configFileNames.filter((f) => fs.existsSync(path.join(projectPath, f)));
48
+ }
49
+ function detectPackageManager(projectPath) {
50
+ if (fs.existsSync(path.join(projectPath, "pnpm-lock.yaml")))
51
+ return "pnpm";
52
+ if (fs.existsSync(path.join(projectPath, "yarn.lock")))
53
+ return "yarn";
54
+ if (fs.existsSync(path.join(projectPath, "package-lock.json")))
55
+ return "npm";
56
+ if (fs.existsSync(path.join(projectPath, "bun.lockb")))
57
+ return "bun";
58
+ if (fs.existsSync(path.join(projectPath, "requirements.txt")))
59
+ return "pip";
60
+ if (fs.existsSync(path.join(projectPath, "Pipfile")))
61
+ return "pipenv";
62
+ if (fs.existsSync(path.join(projectPath, "poetry.lock")))
63
+ return "poetry";
64
+ if (fs.existsSync(path.join(projectPath, "pom.xml")))
65
+ return "maven";
66
+ if (fs.existsSync(path.join(projectPath, "build.gradle")))
67
+ return "gradle";
68
+ return null;
69
+ }
70
+ //# sourceMappingURL=project-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/project-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { FileAnalysis } from "../models/function-info.js";
2
+ export declare function analyzePythonFile(filePath: string): FileAnalysis;
@@ -0,0 +1,259 @@
1
+ import * as fs from "fs";
2
+ export function analyzePythonFile(filePath) {
3
+ const content = fs.readFileSync(filePath, "utf-8");
4
+ return {
5
+ filePath,
6
+ imports: extractPythonImports(content),
7
+ exports: extractPythonExports(content),
8
+ functions: extractPythonFunctions(content),
9
+ classes: extractPythonClasses(content),
10
+ constants: [],
11
+ interfaces: [],
12
+ };
13
+ }
14
+ function extractPythonImports(content) {
15
+ const imports = [];
16
+ // from x import y
17
+ const fromImportRegex = /from\s+([\w.]+)\s+import\s+(.+)/g;
18
+ let match;
19
+ while ((match = fromImportRegex.exec(content)) !== null) {
20
+ const namedImports = match[2]
21
+ .split(",")
22
+ .map((s) => s.trim().split(/\s+as\s+/)[0].trim())
23
+ .filter((s) => s.length > 0);
24
+ imports.push({
25
+ module: match[1],
26
+ namedImports,
27
+ defaultImport: null,
28
+ isTypeOnly: false,
29
+ });
30
+ }
31
+ // import x
32
+ const importRegex = /^import\s+([\w.]+)(?:\s+as\s+(\w+))?/gm;
33
+ while ((match = importRegex.exec(content)) !== null) {
34
+ imports.push({
35
+ module: match[1],
36
+ namedImports: [],
37
+ defaultImport: match[2] || match[1],
38
+ isTypeOnly: false,
39
+ });
40
+ }
41
+ return imports;
42
+ }
43
+ function extractPythonExports(content) {
44
+ // Python doesn't have explicit exports, but we look for __all__
45
+ const allMatch = content.match(/__all__\s*=\s*\[([^\]]+)\]/);
46
+ if (allMatch) {
47
+ return allMatch[1]
48
+ .split(",")
49
+ .map((s) => s.trim().replace(/['"]/g, ""))
50
+ .filter((s) => s.length > 0);
51
+ }
52
+ // Return all top-level functions and classes (non-private)
53
+ const exports = [];
54
+ const funcRegex = /^(?:async\s+)?def\s+(\w+)/gm;
55
+ const classRegex = /^class\s+(\w+)/gm;
56
+ let match;
57
+ while ((match = funcRegex.exec(content)) !== null) {
58
+ if (!match[1].startsWith("_"))
59
+ exports.push(match[1]);
60
+ }
61
+ while ((match = classRegex.exec(content)) !== null) {
62
+ if (!match[1].startsWith("_"))
63
+ exports.push(match[1]);
64
+ }
65
+ return exports;
66
+ }
67
+ function extractPythonFunctions(content) {
68
+ const functions = [];
69
+ const funcRegex = /^(async\s+)?def\s+(\w+)\s*\(([^)]*)\)(?:\s*->\s*([^\n:]+))?\s*:/gm;
70
+ let match;
71
+ while ((match = funcRegex.exec(content)) !== null) {
72
+ const isAsync = !!match[1];
73
+ const name = match[2];
74
+ const paramsStr = match[3];
75
+ const returnType = match[4]?.trim() || null;
76
+ // Extract docstring
77
+ const afterDef = content.substring(match.index + match[0].length);
78
+ const docstringMatch = afterDef.match(/^\s*(?:"""([\s\S]*?)"""|'''([\s\S]*?)''')/);
79
+ const jsDoc = docstringMatch
80
+ ? docstringMatch[1] || docstringMatch[2]
81
+ : null;
82
+ // Extract body by indentation
83
+ const body = extractPythonBody(content, match.index + match[0].length);
84
+ // Extract decorators
85
+ const decorators = extractPythonDecorators(content, match.index);
86
+ functions.push({
87
+ name,
88
+ type: "function",
89
+ isAsync,
90
+ isExported: !name.startsWith("_"),
91
+ isStatic: false,
92
+ parameters: parsePythonParameters(paramsStr),
93
+ returnType,
94
+ className: null,
95
+ decorators,
96
+ jsDoc,
97
+ complexity: calculatePythonComplexity(body),
98
+ startLine: getLineNumber(content, match.index),
99
+ endLine: getLineNumber(content, match.index + match[0].length + body.length),
100
+ body,
101
+ });
102
+ }
103
+ return functions;
104
+ }
105
+ function extractPythonClasses(content) {
106
+ const classes = [];
107
+ const classRegex = /^class\s+(\w+)(?:\(([^)]*)\))?\s*:/gm;
108
+ let match;
109
+ while ((match = classRegex.exec(content)) !== null) {
110
+ const name = match[1];
111
+ const parentStr = match[2] || "";
112
+ const parents = parentStr
113
+ .split(",")
114
+ .map((s) => s.trim())
115
+ .filter((s) => s.length > 0);
116
+ const classBody = extractPythonBody(content, match.index + match[0].length);
117
+ // Extract methods from class body
118
+ const methods = extractMethodsFromPythonClass(classBody, name);
119
+ const constructorInfo = methods.find((m) => m.name === "__init__") || null;
120
+ classes.push({
121
+ name,
122
+ isExported: !name.startsWith("_"),
123
+ constructorInfo,
124
+ methods: methods.filter((m) => m.name !== "__init__"),
125
+ properties: [],
126
+ decorators: extractPythonDecorators(content, match.index),
127
+ extendsClass: parents.length > 0 ? parents[0] : null,
128
+ implementsInterfaces: [],
129
+ });
130
+ }
131
+ return classes;
132
+ }
133
+ function extractMethodsFromPythonClass(classBody, className) {
134
+ const methods = [];
135
+ const methodRegex = /(?:^|\n)\s+(async\s+)?def\s+(\w+)\s*\(([^)]*)\)(?:\s*->\s*([^\n:]+))?\s*:/g;
136
+ let match;
137
+ while ((match = methodRegex.exec(classBody)) !== null) {
138
+ const isAsync = !!match[1];
139
+ const name = match[2];
140
+ const paramsStr = match[3];
141
+ const returnType = match[4]?.trim() || null;
142
+ const decorators = extractPythonDecorators(classBody, match.index);
143
+ const isStatic = decorators.includes("staticmethod");
144
+ methods.push({
145
+ name,
146
+ type: name === "__init__" ? "constructor" : "method",
147
+ isAsync,
148
+ isExported: !name.startsWith("_") || name === "__init__",
149
+ isStatic,
150
+ parameters: parsePythonParameters(paramsStr).filter((p) => p.name !== "self" && p.name !== "cls"),
151
+ returnType,
152
+ className,
153
+ decorators,
154
+ jsDoc: null,
155
+ complexity: 1,
156
+ startLine: 0,
157
+ endLine: 0,
158
+ body: "",
159
+ });
160
+ }
161
+ return methods;
162
+ }
163
+ function parsePythonParameters(paramsStr) {
164
+ if (!paramsStr.trim())
165
+ return [];
166
+ return paramsStr
167
+ .split(",")
168
+ .map((p) => p.trim())
169
+ .filter((p) => p.length > 0 && p !== "self" && p !== "cls")
170
+ .map((p) => {
171
+ let defaultValue = null;
172
+ const defaultMatch = p.match(/\s*=\s*(.+)$/);
173
+ if (defaultMatch) {
174
+ defaultValue = defaultMatch[1].trim();
175
+ p = p.substring(0, p.indexOf("=")).trim();
176
+ }
177
+ let type = null;
178
+ const typeMatch = p.match(/:\s*(.+)$/);
179
+ if (typeMatch) {
180
+ type = typeMatch[1].trim();
181
+ p = p.substring(0, p.indexOf(":")).trim();
182
+ }
183
+ const isRest = p.startsWith("*") || p.startsWith("**");
184
+ if (isRest)
185
+ p = p.replace(/^\*+/, "");
186
+ return {
187
+ name: p,
188
+ type,
189
+ isOptional: defaultValue !== null,
190
+ defaultValue,
191
+ isRest,
192
+ };
193
+ });
194
+ }
195
+ function extractPythonBody(content, startIndex) {
196
+ const lines = content.substring(startIndex).split("\n");
197
+ if (lines.length === 0)
198
+ return "";
199
+ // Find the indentation level of the first non-empty line
200
+ let baseIndent = -1;
201
+ const bodyLines = [];
202
+ for (let i = 1; i < lines.length; i++) {
203
+ const line = lines[i];
204
+ if (line.trim().length === 0) {
205
+ bodyLines.push("");
206
+ continue;
207
+ }
208
+ const indent = line.match(/^(\s*)/)?.[1].length || 0;
209
+ if (baseIndent === -1) {
210
+ baseIndent = indent;
211
+ }
212
+ if (indent >= baseIndent) {
213
+ bodyLines.push(line);
214
+ }
215
+ else {
216
+ break;
217
+ }
218
+ }
219
+ return bodyLines.join("\n");
220
+ }
221
+ function extractPythonDecorators(content, defIndex) {
222
+ const before = content.substring(0, defIndex).trimEnd();
223
+ const lines = before.split("\n").reverse();
224
+ const decorators = [];
225
+ for (const line of lines) {
226
+ const trimmed = line.trim();
227
+ if (trimmed.startsWith("@")) {
228
+ const decoratorName = trimmed.match(/@(\w+)/)?.[1];
229
+ if (decoratorName)
230
+ decorators.push(decoratorName);
231
+ }
232
+ else if (trimmed.length > 0) {
233
+ break;
234
+ }
235
+ }
236
+ return decorators.reverse();
237
+ }
238
+ function calculatePythonComplexity(body) {
239
+ let complexity = 1;
240
+ const keywords = [
241
+ /\bif\b/g,
242
+ /\belif\b/g,
243
+ /\bfor\b/g,
244
+ /\bwhile\b/g,
245
+ /\bexcept\b/g,
246
+ /\band\b/g,
247
+ /\bor\b/g,
248
+ ];
249
+ for (const regex of keywords) {
250
+ const matches = body.match(regex);
251
+ if (matches)
252
+ complexity += matches.length;
253
+ }
254
+ return complexity;
255
+ }
256
+ function getLineNumber(content, index) {
257
+ return content.substring(0, index).split("\n").length;
258
+ }
259
+ //# sourceMappingURL=python-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"python-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/python-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { FileAnalysis } from "../models/function-info.js";
2
+ export declare function analyzeTypeScriptFile(filePath: string): FileAnalysis;