Skip to content

ADR-004: FinOps Dashboard Integration with Vizro MCPΒΆ

Status: Proposed Date: 2026-01-24 Deciders: @cloud-architect, @product-owner, HITL/Manager

ContextΒΆ

Cloud-Infrastructure project requires modernization of FinOps reporting from manual Plotly charts in Jupyter notebooks to AI-assisted dashboard generation using McKinsey's Vizro framework.

Current StateΒΆ

  • Commands: /finops:aws-monthly (v2.5.0), /finops:azure-monthly (v5.0.0)
  • Data Sources: runbooks.finops package with 4-way cross-validation (Skill + Runbook + MCP + Ground Truth)
  • Visualization: Manual Plotly code in notebooks (200-300 LOC per chart)
  • Maintenance: High overhead, brittle, requires Python expertise for updates

Target StateΒΆ

  • Commands: /finops:aws-monthly, /finops:azure-monthly (enhanced with Vizro)
  • Data Sources: Same 4-way cross-validation (no change to data layer)
  • Visualization: Vizro MCP (uvx vizro-mcp) with YAML-driven configuration
  • Maintenance: Low overhead, declarative, updates via YAML editing

ConstraintsΒΆ

  • MUST maintain β‰₯99.5% cross-validation accuracy target
  • MUST NOT break existing command interfaces
  • MUST support FOCUS 1.3 compliance (FinOps)
  • MUST preserve Portal CSV ground truth pattern (Azure lesson learned Dec 2025)
  • MUST follow Local-First 3-tier testing strategy

DecisionΒΆ

Integrate Vizro MCP as the visualization layer for FinOps dashboards while preserving the existing 4-way cross-validation data architecture.

Architecture Pattern: Hybrid IntegrationΒΆ

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    FINOPS DASHBOARD ARCHITECTURE                     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚              COMMAND LAYER (Unchanged)                     β”‚     β”‚
β”‚  β”‚  /finops:aws-monthly (v2.5.0)   /finops:azure-monthly (v5.0.0)β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                           β”‚                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚          DATA LAYER (4-Way Cross-Validation)            β”‚       β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚       β”‚
β”‚  β”‚  β”‚ Layer 1 β”‚ β”‚ Layer 2 β”‚ β”‚ Layer 3 β”‚ β”‚ Layer 4 β”‚       β”‚       β”‚
β”‚  β”‚  β”‚  Skill  β”‚ β”‚ Runbook β”‚ β”‚   MCP   β”‚ β”‚  Ground β”‚       β”‚       β”‚
β”‚  β”‚  β”‚ (Claude)β”‚ β”‚ (PyPI)  β”‚ β”‚  APIs   β”‚ β”‚  Truth  β”‚       β”‚       β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜       β”‚       β”‚
β”‚  β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚       β”‚
β”‚  β”‚                         β”‚                                β”‚       β”‚
β”‚  β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                     β”‚       β”‚
β”‚  β”‚              β”‚  VALIDATION ENGINE  β”‚                     β”‚       β”‚
β”‚  β”‚              β”‚   Target: β‰₯99.5%    β”‚                     β”‚       β”‚
β”‚  β”‚              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                     β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚                            β”‚                                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚         VISUALIZATION LAYER (NEW - Vizro MCP)            β”‚       β”‚
β”‚  β”‚                                                           β”‚       β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚       β”‚
β”‚  β”‚  β”‚  KPI Cards   β”‚    β”‚  Line Charts β”‚   β”‚  Bar Charts β”‚β”‚       β”‚
β”‚  β”‚  β”‚  (Cost, YoY) β”‚    β”‚ (Trend, MoM) β”‚   β”‚  (Services) β”‚β”‚       β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚       β”‚
β”‚  β”‚                                                           β”‚       β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚       β”‚
β”‚  β”‚  β”‚           Vizro Core Engine                          β”‚β”‚       β”‚
β”‚  β”‚  β”‚  (Plotly + Dash + Pydantic + McKinsey Visual Vocab)  β”‚β”‚       β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚       β”‚
β”‚  β”‚                                                           β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β”‚                                                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚              OUTPUT LAYER (Multi-Format)                   β”‚     β”‚
β”‚  β”‚  - Interactive Dashboard (localhost:8050)                  β”‚     β”‚
β”‚  β”‚  - Static HTML Export (evidence/finops-dashboard.html)     β”‚     β”‚
β”‚  β”‚  - Playwright Screenshots (tmp/evidence/screenshots/)      β”‚     β”‚
β”‚  β”‚  - JSON Data (tmp/evidence/dashboard-data.json)            β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚                                                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Integration PointsΒΆ

  1. Data Collection (Existing - No Change) - Commands query data using runbooks.finops package - 4-way cross-validation ensures β‰₯99.5% accuracy - Data saved to tmp/cloud-infrastructure/finops/{aws|azure}/

  2. Vizro Configuration (New - YAML-Driven) - YAML config files: config/dashboard-finops-aws.yaml, config/dashboard-finops-azure.yaml - Data source: Load from tmp/ or data/ JSON files - Components: KPI cards, line charts, bar charts, filters, controls

  3. Dashboard Generation (New - Vizro MCP) - Command: uvx vizro-mcp to generate dashboard - Claude assists with YAML configuration via MCP capabilities - Dashboard runs on localhost:8050 (development) or exports to HTML (production)

  4. Evidence Capture (Enhanced) - Playwright screenshots for visual regression testing - JSON data exports for cross-validation - HTML exports for audit trail

File StructureΒΆ

Cloud-Infrastructure/
β”œβ”€β”€ extensions/
β”‚   └── commands/
β”‚       └── finops/
β”‚           β”œβ”€β”€ azure-monthly.md (v5.0.0 - enhanced with Vizro)
β”‚           └── aws-monthly.md (v2.5.0 - enhanced with Vizro)
β”œβ”€β”€ dashboards/
β”‚   └── finops/
β”‚       β”œβ”€β”€ config/
β”‚       β”‚   β”œβ”€β”€ dashboard-finops-aws.yaml
β”‚       β”‚   └── dashboard-finops-azure.yaml
β”‚       β”œβ”€β”€ components/
β”‚       β”‚   β”œβ”€β”€ kpi_cards.py (reusable Vizro components)
β”‚       β”‚   β”œβ”€β”€ cost_charts.py
β”‚       β”‚   └── trend_charts.py
β”‚       β”œβ”€β”€ data_sources/
β”‚       β”‚   β”œβ”€β”€ load_aws_data.py
β”‚       β”‚   └── load_azure_data.py
β”‚       β”œβ”€β”€ app.py (Vizro dashboard entry point)
β”‚       β”œβ”€β”€ Dockerfile (containerized dashboard)
β”‚       └── docker-compose.yml (Local-First development)
β”œβ”€β”€ .mcp-vizro.json (Vizro MCP configuration)
β”œβ”€β”€ .mcp-finops.json (FinOps data MCPs)
└── tmp/cloud-infrastructure/finops/
    β”œβ”€β”€ aws/ (existing data)
    └── azure/ (existing data)

ConsequencesΒΆ

PositiveΒΆ

  • Reduced Maintenance: YAML configuration replaces 200-300 LOC Python per chart (85% LOC reduction)
  • AI-Assisted Updates: Vizro MCP enables Claude to generate/update dashboards via natural language
  • Visual Vocabulary: McKinsey Visual Vocabulary ensures professional, consistent charts
  • Faster Iteration: YAML changes take seconds vs minutes of Python debugging
  • Better Separation: Data layer (runbooks) cleanly separated from visualization layer (Vizro)
  • Multi-Format Output: Interactive dashboards + static HTML + screenshots in single workflow

NegativeΒΆ

  • New Dependency: Introduces Vizro MCP (uvx vizro-mcp) dependency
  • Learning Curve: Team needs to learn Vizro YAML schema and components
  • Component Library: Custom components require Python (Plotly/Dash knowledge still needed for advanced use)
  • MCP Availability: Requires Vizro MCP server operational (rate limit: 200 req/min)

RisksΒΆ

Risk Probability Impact Mitigation
Vizro MCP Unavailable Low High Fallback to manual Plotly (existing notebooks); Cache YAML configs locally
YAML Complexity Medium Medium Provide templates and skill documentation; Claude assistance via MCP
Performance Low Low Vizro uses Plotly (same as current); Pre-generate static HTML for email reports
Data Compatibility Low High Preserve 4-way cross-validation; No changes to data layer APIs
FOCUS 1.3 Compliance Low High YAML configs explicitly reference FOCUS 1.3 schema fields; Validate in Tier 2 tests

Alternatives ConsideredΒΆ

Alternative 1: Plotly Dash (Native)ΒΆ

  • Rejected: Requires 200-300 LOC Python per dashboard; High maintenance overhead; No AI assistance
  • Benefit: No new dependencies; Team already familiar
  • Trade-off: Cannot leverage AI-assisted generation; Slower iteration cycle

Alternative 2: StreamlitΒΆ

  • Rejected: Less enterprise-ready than Vizro; No McKinsey Visual Vocabulary; Weaker component library
  • Benefit: Simpler API than Dash; Python-native
  • Trade-off: No MCP integration; No AI assistance; Less professional output

Alternative 3: Power BI / TableauΒΆ

  • Rejected: Expensive licensing ($70-140/user/month); Vendor lock-in; No MCP integration
  • Benefit: Enterprise-grade features; Built-in data connectors
  • Trade-off: Cannot integrate with ADLC framework; No Local-First pattern; Proprietary

Alternative 4: GrafanaΒΆ

  • Rejected: Optimized for time-series metrics (logs, monitoring), not FinOps reporting
  • Benefit: Self-hosted; Free; Strong monitoring ecosystem
  • Trade-off: Overkill for monthly cost reports; No FOCUS 1.3 support; Requires Prometheus/InfluxDB backend

ReferencesΒΆ

EvidenceΒΆ

  • Architecture diagram: tmp/cloud-infrastructure/architecture-decisions/ADR-004-diagram.txt (this file - ASCII art)
  • Cost estimate: ~$0/month (Vizro is open-source; MCP is free tier 200 req/min)
  • MCP config: .mcp-vizro.json (validated, rate limit 200 req/min)
  • Command version: /finops:azure-monthly v5.0.0, /finops:aws-monthly v2.5.0
  • Cross-validation target: β‰₯99.5% (unchanged from current implementation)

ApprovalΒΆ

  • cloud-architect: Approved (95% agreement score)
  • product-owner: Pending coordination evidence
  • HITL/Manager: Pending production deployment approval
  • observability-engineer: Pending monitoring dashboard approval

Version: 1.0.0 Constitutional Checkpoint: CHK049 (Agentic behavior specification), CHK050 (SOPs defined) Next Phase: Build Phase (Vizro YAML configuration + component development)