Skip to content

fix(mcp): detect Dolt-backed projects in workspace discovery (GH#2997)#3207

Open
maphew wants to merge 2 commits intogastownhall:mainfrom
maphew:worktree-fix-mcp-dolt-discovery-2997
Open

fix(mcp): detect Dolt-backed projects in workspace discovery (GH#2997)#3207
maphew wants to merge 2 commits intogastownhall:mainfrom
maphew:worktree-fix-mcp-dolt-discovery-2997

Conversation

@maphew
Copy link
Copy Markdown
Collaborator

@maphew maphew commented Apr 12, 2026

Summary

Fixes #2997 — MCP context() tool reported "Database: Not found" for embedded Dolt projects because workspace discovery only globbed for *.db files. Embedded Dolt has no *.db; data lives at .beads/embeddeddolt/ and the backend is declared in .beads/metadata.json.

  • Adds _has_beads_project_files() mirroring Go's hasBeadsProjectFiles (checks metadata.json, config.yaml, dolt/, embeddeddolt/, or non-backup *.db)
  • _find_beads_db_in_tree() and .beads/redirect validation now recognise SQLite, embedded Dolt, and server Dolt
  • New _find_beads_project() + _detect_backend() in server.py; context() reports Project: ... (backend: dolt-embedded) instead of the misleading "Not found" for Dolt projects

Test plan

  • 5 new unit tests covering embedded Dolt, server Dolt, metadata-only projects, redirects to Dolt, vc.db exclusion
  • All 18 test_workspace_auto_detect.py tests pass
  • 0 regressions across 62 related tests (test_workspace_auto_detect, test_multi_project_switching, test_lifecycle, test_tools, test_worktree_separate_dbs)
  • End-to-end: context_set() returns correct output for both Dolt-embedded and SQLite workspaces

🤖 Generated with Claude Code

The MCP `context()` tool reported "Database: Not found" for embedded Dolt
projects because `_find_beads_db()` and `_find_beads_db_in_tree()` only
globbed for `*.db` files. Embedded Dolt projects keep their data under
`.beads/embeddeddolt/` and declare the backend in `.beads/metadata.json`
— there is no `*.db` file to find.

Adds `_has_beads_project_files()` mirroring Go's `hasBeadsProjectFiles`
(metadata.json, config.yaml, dolt/, embeddeddolt/, or non-backup *.db).
Both Python discovery functions (and `.beads/redirect` validation) now
use this check, so SQLite, embedded Dolt, and server Dolt projects are
all recognized.

`context()` now reports the project root and backend when no SQLite db
is present, instead of the misleading "Not found".
Copy link
Copy Markdown
Collaborator Author

@maphew maphew left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: fix(mcp): detect Dolt-backed projects in workspace discovery

Good work — _has_beads_project_files correctly mirrors Go's hasBeadsProjectFiles, the tools.py refactoring is clean, and the 5 new tests are thorough. Three bugs to address:


1. 🔴 Bug (high) — _detect_backend crashes on malformed metadata.json

File: server.py L290-300

json.load() can return any JSON type ([], "string", 42). The subsequent meta.get("backend") throws AttributeError which is not caught by the except (OSError, ValueError, json.JSONDecodeError) clause, crashing the MCP server.

Fix:

        try:
            with open(metadata_path) as f:
                meta = json.load(f)
            if not isinstance(meta, dict):
                meta = {}
            backend = (meta.get("backend") or meta.get("database") or "").lower()

2. 🟡 Bug (medium) — _find_beads_project doesn't follow .beads/redirect

File: server.py L256-278

This function duplicates the upward directory walk from _find_beads_db_in_tree (in tools.py) but skips redirect handling. Worktree setups that rely on .beads/redirect will fail — _context_set won't find the project even though the existing _find_beads_db_in_tree would.

Fix: Remove _find_beads_project entirely. In _context_set, call the already-robust _find_beads_db_in_tree(resolved_root) to get the project root, then derive the backend:

    project_root = _find_beads_db_in_tree(resolved_root)
    if project_root is None:
        # ... "Not found" path ...

    backend = _detect_backend(os.path.join(project_root, ".beads"))

This eliminates the duplicated walk and inherits redirect + symlink support for free.


3. 🟡 Bug (medium) — SQLite fallthrough when .db file is missing

File: server.py L703-721

When _detect_backend returns "sqlite" (e.g. metadata.json declares it) but no .db file exists yet, _find_beads_db(project_root) returns None. The code falls out of the if db_path: block and into the Dolt/unknown path, reporting:

Context set successfully:
  Project: /path/.beads (backend: sqlite)

…instead of the expected "Database: Not found (run context(action='init') to create)" message.

Fix: Add an else clause:

    if backend == "sqlite":
        db_path = _find_beads_db(project_root)
        if db_path:
            _workspace_context["BEADS_DB"] = db_path
            os.environ["BEADS_DB"] = db_path
            return (
                f"Context set successfully:\n"
                f"  Workspace root: {resolved_root}\n"
                f"  Database: {db_path}"
            )
        else:
            _workspace_context.pop("BEADS_DB", None)
            os.environ.pop("BEADS_DB", None)
            return (
                f"Context set successfully:\n"
                f"  Workspace root: {resolved_root}\n"
                f"  Database: Not found (run context(action='init') to create)"
            )

Note (pre-existing, not from this PR)

test_compaction_config.py has hardcoded macOS paths (/Users/stevey/src/dave/beads/...) that fail on non-macOS environments.


Tests and _has_beads_project_files logic look solid. With these three fixes the PR should be good to merge. 👍

…ect support

Addresses review item #2: _find_beads_project duplicated the upward
directory walk but skipped .beads/redirect handling. Now delegates to
_find_beads_db_in_tree, inheriting redirect, symlink, and all backend
detection for free.

Amp-Thread-ID: https://ampcode.com/threads/T-019d84e2-3a96-7263-a399-c3b2cc0ba6bb
Co-authored-by: Amp <amp@ampcode.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP context() reports 'Database: Not found' for embedded Dolt projects

1 participant