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;
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions the tool performs a 'review' with 'cloud/DevOps expertise' and suggests a follow-up action, but doesn't disclose critical behavioral traits: whether this is a read-only analysis or modifies files, what permissions are needed, what the output format is, or any rate limits. The description is insufficient for a complex 7-parameter tool with no annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately concise with two sentences. The first sentence states the core purpose, and the second provides a workflow tip. However, the TIP could be better integrated or presented as a separate guideline rather than appended to the main description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 7 parameters, nested objects, no annotations, and no output schema, the description is inadequate. It doesn't explain what the tool returns, how findings are presented, what 'review' entails operationally, or how the cloud/DevOps expertise is applied. The TIP about updating context is helpful but doesn't compensate for the missing behavioral and output context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 7 parameters thoroughly. The description doesn't add any parameter-specific information beyond what's in the schema. According to the rules, when schema coverage is high (>80%), the baseline is 3 even with no param info in the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Review existing ADRs against actual code implementation with cloud/DevOps expertise.' It specifies the verb ('Review'), resource ('existing ADRs'), and context ('cloud/DevOps expertise'). However, it doesn't explicitly differentiate from sibling tools like 'validate_adr' or 'validate_all_adrs' that might perform similar validation functions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some usage guidance with the TIP about calling 'get_server_context' after review, which implies a workflow sequence. However, it doesn't explicitly state when to use this tool versus alternatives like 'validate_adr' or 'compare_adr_progress', nor does it provide clear exclusions or prerequisites for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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