Skip to main content
Glama

CTS MCP Server

by EricA1019
index.ts7.16 kB
/** * CTS Bughunter Tool - MCP Integration * * Heuristic-based bug detection for Godot projects with pattern matching. * Identifies common coding errors and GDScript-specific antipatterns. */ import { z } from 'zod'; import { ToolDefinition, ToolHandler } from '../../types.js'; import { scanForBugs, filterBySeverity } from './scanner.js'; import { formatReport } from './reporter.js'; import { validateToolResponse, BughunterResponseSchema } from '../../schemas.js'; import { Errors } from '../../errors.js'; /** * Zod schema for bughunter parameters */ const BughunterParamsSchema = z.object({ projectPath: z.string().describe('Path to Godot project directory'), excludePatterns: z.array(z.string()).default(['**/addons/**', '**/.godot/**']).describe('File patterns to exclude from scan'), minSeverity: z.enum(['low', 'medium', 'high', 'critical']).default('medium').describe('Minimum severity level to report'), exportFormat: z.enum(['json', 'markdown', 'cts_plan']).default('json').describe('Output format for bug report'), maxFiles: z.number().min(1).max(10000).optional().describe('Maximum files to scan (for large projects)'), }); /** * Tool definition for MCP protocol */ export const bughunterTool: ToolDefinition = { name: 'CTS_Bughunter', description: 'Scan Godot project for potential bugs using heuristic pattern detection. Identifies common errors (null checks, error handling, type mismatches) and GDScript-specific issues (signal leaks, unfreed nodes, ready checks). Returns severity-scored bug report with line numbers and fix suggestions.', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to Godot project directory', }, excludePatterns: { type: 'array', description: 'File patterns to exclude from scan (e.g., **/addons/**, **/.godot/**)', items: { type: 'string' }, default: ['**/addons/**', '**/.godot/**'], }, minSeverity: { type: 'string', description: 'Minimum severity level to include in report', enum: ['low', 'medium', 'high', 'critical'], default: 'medium', }, exportFormat: { type: 'string', description: 'Output format for bug report', enum: ['json', 'markdown', 'cts_plan'], default: 'json', }, maxFiles: { type: 'number', description: 'Maximum files to scan (useful for large projects)', minimum: 1, maximum: 10000, }, }, required: ['projectPath'], }, }; /** * Create tool handler for bughunter */ export function createBughunterHandler(): ToolHandler { return async (args: Record<string, unknown>) => { try { // Validate input parameters const params = BughunterParamsSchema.parse(args); console.error(`[CTS Bughunter] Starting scan of ${params.projectPath}`); console.error(`[CTS Bughunter] Min severity: ${params.minSeverity}, Format: ${params.exportFormat}`); const startTime = Date.now(); // Scan project for bugs const report = await scanForBugs(params.projectPath, { maxFiles: params.maxFiles, }); const scanDuration = Date.now() - startTime; console.error(`[CTS Bughunter] Scan complete: ${report.totalBugs} bugs found in ${report.totalFiles} files`); console.error(`[CTS Bughunter] Severity breakdown: ${report.severityBreakdown.critical} critical, ${report.severityBreakdown.high} high, ${report.severityBreakdown.medium} medium, ${report.severityBreakdown.low} low`); console.error(`[CTS Bughunter] Quality score: ${report.overallScore}/100`); console.error(`[CTS Bughunter] Scan took ${scanDuration}ms`); // Filter by minimum severity const filteredBugs = filterBySeverity(report, params.minSeverity); // Create filtered report const filteredReport = { ...report, totalBugs: filteredBugs.length, severityBreakdown: { critical: filteredBugs.filter(b => b.severity === 'critical').length, high: filteredBugs.filter(b => b.severity === 'high').length, medium: filteredBugs.filter(b => b.severity === 'medium').length, low: filteredBugs.filter(b => b.severity === 'low').length, }, byFile: report.byFile.map(fileReport => ({ ...fileReport, bugs: fileReport.bugs.filter(bug => { const severityLevels = ['low', 'medium', 'high', 'critical']; const minLevel = severityLevels.indexOf(params.minSeverity); const bugLevel = severityLevels.indexOf(bug.severity); return bugLevel >= minLevel; }), })).filter(fileReport => fileReport.bugs.length > 0), }; // Format report const formattedReport = formatReport(filteredReport, params.exportFormat); // Check performance target (<3s for reasonable project size) if (scanDuration > 3000 && report.totalFiles < 1000) { console.error(`[CTS Bughunter] WARNING: Scan exceeded 3s target (${scanDuration}ms for ${report.totalFiles} files)`); } // Build response in BaseToolResponse format const response = { success: true as const, timestamp: new Date().toISOString(), toolName: 'CTS_Bughunter', duration_ms: scanDuration, result: { bugs: filteredBugs.map(bug => ({ file: bug.file || '', line: bug.line, severity: bug.severity, category: bug.pattern, message: bug.message, suggestion: bug.suggestion, })), stats: { totalBugs: filteredBugs.length, bySeverity: filteredReport.severityBreakdown, byCategory: {}, // TODO: Add category breakdown from scanner filesScanned: report.totalFiles, duration_ms: scanDuration, }, }, }; // Validate response schema before returning const { valid, errors } = validateToolResponse('CTS_Bughunter', response); if (!valid) { throw Errors.validationError( 'response', 'BughunterResponse', errors?.errors[0]?.message || 'Invalid response structure' ); } return response; } catch (error) { console.error('[CTS Bughunter] Error during scan:', error); // Return MCP-compliant error format const errorData = error instanceof z.ZodError ? { code: -32602, // Invalid params message: 'Invalid bughunter parameters', validationErrors: error.errors, } : { code: -32603, // Internal error message: error instanceof Error ? error.message : 'Unknown error during bug scan', errorType: error?.constructor?.name, }; return { content: [ { type: 'text', text: JSON.stringify({ error: errorData }, null, 2), }, ], }; } }; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/EricA1019/CTS_MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server