Skip to content

manage_adr (MCP/CLI) and the UI /api/adr endpoints use separate storage backends #256

Closed

Description

@bschrib

The MCP tool manage_adr writes/reads ADRs as files at <root>/.codebase-memory/adr.md. The HTTP UI's /api/adr endpoints read/write SQLite via cbm_store_adr_get / cbm_store_adr_store. Writes via either interface are invisible to the other.

Reproduction (v0.6.0, macOS arm64):

# write via CLI
codebase-memory-mcp cli manage_adr '{"project":"<name>","mode":"update","content":"## PURPOSE\ntest\n"}'

# CLI roundtrips
codebase-memory-mcp cli manage_adr '{"project":"<name>","mode":"get"}'   # -> returns content
cat <repo>/.codebase-memory/adr.md                                         # -> content present

# UI endpoint
curl http://localhost:9749/api/adr?project=<name>                          # -> {"has_adr": false}

The UI's + ADR button stays + ADR because hasAdr comes from that /api/adr response (graph-ui/src/components/StatsTab.tsx:111).

Code pointers:

  • src/mcp/mcp.c:3498-3555 — handle_manage_adr, file-backed at <root>/.codebase-memory/adr.md.
  • src/ui/http_server.c:449-559 — handle_adr_get / handle_adr_save, SQLite-backed via cbm_store_adr_* (src/store/store.c:4537,4560).

Expected: one canonical backend. The file-on-disk path is likely the right target since it's committable and lives with the repo; the SQLite-backed UI handlers would need to switch to reading/writing the file.

Impact: ADRs created by agents via MCP don't surface in the graph UI. ADRs created by humans in the UI aren't readable by agents.

Activity

  1. DeusData commented on May 31, 2026

    @DeusData
    Owner

    Thanks — clean diagnosis. The two interfaces did use separate backends: manage_adr read/wrote <root>/.codebase-memory/adr.md (a file), while the UI /api/adr GET/POST used the SQLite project_summaries table via cbm_store_adr_get/cbm_store_adr_store. Writes on one side were invisible to the other.

    Fixed in commit 70e3ed7: manage_adr now goes through cbm_store_adr_get/cbm_store_adr_store — the same store backend the UI uses — for all modes (update/store, get, sections). So an ADR written via the MCP tool shows up in the UI and vice-versa.

    Migration: to avoid losing ADRs created by older versions, on first access manage_adr checks for a legacy .codebase-memory/adr.md and, if the store has no ADR yet, imports it into the store automatically. So your existing file-based ADRs carry over with no manual step.

    Regression tests added:

    • tool_manage_adr_unified_backend_issue256 — writes via manage_adr(update), then reads back via cbm_store_adr_get (the exact API /api/adr uses) and asserts they match.
    • the existing tool_manage_adr_get_with_existing_adr now exercises the file→store migration path.

    Ships in the next release. Thanks for the precise reproduction!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions