Skip to main content
Glama

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
NameRequiredDescriptionDefault
adrDirectoryNoDirectory containing ADR filesdocs/adrs
projectPathNoPath to the project directory.
specificAdrNoSpecific ADR filename or title to review (optional)
analysisDepthNoDepth of analysis to performdetailed
includeTreeSitterNoUse tree-sitter for enhanced code analysis
generateUpdatePlanNoGenerate action plan for updating non-compliant ADRs
conversationContextNoRich 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'
        );
      }
    }
  • 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 },
        },
      },
    });
  • 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;
      }
    }

Latest Blog Posts

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/tosin2013/mcp-adr-analysis-server'

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