vibecheck-mcp-server 2.0.1

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.
@@ -0,0 +1,298 @@
1
+ /**
2
+ * MCP Server Tool: MDC Generator
3
+ *
4
+ * Provides Model Context Protocol (MCP) tool for generating
5
+ * Markdown Context (MDC) files from codebase analysis.
6
+ */
7
+
8
+ import { spawn } from 'child_process';
9
+ import { existsSync } from 'fs';
10
+ import fs from 'fs/promises';
11
+ import path from 'path';
12
+ import { fileURLToPath } from 'url';
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = path.dirname(__filename);
16
+
17
+ /**
18
+ * Generate MDC documentation for a codebase
19
+ */
20
+ async function generateMDC(projectPath, options = {}) {
21
+ const scriptPath = path.join(__dirname, '../scripts/generate-mdc.ts');
22
+
23
+ if (!existsSync(scriptPath)) {
24
+ throw new Error('MDC generator script not found');
25
+ }
26
+
27
+ // Build arguments for the npm script (will be passed after '--')
28
+ const scriptArgs = [];
29
+
30
+ // Add project path if different from cwd
31
+ if (projectPath !== process.cwd()) {
32
+ scriptArgs.push('--project', projectPath);
33
+ }
34
+
35
+ if (options.output) {
36
+ scriptArgs.push('--output', options.output);
37
+ }
38
+
39
+ if (options.categories) {
40
+ // Handle comma-separated categories by splitting and adding multiple --category flags
41
+ const categoryList = typeof options.categories === 'string'
42
+ ? options.categories.split(',').map(c => c.trim())
43
+ : Array.isArray(options.categories)
44
+ ? options.categories
45
+ : [options.categories];
46
+ categoryList.forEach(cat => {
47
+ scriptArgs.push('--category', cat);
48
+ });
49
+ }
50
+
51
+ if (options.minImportance) {
52
+ scriptArgs.push('--min-score', options.minImportance.toString());
53
+ }
54
+
55
+ if (options.depth) {
56
+ scriptArgs.push('--depth', options.depth);
57
+ }
58
+
59
+ if (options.includeExamples === false) {
60
+ scriptArgs.push('--no-examples');
61
+ }
62
+
63
+ if (options.useASTParsing === false) {
64
+ scriptArgs.push('--no-ast');
65
+ }
66
+
67
+ if (options.semanticAnalysis === false) {
68
+ scriptArgs.push('--no-semantic');
69
+ }
70
+
71
+ return new Promise((resolve, reject) => {
72
+ // Use npm script which has fallback chain for better compatibility
73
+ const npmArgs = ['run', 'generate-mdc', '--', ...scriptArgs];
74
+ const child = spawn('npm', npmArgs, {
75
+ stdio: ['pipe', 'pipe', 'pipe'],
76
+ cwd: process.cwd(),
77
+ env: { ...process.env },
78
+ shell: true // Use shell on Windows for better compatibility
79
+ });
80
+
81
+ let stdout = '';
82
+ let stderr = '';
83
+
84
+ child.stdout.on('data', (data) => {
85
+ stdout += data.toString();
86
+ });
87
+
88
+ child.stderr.on('data', (data) => {
89
+ stderr += data.toString();
90
+ });
91
+
92
+ child.on('close', (code) => {
93
+ if (code === 0) {
94
+ resolve({
95
+ success: true,
96
+ stdout: stdout,
97
+ stderr: stderr,
98
+ exitCode: code
99
+ });
100
+ } else {
101
+ reject(new Error(`MDC generation failed with exit code ${code}: ${stderr}`));
102
+ }
103
+ });
104
+
105
+ child.on('error', (error) => {
106
+ reject(new Error(`Failed to run MDC generator: ${error.message}`));
107
+ });
108
+ });
109
+ }
110
+
111
+ /**
112
+ * Read generated MDC specifications
113
+ */
114
+ async function readMDCSpecifications(outputDir) {
115
+ const indexPath = path.join(outputDir, 'specifications.json');
116
+
117
+ if (!existsSync(indexPath)) {
118
+ throw new Error('Specifications index not found');
119
+ }
120
+
121
+ try {
122
+ const indexContent = await fs.readFile(indexPath, 'utf8');
123
+ const specifications = JSON.parse(indexContent);
124
+
125
+ // Read individual MDC files
126
+ const mdcFiles = {};
127
+ for (const spec of specifications) {
128
+ const filePath = path.join(outputDir, spec.fileName);
129
+ if (existsSync(filePath)) {
130
+ const content = await fs.readFile(filePath, 'utf8');
131
+ mdcFiles[spec.fileName] = {
132
+ ...spec,
133
+ content: content
134
+ };
135
+ }
136
+ }
137
+
138
+ return {
139
+ specifications,
140
+ mdcFiles,
141
+ totalCount: specifications.length
142
+ };
143
+ } catch (error) {
144
+ throw new Error(`Failed to read MDC specifications: ${error.message}`);
145
+ }
146
+ }
147
+
148
+ /**
149
+ * MCP Tool Definition
150
+ */
151
+ const mdcGeneratorTool = {
152
+ name: 'generate_mdc',
153
+ description: 'Generate comprehensive Markdown Context (MDC) documentation for a codebase',
154
+ inputSchema: {
155
+ type: 'object',
156
+ properties: {
157
+ projectPath: {
158
+ type: 'string',
159
+ description: 'Path to the project directory to analyze (default: current directory)'
160
+ },
161
+ outputDir: {
162
+ type: 'string',
163
+ description: 'Output directory for MDC files (default: .specs)',
164
+ default: '.specs'
165
+ },
166
+ categories: {
167
+ type: 'string',
168
+ description: 'Comma-separated categories to generate (architecture,security,data-flow,design-system,integration,algorithm,utility)'
169
+ },
170
+ minImportance: {
171
+ type: 'number',
172
+ description: 'Minimum importance score threshold (0-100)',
173
+ default: 70,
174
+ minimum: 0,
175
+ maximum: 100
176
+ },
177
+ depth: {
178
+ type: 'string',
179
+ enum: ['shallow', 'medium', 'deep'],
180
+ description: 'Analysis depth level',
181
+ default: 'medium'
182
+ },
183
+ includeExamples: {
184
+ type: 'boolean',
185
+ description: 'Include code examples in documentation',
186
+ default: true
187
+ },
188
+ useASTParsing: {
189
+ type: 'boolean',
190
+ description: 'Use TypeScript AST parsing for analysis',
191
+ default: true
192
+ },
193
+ semanticAnalysis: {
194
+ type: 'boolean',
195
+ description: 'Enable semantic analysis',
196
+ default: true
197
+ },
198
+ readResults: {
199
+ type: 'boolean',
200
+ description: 'Read and return generated MDC files',
201
+ default: false
202
+ }
203
+ },
204
+ required: []
205
+ }
206
+ };
207
+
208
+ /**
209
+ * MCP Tool Handler
210
+ */
211
+ async function handleMDCGeneration(args) {
212
+ const {
213
+ projectPath = process.cwd(),
214
+ outputDir = '.specs',
215
+ categories,
216
+ minImportance = 70,
217
+ depth = 'medium',
218
+ includeExamples = true,
219
+ useASTParsing = true,
220
+ semanticAnalysis = true,
221
+ readResults = false
222
+ } = args;
223
+
224
+ try {
225
+ // Validate project path
226
+ if (!existsSync(projectPath)) {
227
+ throw new Error(`Project path does not exist: ${projectPath}`);
228
+ }
229
+
230
+ // Generate MDC files
231
+ const result = await generateMDC(projectPath, {
232
+ output: outputDir,
233
+ categories,
234
+ minImportance,
235
+ depth,
236
+ includeExamples,
237
+ useASTParsing,
238
+ semanticAnalysis
239
+ });
240
+
241
+ let response = {
242
+ success: true,
243
+ message: 'MDC generation completed successfully',
244
+ projectPath,
245
+ outputDir,
246
+ stdout: result.stdout,
247
+ stderr: result.stderr
248
+ };
249
+
250
+ // Read generated files if requested
251
+ if (readResults) {
252
+ try {
253
+ const specifications = await readMDCSpecifications(outputDir);
254
+ response.specifications = specifications;
255
+ } catch (error) {
256
+ response.readError = error.message;
257
+ }
258
+ }
259
+
260
+ return response;
261
+ } catch (error) {
262
+ return {
263
+ success: false,
264
+ error: error.message,
265
+ projectPath,
266
+ outputDir
267
+ };
268
+ }
269
+ }
270
+
271
+ /**
272
+ * Register MCP tool
273
+ */
274
+ function registerMDCGeneratorTool(server) {
275
+ server.setRequestHandler('tools/list', async () => {
276
+ return {
277
+ tools: [mdcGeneratorTool]
278
+ };
279
+ });
280
+
281
+ server.setRequestHandler('tools/call', async (request) => {
282
+ const { name, arguments: args } = request.params;
283
+
284
+ if (name === 'generate_mdc') {
285
+ return await handleMDCGeneration(args);
286
+ }
287
+
288
+ throw new Error(`Unknown tool: ${name}`);
289
+ });
290
+ }
291
+
292
+ export {
293
+ mdcGeneratorTool,
294
+ handleMDCGeneration,
295
+ registerMDCGeneratorTool,
296
+ generateMDC,
297
+ readMDCSpecifications
298
+ };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "vibecheck-mcp-server",
3
+ "version": "2.0.1",
4
+ "description": "Professional MCP server for Guardrail - Intelligent development environment guardrails",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "bin": {
8
+ "guardrail-mcp": "./index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node index.js",
12
+ "dev": "GUARDRAIL_DEBUG=true node index.js"
13
+ },
14
+ "keywords": [
15
+ "mcp",
16
+ "ai",
17
+ "guardrails",
18
+ "guardrail",
19
+ "development",
20
+ "validation",
21
+ "architecture"
22
+ ],
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^0.5.0"
25
+ },
26
+ "engines": {
27
+ "node": ">=18.0.0"
28
+ },
29
+ "author": "Guardrail",
30
+ "license": "MIT",
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "files": [
35
+ "*.js",
36
+ "README.md"
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://github.com/guardiavault-oss/guardrail"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/guardiavault-oss/guardrail/issues"
44
+ },
45
+ "homepage": "https://github.com/guardiavault-oss/guardrail#readme"
46
+ }
47
+