Analyze Error
analyze_errorAnalyze error output to generate a deterministic fix brief using project context and relevant files.
Instructions
Analyze provided error output and return a deterministic project-local fix brief.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| error_output | Yes | ||
| command | No | ||
| cwd | No | ||
| package_context | No | ||
| relevant_files | No | ||
| environment | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| analysis_id | Yes | ||
| fingerprint | Yes | ||
| stack | Yes | ||
| likely_cause | Yes | ||
| best_first_fix | Yes | ||
| verification | Yes | ||
| prior_project_fixes | Yes | ||
| avoid | Yes | ||
| confidence | Yes |
Implementation Reference
- src/tools/analyze-error.ts:13-64 (handler)Main handler for the analyze_error tool. Parses input, normalizes error, detects stack, generates fingerprint, matches against memory, builds a fix brief, and returns a structured FixBrief with confidence score.
export async function analyzeError(input: AnalyzeErrorInput): Promise<FixBrief> { const parsed = analyzeErrorInputSchema.parse(input); const redactedInput = redactUnknown(parsed); const normalized = normalizeError(redactedInput.error_output); const stack = detectStack({ input: redactedInput, normalized }); const fingerprint = generateFingerprint(normalized, stack); const projectCwd = resolveProjectCwd(redactedInput.cwd); const analysisId = generateAnalysisId(fingerprint, projectCwd); rememberAnalysisProjectPath(analysisId, projectCwd); await writeAnalysisRegistry({ analysis_id: analysisId, fingerprint, project_path: projectCwd }); const memory = await readMemory(projectCwd); const memoryMatches = matchMemory({ records: memory, fingerprint, stack, keywords: normalized.keywords }); const priorProjectFixes = memoryMatches.successes.map(toPriorProjectFix); const avoid = memoryMatches.failures.map(toAvoidFix); const brief = buildBrief({ input: redactedInput, normalized, stack, priorProjectFixes, avoid }); const output = fixBriefSchema.parse({ analysis_id: analysisId, fingerprint, stack, ...brief, prior_project_fixes: priorProjectFixes, avoid, confidence: confidenceFor({ stack, input: redactedInput, hasExactMemoryMatch: [...memoryMatches.successes, ...memoryMatches.failures].some((match) => match.matchedBy.includes("fingerprint") ) }) }); return fixBriefSchema.parse(redactUnknown(output)); } - src/tools/analyze-error.ts:87-115 (helper)confidenceFor: Computes a confidence score (0.35-0.9) based on stack detection, presence of package_context, relevant_files, command, and exact memory fingerprint match.
function confidenceFor({ stack, input, hasExactMemoryMatch }: { stack: string; input: AnalyzeErrorInput; hasExactMemoryMatch: boolean; }): number { let confidence = 0.35; if (stack !== "unknown") { confidence += 0.2; } if (input.package_context) { confidence += 0.1; } if (input.relevant_files && input.relevant_files.length > 0) { confidence += 0.1; } if (input.command) { confidence += 0.05; } if (hasExactMemoryMatch) { confidence += 0.15; } return Math.min(0.9, Number(confidence.toFixed(2))); } - src/tools/analyze-error.ts:66-85 (helper)writeAnalysisRegistry: Persists analysis metadata (analysis_id, fingerprint, project_path) to a registry file for restart recovery.
async function writeAnalysisRegistry({ analysis_id, fingerprint, project_path }: { analysis_id: string; fingerprint: string; project_path: string; }): Promise<void> { try { await appendAnalysisRegistryRecord({ timestamp: new Date().toISOString(), analysis_id, fingerprint, project_path }); } catch { // The registry is a convenience for restart recovery; analysis should still work without it. } } - Input schema (analyzeErrorInputSchema) using Zod defining the required error_output and optional command, cwd, package_context, relevant_files, environment fields. Also exports the AnalyzeErrorInput TypeScript type.
import { z } from "zod"; export const relevantFileSchema = z.object({ path: z.string().optional(), language: z.string().optional(), excerpt: z.string().optional(), content: z.string().optional(), metadata: z.record(z.unknown()).optional() }); export const analyzeErrorInputSchema = z.object({ error_output: z.string().min(1, "error_output is required"), command: z.string().optional(), cwd: z.string().optional(), package_context: z.record(z.unknown()).optional(), relevant_files: z.array(relevantFileSchema).optional(), environment: z.record(z.unknown()).optional() }); export type AnalyzeErrorInput = z.infer<typeof analyzeErrorInputSchema>; - src/server.ts:21-36 (registration)Registration of the 'analyze_error' tool in the MCP server via server.registerTool with title, description, input/output schemas, and the async handler that calls analyzeError and returns text content.
server.registerTool( "analyze_error", { title: "Analyze Error", description: "Analyze provided error output and return a deterministic project-local fix brief.", inputSchema: analyzeErrorInputSchema.shape, outputSchema: fixBriefSchema.shape }, async (args) => { const output = await analyzeError(args); return { content: [{ type: "text", text: JSON.stringify(output, null, 2) }], structuredContent: output }; } );