Skip to content

Component Spec: Governance MCP Server (Active Governance Agent) #2

@Brad-Edwards

Description

@Brad-Edwards

Component Spec: aces-governance-mcp

Purpose

An MCP server that acts as an active governance agent for the ACES
project. Every Claude Code instance working on any ACES repo can query
project standards, validate compliance, and route ADR proposals back to
the governance repo — without manually navigating to or reading from the
governance repo.

Who it serves: Any coding agent (or human with Claude Code) working
in any ACES repository.

Problem it solves: Governance knowledge (ADRs, STANDARDS.md,
ARCHITECTURE.md, templates) lives in the governance repo. Agents working
in other repos have no reliable way to access it. This causes convention
violations, duplicated effort, and standards drift. The MCP server makes
governance a live participant in every development session.

Interface

Reference Tools (read-only)

Tool Parameters Returns
list_adrs() All ADRs with numbers, titles, status
get_adr(identifier) ADR number or keyword Full ADR content, or search results
get_standard(section) Section number or keyword Matching STANDARDS.md section
get_architecture(section) Section name or keyword Matching ARCHITECTURE.md section
search_governance(query) Search term Matching excerpts with file locations
get_template(name) Template filename or "list" Template content or listing

Validation Tools (checks)

Tool Parameters Returns
check_repo_compliance(repo_path, repo_type) Absolute path, rust/python/governance Compliance report: passes and violations
check_dependency_direction(repo_name, dependencies) ACES repo name, list of dep names Validation result against architecture DAG

check_repo_compliance checks:

  • Required files exist per repo type (LICENSE, CHANGELOG.md, CLAUDE.md,
    .markdownlint.yaml, .pre-commit-config.yaml, CI workflow, plus
    type-specific files)
  • Repo naming convention (starts with aces-)
  • Rust: Apache-2.0 in Cargo.toml, deny(missing_docs) in lib.rs
  • Python: mypy strict in pyproject.toml, Apache-2.0 license
  • Template drift: compare governed files against governance templates

check_dependency_direction checks:

  • Dependencies respect the tier system from ARCHITECTURE.md
  • No tier-N repo depends on a tier >N repo

Governance Action Tools

Tool Parameters Returns
propose_adr(title, context, decision) Title string, context paragraphs, decision sketch URL of created GitHub issue

Creates a GitHub issue on aces-framework/aces with the governance
label, formatted as an ADR proposal for discussion. Uses the gh CLI
(must be authenticated).

MCP Resources

URI Content
aces://standards Full STANDARDS.md
aces://architecture Full ARCHITECTURE.md
aces://adrs ADR index (all titles and status)

Scope

In scope:

  • Read-only reference to all governance documents
  • Structural compliance validation (file existence, naming, config)
  • Template drift detection
  • Dependency direction validation against architecture DAG
  • ADR proposal creation via GitHub issues
  • Stdio transport (Claude Code spawns it, no daemon)

Explicitly out of scope:

  • Code generation or automated fixes (the server reports, it doesn't
    patch)
  • Runtime policy enforcement (e.g., OPA-style request authorization)
  • Modifying governance documents (read-only except for issue creation)
  • Network-based transport (stdio only for now)
  • Non-ACES repos (assumes ACES conventions)

Location and Structure

Lives in the governance repo at tools/governance-mcp/.

tools/governance-mcp/
  pyproject.toml          # scaffolded by uv init, deps via uv add
  src/
    aces_governance_mcp/
      __init__.py
      server.py           # FastMCP server, tool definitions
  tests/
    test_reference.py     # tests for reference tools
    test_validation.py    # tests for validation tools
    test_governance.py    # tests for governance action tools

Dependencies

  • mcp (Python MCP SDK — provides FastMCP)
  • gh CLI (for propose_adr, not a Python dependency)
  • Local clone of the governance repo (path via ACES_GOVERNANCE_REPO
    env var, defaults to repo root relative to package location)

Configuration

User adds to ~/.claude/settings.json (global, all ACES repos):

{
  "mcpServers": {
    "aces-governance": {
      "command": "uv",
      "args": [
        "run",
        "--directory", "/path/to/aces/tools/governance-mcp",
        "aces-governance-mcp"
      ]
    }
  }
}

The server resolves the governance repo root from its own install
location. The ACES_GOVERNANCE_REPO env var overrides this if the
server is installed elsewhere.

Verification

Unit tests (TDD — written before implementation):

  • test_reference.py:

    • list_adrs returns all ADRs with correct format
    • get_adr by number returns correct ADR
    • get_adr by keyword returns matching ADRs
    • get_adr with no match returns informative message
    • get_standard by section number returns correct section
    • get_standard by keyword searches title and body
    • get_architecture returns matching sections
    • search_governance finds matches across multiple files
    • search_governance with no results returns informative message
    • get_template by exact name returns content
    • get_template("list") returns all template names
  • test_validation.py:

    • check_repo_compliance on a fully compliant repo returns all passes
    • check_repo_compliance on a repo missing LICENSE reports failure
    • check_repo_compliance detects missing type-specific files
    • check_repo_compliance detects template drift
    • check_repo_compliance checks Rust-specific rules (license,
      missing_docs)
    • check_repo_compliance checks Python-specific rules (mypy strict)
    • check_dependency_direction accepts valid dependencies
    • check_dependency_direction rejects upward tier dependencies
    • check_dependency_direction ignores non-ACES dependencies
  • test_governance.py:

    • propose_adr calls gh issue create with correct arguments
    • propose_adr returns issue URL on success
    • propose_adr returns error message when gh is not installed
    • propose_adr returns error message on gh failure

Integration test:

  • Start the MCP server, send tool calls via MCP protocol, verify
    responses (can be a smoke test in CI).

Conventions

  • Python, following ACES standards (ruff, mypy --strict, Google-style
    docstrings, uv for deps)
  • Scaffolded with uv init, dependencies added with uv add
  • Virtual environment in .venv/
  • TDD: tests written before implementation

Open Questions

  1. Should validation tools also check CI workflow content (not just
    existence)? Or is that overreach for v0.1?
  2. Should propose_adr auto-detect the next ADR number, or leave
    numbering to the human reviewing the issue?
  3. Should there be a check_standards_update_needed(lesson) tool that
    helps agents identify when a lesson learned should be promoted to a
    formal standard?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgovernanceProject governance and repo configuration

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions