ADR-203: MCP Impact Analysis — Decision-Aware Change Risk Assessment
Document: ADR-203-mcp-impact-analysis-decision-aware-risk
Version: 1.0.0
Purpose: Document architectural decision for decision-aware impact analysis MCP server
Audience: Framework contributors, system architects
Date Created: 2026-01-17
Last Updated: 2026-02-15
Status: ACCEPTED
Task ID: H.5.5.3, H.12.2
Related ADRs: ADR-080 (Semantic Search), ADR-118 (Database Architecture),
ADR-151 (Context Graph), ADR-202 (Call Graph)
Related Documents:
- tools/mcp-impact-analysis/server.py
- tools/mcp-impact-analysis/CLAUDE.md
Context and Problem Statement
Background
When modifying code, developers need to understand the impact of their changes. Traditional impact analysis tools compute "blast radius" — the set of functions affected by a change. However, code changes are constrained by more than just call graphs:
- Architectural decisions (ADRs) prescribe how certain components should behave
- Historical errors reveal which functions have been problematic in the past
- Session context shows what was previously attempted and why
No existing tool combines all three dimensions into a single risk assessment.
Problem Statement
How do we provide impact analysis that accounts for architectural constraints and historical context, not just call graph topology, to help developers make informed decisions about code changes?
Requirements
Must-Have:
- Blast radius calculation using call graph data
- Risk score computation (0-100) with clear level categorization
- MCP protocol compliance for Claude Code integration
- Integration with org.db decisions table
Should-Have:
- File-level aggregate impact analysis
- Historical error correlation
- Decision constraint discovery with relevance scoring
- Multi-factor risk breakdown
Nice-to-Have:
- Trend analysis over time
- Automated risk escalation notifications
- Visual blast radius rendering
Decision Drivers
Technical Constraints
- T1: Must use existing call graph data (ADR-202) for blast radius
- T2: Must query org.db (TIER 2) for decisions and error_solutions
- T3: Must query sessions.db (TIER 3) for historical messages
- T4: Risk scoring must be deterministic and explainable
Value Proposition
- V1: No competitor provides decision-aware impact analysis
- V2: Historical error integration prevents repeating known issues
- V3: Risk levels enable graduated approval workflows
Decision Outcome
CHOSEN: Decision-Aware Impact Analysis with 3-Factor Risk Scoring
Rationale
- Unique value: Combines blast radius + decisions + error history (no competitor does this)
- Leverages existing data: org.db already stores decisions and error_solutions
- Actionable output: Risk levels (low/medium/high/critical) map directly to workflows
- Foundation for governance: Enables "architectural approval needed" workflows
Technical Implementation
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ MCP IMPACT ANALYSIS SERVER │
├─────────────────────────────────────────────────────────────────┤
│ │
│ MCP Client (Claude Code) │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ MCP Tools ││
│ │ • analyze_impact - Full impact: blast + decisions + ││
│ │ history + risk score ││
│ │ • analyze_file_impact - Aggregate impact for all functions ││
│ │ in a file ││
│ │ • find_decisions - Find ADRs related to target code ││
│ │ • assess_risk - Calculate change risk score ││
│ │ • impact_stats - System statistics ││
│ └─────────────────────────────────────────────────────────────┘│
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Call │ │ Decision │ │ Error │ │
│ │ Graph │ │ Store │ │ History │ │
│ │ │ │ │ │ │ │
│ │ callers │ │ decisions│ │ error_ │ │
│ │ callees │ │ (FTS5) │ │ solutions│ │
│ │ (org.db) │ │ (org.db) │ │ (org.db) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ └─────────────┬───────┴─────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Risk Calculator │ │
│ │ │ │
│ │ blast_radius: │ │
│ │ 0-40 points │ │
│ │ decisions: │ │
│ │ 0-35 points │ │
│ │ history: │ │
│ │ 0-25 points │ │
│ │ ─────────────── │ │
│ │ total: 0-100 │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
3-Factor Risk Scoring Algorithm
The risk score is computed from three independent factors:
def calculate_risk_score(
blast_radius: int,
decision_count: int,
historical_issues: int
) -> RiskAssessment:
"""
3-factor risk scoring.
Factor 1: Blast Radius (0-40 points)
0 callers → 0 pts (isolated function)
1-5 → 10 pts (small blast radius)
6-20 → 25 pts (medium blast radius)
21+ → 40 pts (large blast radius)
Factor 2: Decision Constraints (0-35 points)
0 decisions → 0 pts (no architectural constraints)
1-2 → 15 pts (few constraints)
3-5 → 25 pts (moderate constraints)
6+ → 35 pts (heavily constrained)
Factor 3: Historical Issues (0-25 points)
0 issues → 0 pts (clean history)
1-2 → 10 pts (some past issues)
3-5 → 18 pts (recurring issues)
6+ → 25 pts (chronically problematic)
"""
Risk Levels:
| Score | Level | Meaning | Action Required |
|---|---|---|---|
| 0-19 | low | Safe to modify | Proceed with standard review |
| 20-44 | medium | Review changes carefully | Peer review recommended |
| 45-69 | high | Significant review needed | Senior review required |
| 70-100 | critical | Architectural approval needed | ADR review before changes |
Decision Discovery
The find_decisions tool uses FTS5 full-text search against the decisions table in org.db:
def find_related_decisions(function_name: str) -> List[DecisionConstraint]:
"""
Find architectural decisions related to a function.
Search strategy:
1. FTS5 MATCH on function name against decision text
2. Path-component secondary search (file path segments)
3. Relevance scoring based on match quality
Returns DecisionConstraint objects with:
- decision_id, decision, decision_type
- rationale, confidence, relevance_score
- tags for categorization
"""
Historical Issue Retrieval
Combines two data sources:
| Source | Database | Table | What It Provides |
|---|---|---|---|
| Error solutions | org.db (TIER 2) | error_solutions | Verified error/fix pairs |
| Session messages | sessions.db (TIER 3) | messages | Past discussions mentioning the function |
MCP Tool Definitions
@mcp_tool
def analyze_impact(
function_name: str,
include_indirect: bool = True,
max_depth: int = 5
) -> Dict:
"""Full impact analysis with blast radius + decisions + history.
Returns blast_radius, decision_constraints, historical_issues, risk_assessment."""
@mcp_tool
def analyze_file_impact(file_path: str) -> Dict:
"""Aggregate impact for all functions in a file.
Useful for file-level refactoring decisions."""
@mcp_tool
def find_decisions(target: str) -> Dict:
"""Find architectural decisions related to code.
Essential for understanding WHY code is structured a certain way."""
@mcp_tool
def assess_risk(function_name: str) -> Dict:
"""Calculate change risk score.
Returns risk_score (0-100), risk_level, and factor breakdown."""
@mcp_tool
def impact_stats() -> Dict:
"""Get impact analysis system statistics.
Returns function/edge counts, decision distribution, high-impact functions."""
Value Proposition
What Competitors Provide
| Tool | Blast Radius | Decision Awareness | Error History | Risk Score |
|---|---|---|---|---|
| Cursor | No | No | No | No |
| JetBrains AI | Partial | No | No | No |
| Code Pathfinder | Partial | No | No | No |
| GitHub Copilot | No | No | No | No |
What CODITECT Uniquely Provides
Single query answers:
- "How risky is changing
hybrid_search?" → Risk: medium (45/100) - "Which ADRs constrain this function?" → ADR-080: "Use RRF fusion"
- "What past issues involved this function?" → ValueError: null embeddings
- "How many callers would be affected?" → 15 (2 direct, 13 indirect)
Example Output
{
"function_name": "hybrid_search",
"blast_radius": {
"total_affected": 15,
"direct_callers": 2,
"indirect_callers": 13
},
"decision_constraints": [
{
"decision": "Use RRF fusion for hybrid search",
"decision_type": "architecture",
"rationale": "Combines FTS5 precision with vector recall...",
"relevance_score": 0.85
}
],
"historical_issues": [
{
"type": "error",
"error_type": "ValueError",
"solution": "Added null check for empty embeddings"
}
],
"risk_assessment": {
"risk_score": 45,
"risk_level": "medium",
"factors": [
"Medium blast radius (15 callers)",
"Few constraints (1 decisions)",
"Few past issues (1)"
]
}
}
How coditect-core Utilizes This Server
Direct MCP Usage
Claude Code invokes these tools during development:
assess_riskbefore suggesting refactoringanalyze_impactbefore modifying shared functionsfind_decisionsto understand architectural constraintsanalyze_file_impactbefore file-level reorganizations
Integration with Other MCP Servers
| Server | Integration |
|---|---|
| mcp-call-graph (ADR-202) | Provides blast radius data (callers/callees) |
| mcp-semantic-search (ADR-080) | Decision search uses same FTS5 infrastructure |
| mcp-unified-gateway (ADR-204) | Routes impact analysis tools through single endpoint |
Automated Workflows
- Code review agents:
code-reviewer,architect-reviewuse risk scores to prioritize review effort - Breaking impact analysis:
breaking-impact-analystagent usesanalyze_file_impact - PR descriptions: Risk level included in auto-generated PR descriptions
- Health monitoring:
mcp-health-check.pyvalidates server availability
Consequences
Positive
- P1: Unique competitive advantage — no competitor provides decision-aware impact analysis
- P2: Risk levels enable graduated approval workflows (auto-merge vs. manual review)
- P3: Historical error correlation prevents repeating known mistakes
- P4: Explainable scoring — each factor contributes transparently
Negative
- N1: Risk scores may need calibration as more data accumulates
- N2: FTS5 decision matching is keyword-based (not semantic)
- N3: Historical issues depend on error_solutions being populated
- N4: Blast radius uses call graph data — requires reindexing when code changes
Dependencies
mcp>=0.9.0 # MCP Python SDK
# Uses org.db and sessions.db via scripts.core.paths
Files
| File | Purpose |
|---|---|
tools/mcp-impact-analysis/server.py | MCP server implementation (1010 lines) |
tools/mcp-impact-analysis/CLAUDE.md | Tool documentation |
Validation
- MCP server starts and registers 5 tools
- analyze_impact returns blast radius + decisions + history + risk score
- analyze_file_impact aggregates across all functions in a file
- find_decisions returns ADR constraints with relevance scoring
- assess_risk returns 0-100 score with level categorization
- impact_stats returns system statistics
- 3-factor risk scoring produces consistent, explainable results
- Decision search uses org.db (TIER 2, not sessions.db)
Status: ACCEPTED Decision Date: 2026-01-17 Implementation Status: COMPLETE Task ID: H.5.5.3, H.12.2 Maintainer: CODITECT Core Team Review Date: 2026-04-15 (quarterly review)