# Environment Variables That Control Codebase Memory Behavior: Complete Configuration Guide

> Master Codebase Memory behavior with our guide to CBM_* environment variables. Configure memory management for your daemon session effectively. Read now to optimize.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: configuration-guide
- Published: 2026-07-28

---

**Codebase Memory (CBM) behavior is governed entirely by `CBM_*` environment variables read at process startup via `cbm_safe_getenv` in [`src/foundation/platform.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/platform.c) and cached for the lifetime of the daemon session.**

The DeusData/codebase-memory-mcp engine relies on a strict environment variable scheme to configure caching, security boundaries, logging verbosity, and memory limits without requiring recompilation. These variables are queried early in the process lifetime and remain immutable for the duration of the daemon-backed session, ensuring consistent runtime behavior across CLI invocations.

## How CBM Reads and Caches Environment Variables

All configuration values are retrieved through **`cbm_safe_getenv`**, a centralized wrapper implemented in [[`src/foundation/platform.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/platform.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/platform.c). This function provides safe fallback handling and is the sole mechanism for environment access throughout the codebase.

When the daemon launches via [[`src/daemon/application.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/daemon/application.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/daemon/application.c), it immediately snapshots the current environment state. Subsequent CLI sessions that attach to this daemon cannot override these values; operators must stop the daemon before changes take effect. Early process entry points in [[`src/main.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/main.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/main.c) and the CLI handler in [[`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) follow the same pattern, reading variables during initialization and caching the results.

## Core Configuration Variables

### Cache and Storage Location (CBM_CACHE_DIR)

**`CBM_CACHE_DIR`** defines the root filesystem path for the SQLite configuration database, UI JSON files, and all log directories. The default value is `~/.cache/codebase-memory-mcp`, which expands to the user's home directory during canonicalization.

Changing this variable requires terminating all active CBM sessions, as the daemon holds file handles open to the original path. All derived paths, including `${CBM_CACHE_DIR}/logs/cbm-daemon.log`, are computed relative to this root during startup.

### Security and Repository Scope (CBM_ALLOWED_ROOT)

**`CBM_ALLOWED_ROOT`** enforces a security boundary for repository indexing. When set, the indexing logic in [[`src/discover/userconfig.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/discover/userconfig.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/discover/userconfig.c) and the supervisor in [[`src/mcp/index_supervisor.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/index_supervisor.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/index_supervisor.c) reject any path that resolves outside the specified directory. This is essential for multi-tenant environments or when processing untrusted caller inputs.

## Logging and Diagnostics

### Log Level Control (CBM_LOG_LEVEL)

**`CBM_LOG_LEVEL`** accepts string values (`debug`, `info`, `warn`, `error`, `none`) or numeric equivalents (`0-4`) to set the verbosity for both daemon and CLI components. The default is `info`. While the daemon always writes to `${CBM_CACHE_DIR}/logs/cbm-daemon.log`, thin-frontend messages respect this threshold for console output.

### Diagnostic Snapshots (CBM_DIAGNOSTICS)

Setting **`CBM_DIAGNOSTICS`** to `true` enables periodic generation of [`snapshot.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/snapshot.json) and `trajectory.ndjson` files in a temporary, owner-private directory. The daemon logs the temporary path to the main log file for correlation. This feature introduces minimal overhead and is useful for debugging indexing behavior.

## Performance and Concurrency

### Worker Pool Sizing (CBM_WORKERS)

**`CBM_WORKERS`** controls the number of parallel indexing workers. When unset, CBM auto-detects the optimal concurrency based on available CPU cores. Operators can override this to limit resource consumption on shared infrastructure or to force specific parallelism levels for reproducibility.

### Index Supervisor (CBM_INDEX_SUPERVISOR)

**`CBM_INDEX_SUPERVISOR`** defaults to `1` (enabled) and controls the restart-capping supervisor that coordinates multiple workers in [[`src/mcp/index_supervisor.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/index_supervisor.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/index_supervisor.c). Set to `0` to disable the supervisor, which is useful for deterministic testing scenarios where worker orchestration must be predictable.

## Feature Toggles

### LSP Cross-Project Indexing (CBM_DISABLE_LSP_CROSS)

Defining **`CBM_DISABLE_LSP_CROSS`** disables cross-project language-server indexing. The pipeline logic in [[`src/pipeline/pipeline.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pipeline.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pipeline.c) checks for this variable and skips the LSP-cross step when present. This is particularly valuable in CI environments that require strictly per-repository data isolation.

### File Watcher Pruning (CBM_WATCHER_PRUNE_GRACE_S)

**`CBM_WATCHER_PRUNE_GRACE_S`** specifies the grace period in seconds before the file watcher prunes stale worktrees. When unset, the system uses internal defaults. Adjust this to control how aggressively CBM cleans up temporary or detached working directories.

## Memory Management

### Memory Budget Cap (CBM_MEM_BUDGET_MB)

**`CBM_MEM_BUDGET_MB`** enforces a hard cap on total heap allocation. The custom allocator in [[`src/foundation/mem.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/mem.c)](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/mem.c) references this limit to prevent unbounded growth during large repository indexing operations.

### Memory Profiling (CBM_MEM_PROFILE)

**`CBM_MEM_PROFILE`** and **`CBM_MEM_PROFILE_MIN`** enable low-overhead memory usage profiling in the daemon. When `CBM_MEM_PROFILE` is set to a non-zero value, the system records allocation statistics for analysis.

## Practical Configuration Examples

Change the cache directory and restart the daemon:

```bash
export CBM_CACHE_DIR="$HOME/.local/share/cbm"
codebase-memory-mcp daemon stop
codebase-memory-mcp config set

```

Enable debug logging for troubleshooting:

```bash
export CBM_LOG_LEVEL=debug
codebase-memory-mcp daemon start

```

Restrict indexing to a trusted directory tree:

```bash
export CBM_ALLOWED_ROOT="/srv/trusted-repos"
codebase-memory-mcp index /srv/trusted-repos/my-project  # succeeds

codebase-memory-mcp index /tmp/malicious-repo            # fails with "outside allowed root"

```

Disable cross-project LSP indexing for CI:

```bash
export CBM_DISABLE_LSP_CROSS=1
codebase-memory-mcp index .

```

In C, environment variables are accessed programmatically:

```c
char buf[256];
if (cbm_safe_getenv("CBM_LOG_LEVEL", buf, sizeof(buf), NULL) && buf[0]) {
    set_log_level(buf);   // defined in src/foundation/diagnostics.c
}

```

## Summary

- **All configuration** flows through `cbm_safe_getenv` in [`src/foundation/platform.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/platform.c), which provides safe defaults and prevents buffer overflows.
- **`CBM_CACHE_DIR`** determines the root for all persistent data, while **`CBM_ALLOWED_ROOT`** provides a security sandbox for repository access.
- **Logging verbosity** is controlled by `CBM_LOG_LEVEL`, and **diagnostic artifacts** are enabled via `CBM_DIAGNOSTICS`.
- **Concurrency** is managed by `CBM_WORKERS` and `CBM_INDEX_SUPERVISOR`, allowing fine-tuning of the indexing pipeline.
- **Memory limits** are enforced by `CBM_MEM_BUDGET_MB` in the custom allocator at [`src/foundation/mem.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/foundation/mem.c).
- **Daemon immutability**: Environment variables are captured at daemon startup; changes require a daemon restart to take effect.

## Frequently Asked Questions

### What happens if I change CBM_CACHE_DIR while the daemon is running?

The change is ignored until all CBM sessions are terminated and the daemon is restarted. The daemon holds open file descriptors to the original cache directory, and the canonicalization logic only runs during initialization in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c). You must run `codebase-memory-mcp daemon stop` before the new root takes effect.

### How do I restrict CBM to only index specific directories?

Set **`CBM_ALLOWED_ROOT`** to the absolute path of your trusted repository root. The `index_repository` function in [`src/mcp/index_supervisor.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/mcp/index_supervisor.c) resolves all input paths and rejects any that fall outside this boundary. This prevents accidental or malicious indexing of sensitive filesystem locations.

### Can I adjust log levels without restarting the daemon?

No. The daemon snapshots **`CBM_LOG_LEVEL`** during initialization in [`src/daemon/application.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/daemon/application.c). While the thin CLI frontend can adjust its own verbosity, the persistent daemon logs at the level captured at startup. To change daemon log verbosity, stop the daemon, update the variable, and restart.

### What is the difference between CBM_WORKERS and CBM_INDEX_SUPERVISOR?

**`CBM_WORKERS`** sets the number of parallel indexing threads, while **`CBM_INDEX_SUPERVISOR`** enables a coordination layer that manages worker restarts and crash recovery. Disabling the supervisor (`CBM_INDEX_SUPERVISOR=0`) allows workers to run without oversight, which is useful for deterministic testing but risky for production workloads.