review_existing_adrs
Analyze existing ADRs against actual code implementation to identify gaps and ensure alignment with architectural decisions.
Instructions
Review existing ADRs against actual code implementation with cloud/DevOps expertise. TIP: After review, call get_server_context to update @.mcp-server-context.md with findings.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| adrDirectory | No | Directory containing ADR files | docs/adrs |
| projectPath | No | Path to the project directory | . |
| specificAdr | No | Specific ADR filename or title to review (optional) | |
| analysisDepth | No | Depth of analysis to perform | detailed |
| includeTreeSitter | No | Use tree-sitter for enhanced code analysis | |
| generateUpdatePlan | No | Generate action plan for updating non-compliant ADRs | |
| conversationContext | No | Rich context from the calling LLM about user goals and discussion history |
Implementation Reference
- The core handler function that executes the 'review_existing_adrs' tool logic. Discovers ADRs, analyzes code structure using tree-sitter, computes compliance scores, identifies gaps, generates recommendations and update plans.export async function reviewExistingAdrs(args: { adrDirectory?: string; projectPath?: string; specificAdr?: string; analysisDepth?: 'basic' | 'detailed' | 'comprehensive'; includeTreeSitter?: boolean; generateUpdatePlan?: boolean; conversationContext?: ConversationContext; }): Promise<any> { const { adrDirectory = 'docs/adrs', projectPath = process.cwd(), specificAdr, analysisDepth = 'detailed', includeTreeSitter = true, generateUpdatePlan = true, } = args; // Security: Validate and resolve project path const resolvedProjectPath = path.resolve(projectPath); // Security: Ensure project path is not a system directory // Note: We explicitly ALLOW temp directories (/tmp, /var/folders, /private/tmp) // because tests and legitimate workflows use them const systemPaths = ['/Library', '/System', '/usr', '/etc', '/Applications', '/bin', '/sbin']; const allowedVarPaths = ['/var/folders', '/var/tmp']; // macOS temp directories const homeDir = process.env['HOME'] || ''; const sensitiveHomePaths = ['Library', 'Applications']; // Check for system paths, but allow temp directories const isSystemPath = systemPaths.some(sysPath => resolvedProjectPath.startsWith(sysPath)); const isAllowedVarPath = allowedVarPaths.some(varPath => resolvedProjectPath.startsWith(varPath)); if (isSystemPath) { throw new McpAdrError( 'INVALID_INPUT', `Security: Cannot analyze system directory: ${resolvedProjectPath}`, { projectPath: resolvedProjectPath } ); } // Block /var paths except allowed temp directories if (resolvedProjectPath.startsWith('/var') && !isAllowedVarPath) { throw new McpAdrError( 'INVALID_INPUT', `Security: Cannot analyze system directory: ${resolvedProjectPath}`, { projectPath: resolvedProjectPath } ); } // Block /private paths except /private/tmp (macOS symlink for /tmp) if ( resolvedProjectPath.startsWith('/private') && !resolvedProjectPath.startsWith('/private/tmp') && !resolvedProjectPath.startsWith('/private/var/folders') ) { throw new McpAdrError( 'INVALID_INPUT', `Security: Cannot analyze system directory: ${resolvedProjectPath}`, { projectPath: resolvedProjectPath } ); } // Check for sensitive paths within home directory if (homeDir.length > 0 && resolvedProjectPath.startsWith(homeDir)) { const relativePath = resolvedProjectPath.slice(homeDir.length + 1); const firstDir = relativePath.split(path.sep)[0]; if (firstDir && sensitiveHomePaths.includes(firstDir)) { throw new McpAdrError( 'INVALID_INPUT', `Security: Cannot analyze sensitive directory: ${resolvedProjectPath}`, { projectPath: resolvedProjectPath } ); } } try { // Step 1: Discover existing ADRs const { discoverAdrsInDirectory } = await import('../utils/adr-discovery.js'); const discoveryResult = await discoverAdrsInDirectory(adrDirectory, resolvedProjectPath, { includeContent: true, includeTimeline: false, }); if (discoveryResult.totalAdrs === 0) { return { content: [ { type: 'text', text: `# ADR Review: No ADRs Found ## Discovery Results - **Directory**: ${adrDirectory} - **Project Path**: ${resolvedProjectPath} - **ADRs Found**: 0 ## Recommendations 1. **Create Initial ADRs**: Use the \`suggest_adrs\` tool to identify architectural decisions 2. **Set Up ADR Directory**: Create the ADR directory structure 3. **Establish ADR Process**: Implement ADR workflow for future decisions ## Next Steps \`\`\`json { "tool": "suggest_adrs", "args": { "projectPath": "${resolvedProjectPath}", "analysisType": "comprehensive" } } \`\`\` `, }, ], }; } // Step 2: Filter ADRs if specific one requested const adrsToReview = specificAdr ? discoveryResult.adrs.filter( adr => adr.filename.includes(specificAdr) || adr.title.toLowerCase().includes(specificAdr.toLowerCase()) ) : discoveryResult.adrs; if (adrsToReview.length === 0) { throw new McpAdrError(`No ADRs found matching: ${specificAdr}`, 'ADR_NOT_FOUND'); } // Step 3: Analyze environment context (simplified - no ResearchOrchestrator per ADR-018) // The ResearchOrchestrator is deprecated and caused 37+ test timeouts (850s+ test suite) // For environment analysis, users can call environment-analysis-tool separately if needed const environmentContext = ` ## 📊 Code Analysis Context **Analysis Mode**: ${analysisDepth} **Tree-sitter Enabled**: ${includeTreeSitter ? '✅' : '❌'} **Project**: ${path.basename(resolvedProjectPath)} > **Note**: For detailed environment analysis, use the \`environment-analysis-tool\` separately. > This tool focuses on ADR-to-code compliance validation. `; const researchConfidence = 0.85; // Static confidence for basic code analysis // Step 4: Analyze code structure const codeAnalysis = await analyzeCodeStructure(resolvedProjectPath, includeTreeSitter); // Step 5: Review each ADR const reviewResults: AdrReviewResult[] = []; for (const adr of adrsToReview) { const reviewResult = await reviewSingleAdr( adr, codeAnalysis, analysisDepth, resolvedProjectPath ); reviewResults.push(reviewResult); } // Step 5: Generate comprehensive report const overallScore = reviewResults.reduce((sum, result) => sum + result.complianceScore, 0) / reviewResults.length; const totalGaps = reviewResults.reduce( (sum, result) => sum + result.codeCompliance.gaps.length, 0 ); const needsUpdate = reviewResults.filter(result => result.recommendations.updateAdr).length; const needsCodeChanges = reviewResults.filter( result => result.recommendations.updateCode ).length; let updatePlan = ''; if (generateUpdatePlan) { updatePlan = await generateUpdatePlanContent( reviewResults, codeAnalysis, resolvedProjectPath ); } return { content: [ { type: 'text', text: `# ADR Compliance Review Report ## Overview - **Project**: ${path.basename(resolvedProjectPath)} - **ADRs Reviewed**: ${reviewResults.length} - **Overall Compliance Score**: ${overallScore.toFixed(1)}/10 - **Research Confidence**: ${(researchConfidence * 100).toFixed(1)}% - **Analysis Depth**: ${analysisDepth} - **Tree-sitter Analysis**: ${includeTreeSitter ? '✅ Enabled' : '❌ Disabled'} ${environmentContext} ## Summary Statistics - **Total Gaps Identified**: ${totalGaps} - **ADRs Needing Updates**: ${needsUpdate} - **Code Changes Required**: ${needsCodeChanges} - **Full Compliance**: ${reviewResults.filter(r => r.complianceScore >= 8).length} - **Partial Compliance**: ${reviewResults.filter(r => r.complianceScore >= 5 && r.complianceScore < 8).length} - **Non-Compliance**: ${reviewResults.filter(r => r.complianceScore < 5).length} ## Detailed Reviews ${reviewResults .map( result => ` ### ${result.title} - **File**: ${path.basename(result.adrPath)} - **Status**: ${result.status} - **Compliance Score**: ${result.complianceScore}/10 #### Implementation Status - **Implemented**: ${result.codeCompliance.implemented ? '✅' : '❌'} - **Partially Implemented**: ${result.codeCompliance.partiallyImplemented ? '⚠️' : '❌'} - **Not Implemented**: ${result.codeCompliance.notImplemented ? '🚨' : '✅'} #### Evidence Found ${ result.codeCompliance.evidence.length > 0 ? result.codeCompliance.evidence.map(e => `- ${e}`).join('\n') : '- No supporting evidence found in codebase' } #### Gaps Identified ${ result.codeCompliance.gaps.length > 0 ? result.codeCompliance.gaps.map(g => `- ${g}`).join('\n') : '- No gaps identified' } #### Recommendations ${result.recommendations.actions.map(a => `- ${a}`).join('\n')} #### Analysis ${result.analysis} --- ` ) .join('\n')} ## Code Structure Analysis - **Files Analyzed**: ${codeAnalysis.files.length} - **Technologies Detected**: ${codeAnalysis.technologies.join(', ')} - **Architectural Patterns**: ${codeAnalysis.patterns.join(', ')} ### Architectural Elements - **APIs**: ${codeAnalysis.architecturalElements.apis?.length || 0} - **Databases**: ${codeAnalysis.architecturalElements.databases?.length || 0} - **Frameworks**: ${codeAnalysis.architecturalElements.frameworks?.length || 0} - **Patterns**: ${codeAnalysis.architecturalElements.patterns?.length || 0} - **Infrastructure Resources**: ${codeAnalysis.architecturalElements.infrastructureResources?.length || 0} - **DevOps Tools**: ${codeAnalysis.architecturalElements.devopsTools?.length || 0} ### Enterprise Security Analysis (Tree-sitter) ${ includeTreeSitter ? ` - **Security Findings**: ${codeAnalysis.architecturalElements.securityFindings?.length || 0} ${ (codeAnalysis.architecturalElements.securityFindings?.length || 0) > 0 ? ` #### Critical Security Issues: ${codeAnalysis.architecturalElements .securityFindings!.slice(0, 10) .map((finding: string) => `- ${finding}`) .join('\n')} ${(codeAnalysis.architecturalElements.securityFindings!.length || 0) > 10 ? `\n*... and ${(codeAnalysis.architecturalElements.securityFindings!.length || 0) - 10} more security findings*` : ''} ` : '- ✅ No security issues detected' } ` : '- Tree-sitter security analysis disabled' } ### DevOps Stack Analysis ${ includeTreeSitter && (codeAnalysis.architecturalElements.infrastructureResources?.length || 0) > 0 ? ` #### Infrastructure Resources: ${codeAnalysis.architecturalElements .infrastructureResources!.slice(0, 10) .map((resource: string) => `- ${resource}`) .join('\n')} ${(codeAnalysis.architecturalElements.infrastructureResources!.length || 0) > 10 ? `\n*... and ${(codeAnalysis.architecturalElements.infrastructureResources!.length || 0) - 10} more resources*` : ''} ` : '- No infrastructure resources detected' } ${ includeTreeSitter && (codeAnalysis.architecturalElements.devopsTools?.length || 0) > 0 ? ` #### DevOps Tools Detected: ${codeAnalysis.architecturalElements .devopsTools!.slice(0, 10) .map((tool: string) => `- ${tool}`) .join('\n')} ${(codeAnalysis.architecturalElements.devopsTools!.length || 0) > 10 ? `\n*... and ${(codeAnalysis.architecturalElements.devopsTools!.length || 0) - 10} more tools*` : ''} ` : '- No DevOps tools detected' } ${generateUpdatePlan ? updatePlan : ''} ## Next Steps ### Immediate Actions (High Priority) ${ reviewResults .filter(r => r.complianceScore < 5) .map(r => `- **${r.title}**: ${r.recommendations.actions[0] || 'Requires immediate attention'}`) .join('\n') || '- No immediate actions required' } ### Medium Priority ${ reviewResults .filter(r => r.complianceScore >= 5 && r.complianceScore < 8) .map(r => `- **${r.title}**: ${r.recommendations.actions[0] || 'Minor updates needed'}`) .join('\n') || '- No medium priority items' } ### Maintenance ${ reviewResults .filter(r => r.complianceScore >= 8) .map(r => `- **${r.title}**: Well implemented, monitor for changes`) .join('\n') || '- No items in maintenance status' } ## Quality Assessment ### Best Practices Compliance - **Documentation Quality**: ${calculateDocumentationQuality(reviewResults)}/10 - **Implementation Fidelity**: ${calculateImplementationFidelity(reviewResults)}/10 - **Architectural Consistency**: ${calculateArchitecturalConsistency(reviewResults)}/10 ### Recommendations for Process Improvement 1. **Regular ADR Reviews**: Schedule quarterly compliance reviews 2. **Automated Validation**: Implement CI/CD checks for ADR compliance 3. **Developer Training**: Ensure team understands ADR importance 4. **Template Updates**: Standardize ADR format for better tracking ## Tools for Follow-up ### Update Specific ADRs \`\`\`json { "tool": "generate_adr_from_decision", "args": { "decisionData": { "title": "Updated [ADR Title]", "context": "Review findings and current implementation", "decision": "Refined decision based on analysis", "consequences": "Updated consequences from review" } } } \`\`\` ### Generate Implementation Plan \`\`\`json { "tool": "generate_implementation_plan", "args": { "adrPath": "[specific ADR path]", "includeCodeChanges": true, "priority": "high" } } \`\`\` `, }, ], }; } catch (error) { throw new McpAdrError( `Failed to review ADRs: ${error instanceof Error ? error.message : String(error)}`, 'REVIEW_ERROR' ); } }
- src/tools/tool-catalog.ts:400-418 (schema)Defines the tool metadata, input schema, and categorization in the central tool catalog used for MCP ListTools and dynamic discovery.TOOL_CATALOG.set('review_existing_adrs', { name: 'review_existing_adrs', shortDescription: 'Review and analyze existing ADRs', fullDescription: 'Reviews existing ADRs for relevance, accuracy, and potential updates.', category: 'adr', complexity: 'moderate', tokenCost: { min: 2000, max: 4000 }, hasCEMCPDirective: true, // Phase 4.3: Moderate tool - ADR review relatedTools: ['validate_all_adrs', 'suggest_adrs'], keywords: ['adr', 'review', 'analyze', 'update'], requiresAI: true, inputSchema: { type: 'object', properties: { focusArea: { type: 'string' }, includeRecommendations: { type: 'boolean', default: true }, }, }, });
- src/utils/server-context-generator.ts:199-201 (registration)Lists the tool in server context documentation with name and description for LLM awareness.name: 'review_existing_adrs', description: 'Review and analyze existing ADRs for quality and completeness', },
- Helper function that reviews a single ADR against code analysis results, extracts elements, finds related files, computes compliance.async function reviewSingleAdr( adr: any, codeAnalysis: CodeAnalysisResult, depth: string, projectPath: string ): Promise<AdrReviewResult> { const result: AdrReviewResult = { adrPath: adr.path, title: adr.title, status: adr.status, complianceScore: 0, codeCompliance: { implemented: false, partiallyImplemented: false, notImplemented: false, evidence: [], gaps: [], }, recommendations: { updateAdr: false, updateCode: false, createPlan: false, actions: [], }, analysis: '', }; try { // Parse ADR content for key architectural elements const adrElements = extractAdrElements(adr.content || ''); // SMART CODE LINKING: Find related code files for this specific ADR let relatedFiles: any[] = []; try { const { findRelatedCode } = await import('../utils/file-system.js'); const relatedCodeResult = await findRelatedCode(adr.path, adr.content || '', projectPath, { useAI: true, useRipgrep: true, maxFiles: 25, includeContent: false, }); relatedFiles = relatedCodeResult.relatedFiles; // Add Smart Code Linking results to evidence if (relatedFiles.length > 0) { result.codeCompliance.evidence.push( `Smart Code Linking found ${relatedFiles.length} related files (confidence: ${(relatedCodeResult.confidence * 100).toFixed(0)}%)` ); // Add top related files as evidence const topFiles = relatedFiles.slice(0, 5); topFiles.forEach(file => { result.codeCompliance.evidence.push(`Related: ${file.path}`); }); } else { result.codeCompliance.gaps.push('No related code files found using Smart Code Linking'); } } catch (error) { console.warn('Smart Code Linking failed:', error); result.codeCompliance.gaps.push('Smart Code Linking unavailable - manual review required'); } // Compare ADR elements with code implementation (enhanced with related files) const complianceAnalysis = await analyzeCompliance(adrElements, codeAnalysis, relatedFiles); // Merge Smart Code Linking evidence with compliance analysis result.codeCompliance.evidence.push(...complianceAnalysis.evidence); result.codeCompliance.gaps.push(...complianceAnalysis.gaps); result.codeCompliance.implemented = complianceAnalysis.implemented || relatedFiles.length > 0; result.codeCompliance.partiallyImplemented = complianceAnalysis.partiallyImplemented || (relatedFiles.length > 0 && relatedFiles.length < 5); result.codeCompliance.notImplemented = complianceAnalysis.notImplemented && relatedFiles.length === 0; result.complianceScore = calculateComplianceScore(result.codeCompliance); // Generate recommendations (enhanced with Smart Code Linking insights) result.recommendations = generateRecommendations( result.codeCompliance, result.complianceScore, relatedFiles ); // Generate detailed analysis (include Smart Code Linking results) result.analysis = generateDetailedAnalysis( adrElements, result.codeCompliance, depth, relatedFiles ); return result; } catch (error) { result.analysis = `Error analyzing ADR: ${error instanceof Error ? error.message : String(error)}`; return result; } }