MCP Server · .NET 10 · stdio

Every architectural decision, on the record.

AdrMcp turns a folder of Markdown decision records into live tools your AI assistant can use — search them, write them, validate them, and trace how one decision superseded another.

$ dotnet tool install -g AdrMcp
ACCEPTED
id: 0007
date: 2026-05-12
tags: datastorage
links: supersedes → 0003

Use PostgreSQL for persistence

Context and Problem Statement
Considered Options
Decision Outcome
Consequences
18 tools MADR 4.0 format Preview by default Git-native storage Provider-based code linking Any MCP client

The record

Decisions live next to the code, not in someone's memory.

ADRs are plain Markdown files under docs/adr/ — versioned in git, diff-able, and readable without any tooling. AdrMcp adds the layer that makes them queryable and writable from your assistant, so the reasoning behind a choice is captured when it's made and traceable years later.

MECHANICS

The server does the bookkeeping

Sequential numbering, frontmatter, slugs, bidirectional links, and lifecycle rules — handled, so a record is never malformed.

SAFETY

Nothing writes without a preview

Every mutating tool returns a unified diff first. Pass previewOnly=false only when the change is what you meant.

HISTORY

Supersede, never overwrite

Decisions change. AdrMcp records the replacement and links both ways, so the trail from old to current stays intact.

Toolbox

Eighteen tools, four jobs.

Grouped by what they do to the record — read it, write it, reason about it, or ship it.

Navigation

read-only
  • list_adrs — filter by status, tag, date
  • get_adr — one record, or just sections
  • search_adrs — lexical or semantic
  • get_adr_index — the decision log
  • find_related_adrs — links + chain
  • get_adr_graph — nodes and edges

Authoring

preview-first
  • create_adr — from a MADR/Nygard template
  • update_adr — replace one section
  • set_status — lifecycle-enforced
  • supersede_adr — replace + link, one call
  • link_adrs — typed, bidirectional

Intelligence

analysis
  • validate_adr — structure + link integrity
  • detect_conflicts — overlapping decisions
  • find_stale_adrs — broken code refs
  • coverage_report — gaps by area
  • suggest_adr_from_change — draft from a diff

Utility

export
  • render_index — browsable README
  • diff_adr — compare two records

Writes are preview-by-default. Every authoring and utility tool takes previewOnly (true by default) and returns the diff of the intended change before anything touches disk.

Lifecycle

A status a record can't skip.

The server enforces the transitions, so a decision can't quietly jump from a draft to retired without passing through the states in between.

proposed accepted deprecated / superseded
proposed rejected

Superseding creates the replacement as accepted, flips the original to superseded, and writes the supersedes / superseded-by links between them — in a single call.

The craft

Skills that supply the judgment the tools don't.

The server provides the mechanics. Three Claude Code skills add the taste — when a decision is worth recording, and whether it's framed honestly.

adr-author

Write it well

Decides whether a decision warrants a record, then frames a sharp Context, Decision, and honest Consequences.

triggers on "record this decision"
adr-review

Hold it up to the light

Structural and substantive critique against a rubric — is the decision falsifiable, are the alternatives real?

triggers on "review this ADR"
adr-supersede

Retire it correctly

Picks the right lifecycle move and preserves history instead of editing the past.

triggers on "we changed our mind"

Quick start

Install, then point your client at it.

Runs as a local stdio process your MCP client launches — no port, no server to host.

shell
# as a global tool
dotnet tool install -g AdrMcp
adr-mcp --adr-root ./docs/adr

# or from source
dotnet run --project AdrMcp -- \
  --adr-root ./docs/adr
mcp client config
{
  "mcpServers": {
    "adr": {
      "command": "adr-mcp",
      "args": [
        "--adr-root", "docs/adr",
        "--repo-root", "."
      ]
    }
  }
}