Files
codebase-memory-mcp/docs/CONFIGURATION.md
T
Martin Vogel 7fa5b07718 feat: enforce one workspace boundary on every indexing entry point
Routes the MCP index_repository handler and the graph UI's POST /api/index
through a single decision function. The UI route previously checked only that
root_path was a directory, so an operator's configured boundary held on one
entry point and not the other; it now canonicalizes first and applies the same
policy, answering 403 with the reason.

The decision is two-tier, because a bare default-deny would refuse every
first run and a bare opt-in leaves the default open:

- Breadth is always enforced, with nothing configured. Filesystem, drive and
  share roots, top-level system trees, the home directory itself and
  credential directories are refused as indexing roots out of the box.
- Containment in a declared root applies once CBM_ALLOWED_ROOT is set or a
  grant exists, and is evaluated first so a path outside a configured root is
  reported as exactly that.

Three things the tests caught, each a real defect rather than a test fix:

- On macOS /etc, /tmp and /var are firmlinked under /private, so
  canonicalizing "/etc" yields "/private/etc" and counted two deep — sailing
  past a minimum of two, missing the very path being guarded. Depth now
  discounts a leading "private" component.
- An earlier draft refused any root containing the cache directory. That was
  over-claimed: the indexer only parses recognised source files and a graph
  database is binary SQLite it would never extract. Refusing a whole root is
  also the wrong remedy where the concern does hold — not walking the cache
  is. Removed, with the reasoning recorded at the site.
- Rewording the refusal to "outside every allowed root" broke an assertion
  matching "outside the allowed root", and that test's early return skipped
  its CBM_ALLOWED_ROOT cleanup, leaking the variable into every later test in
  the suite. The original wording is kept and guidance appended instead.
  Worth remembering: these contracts match strings, not properties.

Docs updated in the same change, since both env-var tables said "unset
imposes no restriction" and that is no longer true: CONFIGURATION.md and
README.md describe the two tiers, and CONFIGURATION.md lists the always-
refused roots along with the two limits that matter — this constrains scope
rather than sensitivity, and the credential list is a denylist that raises the
cost of a mistake rather than closing the class. SECURITY.md's supported-
versions table was still on 0.8.x and now reads 0.9.x.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-06 01:02:02 +02:00

7.1 KiB

Configuration Reference

This page documents the configuration files that codebase-memory-mcp reads or writes today.

At a Glance

Purpose Path Format Notes
Global custom extension mapping $XDG_CONFIG_HOME/codebase-memory-mcp/config.json JSON Falls back to ~/.config/codebase-memory-mcp/config.json when XDG_CONFIG_HOME is unset.
Per-project custom extension mapping {repo_root}/.codebase-memory.json JSON Overrides conflicting global extra_extensions entries.
CLI-managed runtime settings ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/_config.db SQLite Written by codebase-memory-mcp config set/reset.
UI settings ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/config.json JSON Stores ui_enabled and ui_port.
Daemon operation log ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/logs/cbm-daemon.log Structured log Durable daemon lifecycle, watcher/indexing, UI, resource, and error events.
Admission conflict log ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/logs/daemon-conflicts.ndjson NDJSON Exact-build, ABI, and canonical-cache conflicts.
Activation log ${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/logs/activation-events.ndjson NDJSON Install/update/uninstall activation progress and outcomes.

CBM resolves CBM_CACHE_DIR to a canonical per-account path before using any of these locations. The log directory and files are private to the account.

1. Custom File Extension Mapping

Two optional JSON files let you map additional file extensions to built-in languages.

Global config

Default path:

$XDG_CONFIG_HOME/codebase-memory-mcp/config.json

Fallback when XDG_CONFIG_HOME is unset:

~/.config/codebase-memory-mcp/config.json

Per-project config

Place this file in the repository root:

.codebase-memory.json

Format

{
  "extra_extensions": {
    ".blade.php": "php",
    ".mjs": "javascript",
    ".twig": "html"
  }
}

Notes:

  • Extension keys must include the leading dot.
  • Language names are case-insensitive.
  • Unknown language names are skipped.
  • Missing files are ignored.
  • If the same extension appears in both files, the per-project file wins.

2. CLI-Managed Runtime Settings

The config subcommand stores runtime settings in a small SQLite database:

${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/_config.db

Inspect or change values with the CLI:

codebase-memory-mcp config list
codebase-memory-mcp config get auto_index
codebase-memory-mcp config set auto_index true
codebase-memory-mcp config set auto_index_limit 50000
codebase-memory-mcp config reset auto_index

Current keys:

Key Default Meaning
auto_index false Automatically index new projects when an MCP session starts.
auto_index_limit 50000 Maximum file count allowed for automatic indexing of a new project.

3. UI Settings

The optional built-in graph UI stores its settings in:

${CBM_CACHE_DIR:-~/.cache/codebase-memory-mcp}/config.json

Current format:

{
  "ui_enabled": false,
  "ui_port": 9749
}

Notes:

  • If the UI-enabled binary has embedded assets and no UI config file exists yet, the UI auto-enables on first run.
  • CBM_CACHE_DIR changes both the UI config location and the runtime settings database location.
  • CBM resolves CBM_CACHE_DIR to one canonical per-account cache root. A process configured with a different root fails while any CBM session or command is active; close them before switching roots.

4. Environment Variables

These environment variables affect runtime behavior:

Variable Default Description
CBM_ALLOWED_ROOT (unset) Confine index_repository to paths within this directory. When set, a repo_path that resolves (after symlink / .. resolution) outside this root is refused, and the same check now applies to the graph UI's POST /api/index route rather than only to the MCP tool. Unset imposes no containment restriction — but see the always-on limits below, which apply whether or not this is set. Useful when the server may be driven by an untrusted caller, e.g. agentic or multi-tenant deployments.
CBM_CACHE_DIR ~/.cache/codebase-memory-mcp Override the cache directory used for indexes, _config.db, and UI config.json.
CBM_DIAGNOSTICS false Enable periodic snapshot.json and retained trajectory.ndjson below a fresh owner-private directory in the system temp directory. The daemon records the randomized paths in the diagnostics.start discovery record (a single JSON line) in ${CBM_CACHE_DIR}/logs/cbm-daemon.log; that one record is emitted even when CBM_LOG_LEVEL suppresses ordinary logging, so the paths always remain discoverable.
CBM_DOWNLOAD_URL GitHub releases Override the update download URL.
CBM_LOG_LEVEL info Set the log level to debug, info, warn, error, or none (or 0-4). Thin-frontend messages use that session's stderr; detached daemon events use ${CBM_CACHE_DIR}/logs/cbm-daemon.log.
CBM_WORKERS auto-detected Override the indexing worker count.

Environment used by daemon-owned components—such as diagnostics, daemon logging, and process-wide indexing resource limits—is captured from the first daemon-backed session that starts the daemon. Later sessions join the existing process and cannot replace those values. To change them, close every daemon-backed session, update the relevant agent configurations consistently, and restart a session. CBM_ALLOWED_ROOT remains session-specific, a conflicting CBM_CACHE_DIR is rejected, and one-shot CLI commands use their own current environment without starting the daemon.

Roots that are always refused

Independently of CBM_ALLOWED_ROOT, some directories are refused as an indexing root because they are too broad or too sensitive to index as a unit:

  • a filesystem root, a Windows drive root, or a UNC share root;
  • a top-level system tree — /etc, /var, /usr, /home, /Users, and on Windows C:\Windows, C:\Users, C:\ProgramData, C:\Program Files;
  • your home directory itself (directories below it are fine);
  • a credential directory at any depth — .ssh, .aws, .gnupg, .kube, .docker, .netrc, .git-credentials, .password-store, macOS Keychains.

Two limits are worth stating plainly. This constrains scope, not sensitivity: inside a root that is allowed, every file the process can read may be indexed and later returned. And the credential list is a denylist, so it raises the cost of a mistake rather than closing the class — a directory it does not name is permitted.

5. Agent and Editor Integration Files

The install command can also write MCP entries and instruction blocks into agent/editor config files such as Claude Code, Codex, Gemini, VS Code, Cursor, Zed, and others.

Those target paths vary by tool and platform, so the easiest way to inspect the exact files for your machine is:

codebase-memory-mcp install --dry-run

That prints the specific config files the installer would modify without writing anything.