Skip to content

mcp: scans wrong directory when launched by Cursor/Windsurf (cwd-based root resolution) #346

@justrach

Description

@justrach

Problem

When Cursor, Windsurf, or VS Code launch codedb mcp as an MCP server they do not set cwd to the open project directory — they inherit their own application process cwd, which is typically /Applications, /usr/local, ~, or whatever the OS assigns at app launch.

codedb mcp resolves its scan root from cwd at startup (src/main.zig L97: root = ".", then resolveRoot calls cwd().realpath(".", ...)). This means codedb silently indexes the wrong directory — one the user never asked for — and the user gets no results or, worse, results from an unrelated path.

The existing root_policy.isIndexableRoot guard only blocks /, /tmp, and the literal home directory. Paths like /Applications, /usr/local, /opt, and /opt/homebrew all pass the guard today and will trigger a full scan.

The MCP protocol has a roots handshake (roots/list) that codedb already implements, but it races: scanBg fires unconditionally on startup (main.zig L636–638) before the first JSON-RPC message arrives, so the roots response always comes too late.

Failing Test

test "issue-332: root_policy rejects dangerous ambient cwd roots" {
    const root_policy = @import("root_policy.zig");
    try testing.expect(!root_policy.isIndexableRoot("/"));
    try testing.expect(!root_policy.isIndexableRoot("/Applications"));
    try testing.expect(!root_policy.isIndexableRoot("/usr"));
    try testing.expect(!root_policy.isIndexableRoot("/usr/local"));
    try testing.expect(!root_policy.isIndexableRoot("/usr/local/bin"));
    try testing.expect(!root_policy.isIndexableRoot("/opt"));
    try testing.expect(!root_policy.isIndexableRoot("/opt/homebrew"));
}

Verified failing on current main:

error: 'tests.test.issue-332: root_policy rejects dangerous ambient cwd roots' failed
src/tests.zig:7604: try testing.expect(!root_policy.isIndexableRoot("/Applications"));
409/410 tests passed (1 failed)

Expected

codedb mcp launched without an explicit path arg should either:

  1. Block startup until a valid root is confirmed (MCP roots handshake or CLI positional arg), or
  2. Exit immediately with a clear error rather than scanning the ambient cwd

isIndexableRoot must also reject shallow system paths (/Applications, /usr, /opt, etc.).

Fix

See RFC: docs/rfc-mcp-root-resolution.md (filed alongside this issue).

Short-term: expand isIndexableRoot to deny all paths shallower than a real project dir.
Long-term: defer the initial scan until a confirmed root is available. See RFC for full design.

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