code-auditor-mcp 2.0.3 → 2.2.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.
- package/README.md +41 -3
- package/dist/applyDataDirEnv.d.ts +2 -0
- package/dist/applyDataDirEnv.d.ts.map +1 -0
- package/dist/applyDataDirEnv.js +21 -0
- package/dist/applyDataDirEnv.js.map +1 -0
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +48 -13
- package/dist/auditRunner.js.map +1 -1
- package/dist/codeIndexDB-enhanced.d.ts +2 -3
- package/dist/codeIndexDB-enhanced.d.ts.map +1 -1
- package/dist/codeIndexDB-enhanced.js +41 -15
- package/dist/codeIndexDB-enhanced.js.map +1 -1
- package/dist/codeIndexDb.d.ts +30 -1
- package/dist/codeIndexDb.d.ts.map +1 -1
- package/dist/codeIndexDb.js +114 -15
- package/dist/codeIndexDb.js.map +1 -1
- package/dist/codeIndexService.d.ts +7 -3
- package/dist/codeIndexService.d.ts.map +1 -1
- package/dist/codeIndexService.js +14 -22
- package/dist/codeIndexService.js.map +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -0
- package/dist/constants.js.map +1 -1
- package/dist/dataPaths.d.ts +10 -0
- package/dist/dataPaths.d.ts.map +1 -0
- package/dist/dataPaths.js +19 -0
- package/dist/dataPaths.js.map +1 -0
- package/dist/mcp-index.d.ts +3 -1
- package/dist/mcp-index.d.ts.map +1 -1
- package/dist/mcp-index.js +30 -8
- package/dist/mcp-index.js.map +1 -1
- package/dist/mcp-standalone.d.ts +1 -1
- package/dist/mcp-standalone.d.ts.map +1 -1
- package/dist/mcp-standalone.js +163 -59
- package/dist/mcp-standalone.js.map +1 -1
- package/dist/mcp-tools/projectTasks.d.ts +69 -0
- package/dist/mcp-tools/projectTasks.d.ts.map +1 -0
- package/dist/mcp-tools/projectTasks.js +129 -0
- package/dist/mcp-tools/projectTasks.js.map +1 -0
- package/dist/mcp-tools-shared.d.ts.map +1 -1
- package/dist/mcp-tools-shared.js +3 -3
- package/dist/mcp-tools-shared.js.map +1 -1
- package/dist/mcp-ui-simple.d.ts.map +1 -1
- package/dist/mcp-ui-simple.js +3 -2
- package/dist/mcp-ui-simple.js.map +1 -1
- package/dist/mcp.js +206 -65
- package/dist/mcp.js.map +1 -1
- package/dist/mcpAutoIndex.d.ts +2 -0
- package/dist/mcpAutoIndex.d.ts.map +1 -0
- package/dist/mcpAutoIndex.js +71 -0
- package/dist/mcpAutoIndex.js.map +1 -0
- package/dist/mcpDiagnostics.d.ts +11 -0
- package/dist/mcpDiagnostics.d.ts.map +1 -0
- package/dist/mcpDiagnostics.js +54 -0
- package/dist/mcpDiagnostics.js.map +1 -0
- package/dist/mcpToolErrors.d.ts +21 -0
- package/dist/mcpToolErrors.d.ts.map +1 -0
- package/dist/mcpToolErrors.js +81 -0
- package/dist/mcpToolErrors.js.map +1 -0
- package/dist/search/QueryParser.d.ts.map +1 -1
- package/dist/search/QueryParser.js +11 -12
- package/dist/search/QueryParser.js.map +1 -1
- package/dist/services/ProjectTaskRepository.d.ts +20 -0
- package/dist/services/ProjectTaskRepository.d.ts.map +1 -0
- package/dist/services/ProjectTaskRepository.js +96 -0
- package/dist/services/ProjectTaskRepository.js.map +1 -0
- package/dist/services/projectTaskHelpers.d.ts +23 -0
- package/dist/services/projectTaskHelpers.d.ts.map +1 -0
- package/dist/services/projectTaskHelpers.js +232 -0
- package/dist/services/projectTaskHelpers.js.map +1 -0
- package/dist/types/projectTask.d.ts +64 -0
- package/dist/types/projectTask.d.ts.map +1 -0
- package/dist/types/projectTask.js +6 -0
- package/dist/types/projectTask.js.map +1 -0
- package/package.json +34 -27
package/dist/mcp.js
CHANGED
|
@@ -2,24 +2,21 @@
|
|
|
2
2
|
// MCP servers use stdio: stdout for protocol messages, stderr for logging
|
|
3
3
|
// All log messages must go to stderr to avoid interfering with MCP protocol
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
-
console.error(chalk.blue('[INFO]'), 'Loading modules...');
|
|
6
5
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
6
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
7
|
import { CallToolRequestSchema, ListToolsRequestSchema, InitializeRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
-
console.error(chalk.blue('[INFO]'), 'MCP SDK loaded');
|
|
10
8
|
import { createAuditRunner } from './auditRunner.js';
|
|
11
|
-
console.error(chalk.blue('[INFO]'), 'Audit runner loaded');
|
|
12
9
|
import { searchFunctions, findDefinition, syncFileIndex, getDatabase } from './codeIndexService.js';
|
|
13
10
|
import { CodeMapGenerator } from './services/CodeMapGenerator.js';
|
|
14
11
|
import { analyzeDocumentation } from './analyzers/documentationAnalyzer.js';
|
|
15
12
|
import { ConfigGeneratorFactory } from './generators/ConfigGeneratorFactory.js';
|
|
16
|
-
import { DEFAULT_SERVER_URL, IS_DEV_MODE } from './constants.js';
|
|
17
|
-
console.error(chalk.blue('[INFO]'), 'Code index service loaded');
|
|
13
|
+
import { DEFAULT_SERVER_URL, IS_DEV_MODE, PACKAGE_VERSION } from './constants.js';
|
|
18
14
|
import path from 'node:path';
|
|
19
15
|
import fs from 'node:fs/promises';
|
|
20
16
|
import { createWriteStream } from 'node:fs';
|
|
21
17
|
import { CodeIndexDB } from './codeIndexDB.js';
|
|
22
|
-
|
|
18
|
+
import { logMcpDebug, logMcpInfo, mcpDebugStderr } from './mcpDiagnostics.js';
|
|
19
|
+
import { assertAuditPathExists, formatMcpToolErrorPayload } from './mcpToolErrors.js';
|
|
23
20
|
// Set up file logging (only in development mode)
|
|
24
21
|
let logStream = null;
|
|
25
22
|
if (IS_DEV_MODE) {
|
|
@@ -27,17 +24,16 @@ if (IS_DEV_MODE) {
|
|
|
27
24
|
logStream = createWriteStream(logFilePath, { flags: 'a' });
|
|
28
25
|
console.error(chalk.blue('[INFO]'), `Development mode: Logging to file: ${logFilePath}`);
|
|
29
26
|
}
|
|
30
|
-
// Save original console
|
|
31
|
-
const originalConsoleLog = console.log;
|
|
27
|
+
// Save original console.error (log is redirected to stderr; see below)
|
|
32
28
|
const originalConsoleError = console.error;
|
|
33
|
-
// Override console.log (
|
|
29
|
+
// Override console.log — MCP uses stdout only for JSON-RPC; log() must never touch stdout.
|
|
34
30
|
console.log = (...args) => {
|
|
35
31
|
if (logStream) {
|
|
36
32
|
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
37
33
|
const timestamp = new Date().toISOString();
|
|
38
34
|
logStream.write(`[${timestamp}] [LOG] ${message}\n`);
|
|
39
35
|
}
|
|
40
|
-
|
|
36
|
+
originalConsoleError.apply(console, args);
|
|
41
37
|
};
|
|
42
38
|
// Override console.error (with conditional file logging)
|
|
43
39
|
console.error = (...args) => {
|
|
@@ -191,13 +187,13 @@ const tools = [
|
|
|
191
187
|
},
|
|
192
188
|
{
|
|
193
189
|
name: 'sync_index',
|
|
194
|
-
description: 'Synchronize, cleanup, or reset
|
|
190
|
+
description: 'Synchronize, cleanup, or reset analysis-derived data (indexed functions, FlexSearch, cached audits, code maps, schema overlays). Project tasks, analyzer configs, and whitelist entries are preserved on reset.',
|
|
195
191
|
parameters: [
|
|
196
192
|
{
|
|
197
193
|
name: 'mode',
|
|
198
194
|
type: 'string',
|
|
199
195
|
required: false,
|
|
200
|
-
description: '
|
|
196
|
+
description: 'sync: update index from files; cleanup: remove index rows for deleted files; reset: clear all analysis-derived data (not tasks/config/whitelist)',
|
|
201
197
|
default: 'sync',
|
|
202
198
|
enum: ['sync', 'cleanup', 'reset'],
|
|
203
199
|
},
|
|
@@ -333,32 +329,149 @@ const tools = [
|
|
|
333
329
|
},
|
|
334
330
|
],
|
|
335
331
|
},
|
|
332
|
+
{
|
|
333
|
+
name: 'project_tasks',
|
|
334
|
+
description: 'Manage a persistent per-project task queue. Tasks and analyzer configs survive sync_index reset; reset clears function index, cached audits, code maps, and schema overlays (no ghost code references). Use delete to remove a task.',
|
|
335
|
+
parameters: [
|
|
336
|
+
{
|
|
337
|
+
name: 'action',
|
|
338
|
+
type: 'string',
|
|
339
|
+
required: true,
|
|
340
|
+
description: 'list | create | get | update | delete. list/create use projectPath or default to process.cwd(); create also needs title; get/update/delete need taskId; update needs patch object.',
|
|
341
|
+
enum: ['list', 'create', 'get', 'update', 'delete'],
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
name: 'projectPath',
|
|
345
|
+
type: 'string',
|
|
346
|
+
required: false,
|
|
347
|
+
description: 'Project root (resolved). Omit to use the MCP server working directory (same default idea as audit path); response includes projectPathDefaulted when omitted.',
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
name: 'taskId',
|
|
351
|
+
type: 'string',
|
|
352
|
+
required: false,
|
|
353
|
+
description: 'Stable task id (UUID). Required for get, update, delete.',
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: 'title',
|
|
357
|
+
type: 'string',
|
|
358
|
+
required: false,
|
|
359
|
+
description: 'Task title. Required for create.',
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
name: 'description',
|
|
363
|
+
type: 'string',
|
|
364
|
+
required: false,
|
|
365
|
+
description: 'Longer description / notes.',
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
name: 'status',
|
|
369
|
+
type: 'string',
|
|
370
|
+
required: false,
|
|
371
|
+
description: 'pending | in_progress | blocked | done | cancelled. Filter for list; initial status for create; can be set via update patch.',
|
|
372
|
+
enum: ['pending', 'in_progress', 'blocked', 'done', 'cancelled'],
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
name: 'priority',
|
|
376
|
+
type: 'string',
|
|
377
|
+
required: false,
|
|
378
|
+
description: 'Optional priority for create/update patch.',
|
|
379
|
+
enum: ['low', 'medium', 'high'],
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: 'labels',
|
|
383
|
+
type: 'array',
|
|
384
|
+
required: false,
|
|
385
|
+
description: 'String tags (e.g. ["audit","refactor"]).',
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
name: 'metadata',
|
|
389
|
+
type: 'object',
|
|
390
|
+
required: false,
|
|
391
|
+
description: 'Arbitrary JSON object: related file paths, links, audit IDs, etc.',
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
name: 'parentTaskId',
|
|
395
|
+
type: 'string',
|
|
396
|
+
required: false,
|
|
397
|
+
description: 'Optional parent task for subtasks.',
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: 'source',
|
|
401
|
+
type: 'string',
|
|
402
|
+
required: false,
|
|
403
|
+
description: 'manual | audit | mcp. Filter for list; provenance for create; can be set via update patch.',
|
|
404
|
+
enum: ['manual', 'audit', 'mcp'],
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: 'blockedBy',
|
|
408
|
+
type: 'array',
|
|
409
|
+
required: false,
|
|
410
|
+
description: 'Task IDs this item is blocked by (waiting-on).',
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
name: 'dueAt',
|
|
414
|
+
type: 'string',
|
|
415
|
+
required: false,
|
|
416
|
+
description: 'ISO 8601 due datetime for create; omit or null in patch to clear.',
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
name: 'sortOrder',
|
|
420
|
+
type: 'number',
|
|
421
|
+
required: false,
|
|
422
|
+
description: 'Lower numbers sort first within a project (default 0).',
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
name: 'relatedFiles',
|
|
426
|
+
type: 'array',
|
|
427
|
+
required: false,
|
|
428
|
+
description: 'Repo-relative or absolute file paths tied to the task.',
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
name: 'relatedSymbols',
|
|
432
|
+
type: 'array',
|
|
433
|
+
required: false,
|
|
434
|
+
description: 'Function, class, or component names for cross-linking.',
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
name: 'patch',
|
|
438
|
+
type: 'object',
|
|
439
|
+
required: false,
|
|
440
|
+
description: 'For update: partial fields (title, description, status, priority, labels, metadata, parentTaskId, source, blockedBy, dueAt, sortOrder, relatedFiles, relatedSymbols).',
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
name: 'limit',
|
|
444
|
+
type: 'number',
|
|
445
|
+
required: false,
|
|
446
|
+
description: 'Max tasks to return for list (default 500, max 1000).',
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
},
|
|
336
450
|
];
|
|
337
451
|
async function startMcpServer() {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
452
|
+
logMcpInfo('startup', `code-auditor-mcp ${PACKAGE_VERSION} (stdio)`, {
|
|
453
|
+
pid: process.pid,
|
|
454
|
+
cwd: process.cwd(),
|
|
455
|
+
dataDir: process.env.CODE_AUDITOR_DATA_DIR ?? '(default)',
|
|
456
|
+
debug: process.env.CODE_AUDITOR_DEBUG ?? '0',
|
|
457
|
+
logFile: process.env.CODE_AUDITOR_LOG_FILE ?? '(none)'
|
|
458
|
+
});
|
|
459
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), `Node ${process.version} · cwd ${process.cwd()}`);
|
|
342
460
|
const server = new Server({
|
|
343
461
|
name: 'code-auditor',
|
|
462
|
+
version: PACKAGE_VERSION,
|
|
344
463
|
}, {
|
|
345
464
|
capabilities: {
|
|
346
465
|
tools: {},
|
|
347
466
|
},
|
|
348
467
|
});
|
|
349
|
-
console.error(chalk.blue('[INFO]'), 'Server instance created');
|
|
350
|
-
console.error(chalk.blue('[DEBUG]'), 'Server capabilities:', JSON.stringify({ tools: {} }));
|
|
351
468
|
// Add error handler
|
|
352
469
|
server.onerror = (error) => {
|
|
353
470
|
console.error(chalk.red('[ERROR]'), 'Server error occurred:', error);
|
|
354
471
|
console.error(chalk.red('[ERROR]'), 'Error stack:', error.stack);
|
|
355
472
|
};
|
|
356
|
-
// Handle tool listing
|
|
357
|
-
console.error(chalk.blue('[INFO]'), 'Setting up request handlers...');
|
|
358
473
|
server.setRequestHandler(ListToolsRequestSchema, async (request) => {
|
|
359
|
-
|
|
360
|
-
console.error(chalk.blue('[DEBUG]'), 'Request:', JSON.stringify(request, null, 2));
|
|
361
|
-
console.error(chalk.blue('[DEBUG]'), 'Handling ListTools request');
|
|
474
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'ListTools', JSON.stringify(request, null, 2));
|
|
362
475
|
const response = {
|
|
363
476
|
tools: tools.map(tool => ({
|
|
364
477
|
name: tool.name,
|
|
@@ -378,15 +491,11 @@ async function startMcpServer() {
|
|
|
378
491
|
},
|
|
379
492
|
})),
|
|
380
493
|
};
|
|
381
|
-
|
|
382
|
-
console.error(chalk.blue('[DEBUG]'), 'ListTools response:', JSON.stringify(response, null, 2));
|
|
494
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), `ListTools → ${response.tools.length} tools`);
|
|
383
495
|
return response;
|
|
384
496
|
});
|
|
385
|
-
console.error(chalk.blue('[INFO]'), `Registered ${tools.length} tools`);
|
|
386
|
-
// Add handler for initialize request
|
|
387
497
|
server.setRequestHandler(InitializeRequestSchema, async (request) => {
|
|
388
|
-
|
|
389
|
-
console.error(chalk.blue('[DEBUG]'), 'Request:', JSON.stringify(request, null, 2));
|
|
498
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'initialize', JSON.stringify(request, null, 2));
|
|
390
499
|
const response = {
|
|
391
500
|
protocolVersion: '2024-11-05',
|
|
392
501
|
capabilities: {
|
|
@@ -394,31 +503,30 @@ async function startMcpServer() {
|
|
|
394
503
|
},
|
|
395
504
|
serverInfo: {
|
|
396
505
|
name: 'code-auditor',
|
|
397
|
-
version:
|
|
506
|
+
version: PACKAGE_VERSION,
|
|
398
507
|
},
|
|
399
508
|
};
|
|
400
|
-
|
|
509
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'initialize response', JSON.stringify(response, null, 2));
|
|
401
510
|
return response;
|
|
402
511
|
});
|
|
403
|
-
// Handle tool execution
|
|
404
512
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
405
|
-
|
|
406
|
-
console.error(chalk.blue('[DEBUG]'), 'Request:', JSON.stringify(request, null, 2));
|
|
513
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'CallTool raw', JSON.stringify(request, null, 2));
|
|
407
514
|
const { name, arguments: args } = request.params;
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
console.error(chalk.blue('[DEBUG]'), `Handling CallTool request for: ${name}`);
|
|
515
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), `CallTool ${name}`, JSON.stringify(args, null, 2));
|
|
516
|
+
const toolStartedAt = Date.now();
|
|
411
517
|
try {
|
|
412
|
-
|
|
518
|
+
logMcpDebug('tool', `call ${name}`, {
|
|
519
|
+
argKeys: args && typeof args === 'object' ? Object.keys(args) : [],
|
|
520
|
+
pathArg: args?.path,
|
|
521
|
+
cwd: process.cwd()
|
|
522
|
+
});
|
|
413
523
|
let result;
|
|
414
524
|
switch (name) {
|
|
415
525
|
case 'audit': {
|
|
416
526
|
const auditPath = path.resolve(args.path || process.cwd());
|
|
417
527
|
const indexFunctions = args.indexFunctions !== false; // Default true
|
|
418
528
|
const generateCodeMap = args.generateCodeMap || false;
|
|
419
|
-
|
|
420
|
-
const stats = await fs.stat(auditPath).catch(() => null);
|
|
421
|
-
const isFile = stats?.isFile() || false;
|
|
529
|
+
const { isFile } = await assertAuditPathExists(auditPath);
|
|
422
530
|
// Get stored analyzer configs from database
|
|
423
531
|
const db = CodeIndexDB.getInstance();
|
|
424
532
|
await db.initialize();
|
|
@@ -436,12 +544,27 @@ async function startMcpServer() {
|
|
|
436
544
|
indexFunctions,
|
|
437
545
|
...(isFile && { includePaths: [auditPath] }),
|
|
438
546
|
...(Object.keys(analyzerConfigs).length > 0 && { analyzerConfigs }),
|
|
547
|
+
progressCallback: (p) => {
|
|
548
|
+
if (p.phase === 'function-indexing' &&
|
|
549
|
+
typeof p.current === 'number' &&
|
|
550
|
+
typeof p.total === 'number' &&
|
|
551
|
+
p.total > 0 &&
|
|
552
|
+
p.current % 50 !== 0 &&
|
|
553
|
+
p.current !== p.total) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
logMcpDebug('audit', p.message ?? p.phase ?? 'progress', {
|
|
557
|
+
phase: p.phase,
|
|
558
|
+
analyzer: p.analyzer,
|
|
559
|
+
current: p.current,
|
|
560
|
+
total: p.total
|
|
561
|
+
});
|
|
562
|
+
}
|
|
439
563
|
};
|
|
440
|
-
|
|
564
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'audit runner options', JSON.stringify(options, null, 2));
|
|
441
565
|
const runner = createAuditRunner(options);
|
|
442
|
-
console.error(chalk.blue('[DEBUG]'), 'About to run audit...');
|
|
443
566
|
const auditResult = await runner.run();
|
|
444
|
-
|
|
567
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'audit summary', auditResult.summary);
|
|
445
568
|
// Handle function indexing if enabled and functions were collected
|
|
446
569
|
let indexingResult = null;
|
|
447
570
|
if (indexFunctions && auditResult.metadata.fileToFunctionsMap) {
|
|
@@ -460,7 +583,7 @@ async function startMcpServer() {
|
|
|
460
583
|
failed: 0,
|
|
461
584
|
syncStats
|
|
462
585
|
};
|
|
463
|
-
|
|
586
|
+
mcpDebugStderr(chalk.blue('[INFO]'), `Synced functions: ${syncStats.added} added, ${syncStats.updated} updated, ${syncStats.removed} removed`);
|
|
464
587
|
}
|
|
465
588
|
catch (error) {
|
|
466
589
|
console.error(chalk.yellow('[WARN]'), 'Failed to sync functions:', error);
|
|
@@ -507,7 +630,7 @@ async function startMcpServer() {
|
|
|
507
630
|
sections: paginatedResult.summary.sectionsAvailable,
|
|
508
631
|
documentationCoverage: documentation?.coverageScore
|
|
509
632
|
};
|
|
510
|
-
|
|
633
|
+
mcpDebugStderr(chalk.blue('[INFO]'), `Generated paginated code map: ${paginatedResult.summary.stats.totalFiles} files, ${paginatedResult.summary.totalSections} sections`);
|
|
511
634
|
}
|
|
512
635
|
catch (error) {
|
|
513
636
|
console.error(chalk.yellow('[WARN]'), 'Failed to generate code map:', error);
|
|
@@ -537,6 +660,7 @@ async function startMcpServer() {
|
|
|
537
660
|
}
|
|
538
661
|
case 'audit_health': {
|
|
539
662
|
const auditPath = path.resolve(args.path || process.cwd());
|
|
663
|
+
await assertAuditPathExists(auditPath);
|
|
540
664
|
const threshold = args.threshold || 70;
|
|
541
665
|
const indexFunctions = args.indexFunctions !== false; // Default true
|
|
542
666
|
const generateCodeMap = args.generateCodeMap !== false; // Default true
|
|
@@ -556,6 +680,22 @@ async function startMcpServer() {
|
|
|
556
680
|
verbose: false,
|
|
557
681
|
indexFunctions, // Pass the flag to the runner
|
|
558
682
|
...(Object.keys(analyzerConfigs).length > 0 && { analyzerConfigs }),
|
|
683
|
+
progressCallback: (p) => {
|
|
684
|
+
if (p.phase === 'function-indexing' &&
|
|
685
|
+
typeof p.current === 'number' &&
|
|
686
|
+
typeof p.total === 'number' &&
|
|
687
|
+
p.total > 0 &&
|
|
688
|
+
p.current % 50 !== 0 &&
|
|
689
|
+
p.current !== p.total) {
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
logMcpDebug('audit_health', p.message ?? p.phase ?? 'progress', {
|
|
693
|
+
phase: p.phase,
|
|
694
|
+
analyzer: p.analyzer,
|
|
695
|
+
current: p.current,
|
|
696
|
+
total: p.total
|
|
697
|
+
});
|
|
698
|
+
}
|
|
559
699
|
});
|
|
560
700
|
const auditResult = await runner.run();
|
|
561
701
|
const healthScore = calculateHealthScore(auditResult);
|
|
@@ -577,7 +717,7 @@ async function startMcpServer() {
|
|
|
577
717
|
failed: 0,
|
|
578
718
|
syncStats
|
|
579
719
|
};
|
|
580
|
-
|
|
720
|
+
mcpDebugStderr(chalk.blue('[INFO]'), `Synced functions: ${syncStats.added} added, ${syncStats.updated} updated, ${syncStats.removed} removed`);
|
|
581
721
|
}
|
|
582
722
|
catch (error) {
|
|
583
723
|
console.error(chalk.yellow('[WARN]'), 'Failed to sync functions:', error);
|
|
@@ -624,7 +764,7 @@ async function startMcpServer() {
|
|
|
624
764
|
sections: paginatedResult.summary.sectionsAvailable,
|
|
625
765
|
documentationCoverage: documentation?.coverageScore
|
|
626
766
|
};
|
|
627
|
-
|
|
767
|
+
mcpDebugStderr(chalk.blue('[INFO]'), `Generated paginated code map: ${paginatedResult.summary.stats.totalFiles} files, ${paginatedResult.summary.totalSections} sections`);
|
|
628
768
|
}
|
|
629
769
|
catch (error) {
|
|
630
770
|
console.error(chalk.yellow('[WARN]'), 'Failed to generate code map:', error);
|
|
@@ -784,7 +924,7 @@ async function startMcpServer() {
|
|
|
784
924
|
result = {
|
|
785
925
|
mode: 'reset',
|
|
786
926
|
success: true,
|
|
787
|
-
message: '
|
|
927
|
+
message: 'Analysis-derived data cleared (functions, search index, cached audits, code maps, schemas). Project tasks, whitelist, and analyzer configs were preserved.'
|
|
788
928
|
};
|
|
789
929
|
break;
|
|
790
930
|
}
|
|
@@ -983,6 +1123,11 @@ async function startMcpServer() {
|
|
|
983
1123
|
}
|
|
984
1124
|
break;
|
|
985
1125
|
}
|
|
1126
|
+
case 'project_tasks': {
|
|
1127
|
+
const { handleProjectTasks } = await import('./mcp-tools/projectTasks.js');
|
|
1128
|
+
result = await handleProjectTasks((args || {}));
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
986
1131
|
default:
|
|
987
1132
|
throw new Error(`Unknown tool: ${name}`);
|
|
988
1133
|
}
|
|
@@ -994,30 +1139,31 @@ async function startMcpServer() {
|
|
|
994
1139
|
},
|
|
995
1140
|
],
|
|
996
1141
|
};
|
|
997
|
-
|
|
998
|
-
console.error(chalk.blue('[DEBUG]'), 'CallTool response:', JSON.stringify(response, null, 2).substring(0, 500) + '...');
|
|
1142
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), `Tool ${name} ok`, JSON.stringify(response, null, 2).substring(0, 500) + '...');
|
|
999
1143
|
return response;
|
|
1000
1144
|
}
|
|
1001
1145
|
catch (error) {
|
|
1002
1146
|
console.error(chalk.red('[ERROR]'), `Tool ${name} execution failed:`, error);
|
|
1003
1147
|
console.error(chalk.red('[ERROR]'), 'Error stack:', error instanceof Error ? error.stack : 'No stack trace');
|
|
1148
|
+
logMcpDebug('tool', `call ${name} failed`, {
|
|
1149
|
+
ms: Date.now() - toolStartedAt,
|
|
1150
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1151
|
+
});
|
|
1004
1152
|
return {
|
|
1005
1153
|
content: [
|
|
1006
1154
|
{
|
|
1007
1155
|
type: 'text',
|
|
1008
|
-
text: JSON.stringify(
|
|
1009
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
1010
|
-
tool: name,
|
|
1011
|
-
}),
|
|
1156
|
+
text: JSON.stringify(formatMcpToolErrorPayload(name, error), null, 2),
|
|
1012
1157
|
},
|
|
1013
1158
|
],
|
|
1014
1159
|
isError: true,
|
|
1015
1160
|
};
|
|
1016
1161
|
}
|
|
1162
|
+
finally {
|
|
1163
|
+
logMcpDebug('tool', `call ${name} finished`, { ms: Date.now() - toolStartedAt });
|
|
1164
|
+
}
|
|
1017
1165
|
});
|
|
1018
|
-
console.error(chalk.blue('[INFO]'), 'Request handlers configured');
|
|
1019
1166
|
const transport = new StdioServerTransport();
|
|
1020
|
-
console.error(chalk.blue('[INFO]'), 'Creating stdio transport...');
|
|
1021
1167
|
// Add transport event handlers if available
|
|
1022
1168
|
if (transport.onclose) {
|
|
1023
1169
|
transport.onclose = () => {
|
|
@@ -1029,16 +1175,13 @@ async function startMcpServer() {
|
|
|
1029
1175
|
console.error(chalk.red('[ERROR]'), 'Transport error:', error);
|
|
1030
1176
|
};
|
|
1031
1177
|
}
|
|
1032
|
-
console.error(chalk.blue('[DEBUG]'), 'Connecting server to transport...');
|
|
1033
1178
|
await server.connect(transport);
|
|
1034
|
-
console.error(chalk.blue('[DEBUG]'), 'Server connected to transport');
|
|
1035
1179
|
console.error(chalk.green('✓ Code Auditor MCP Server started'));
|
|
1036
|
-
console.error(chalk.gray(
|
|
1037
|
-
|
|
1180
|
+
console.error(chalk.gray(`Listening on stdio · ${tools.length} tools · ${PACKAGE_VERSION}`));
|
|
1181
|
+
mcpDebugStderr(chalk.blue('[DEBUG]'), 'Server ready', {
|
|
1038
1182
|
name: 'code-auditor',
|
|
1039
1183
|
transport: 'stdio',
|
|
1040
|
-
|
|
1041
|
-
toolCount: tools.length,
|
|
1184
|
+
toolCount: tools.length
|
|
1042
1185
|
});
|
|
1043
1186
|
}
|
|
1044
1187
|
function getAllViolations(result) {
|
|
@@ -1126,8 +1269,6 @@ process.stdin.on('error', (error) => {
|
|
|
1126
1269
|
process.stdout.on('error', (error) => {
|
|
1127
1270
|
console.error(chalk.red('[ERROR]'), 'stdout error:', error);
|
|
1128
1271
|
});
|
|
1129
|
-
// Start server
|
|
1130
|
-
console.error(chalk.blue('[INFO]'), 'Initializing server...');
|
|
1131
1272
|
startMcpServer().catch(error => {
|
|
1132
1273
|
console.error(chalk.red('[ERROR]'), 'Failed to start MCP server:', error);
|
|
1133
1274
|
console.error(chalk.red('[ERROR]'), 'Stack:', error.stack);
|