# How the Codebase Memory MCP Configuration System Works with Environment Variables and JSON Files

> Understand the Codebase Memory MCP configuration system. Learn how it uses environment variables, JSON files, and a SQLite database for flexible and prioritized settings management.

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

---

**The Codebase Memory MCP configuration system uses a layered architecture where environment variables provide the highest precedence overrides, JSON files manage extension mappings and UI preferences, and a SQLite database persists CLI-managed runtime settings.**

The `codebase-memory-mcp` repository implements a deliberately simple yet powerful configuration model that blends multiple persistence layers. Understanding how these layers interact—from shell environment variables to project-specific JSON files—enables precise control over indexing behavior, caching locations, and language detection across your development workflow.

## The Layered Configuration Architecture

The configuration system operates on a **precedence-based layering model** where each source is read independently and later layers override earlier ones. According to the source code in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c) and [`src/pipeline/pipeline.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pipeline.c), the system resolves configuration in this order:

1. **Environment variables** (highest precedence)
2. **Global JSON extension map** (`$XDG_CONFIG_HOME/codebase-memory-mcp/config.json`)
3. **Per-project JSON extension map** (`<repo-root>/.codebase-memory.json`)
4. **CLI-managed SQLite database** (`${CBM_CACHE_DIR}/_config.db`)
5. **UI JSON settings** (`${CBM_CACHE_DIR}/config.json`)

This design ensures that temporary environment overrides can redirect cache paths, while persistent project settings remain scoped to specific repositories.

## Environment Variables: Runtime Control

Environment variables are read immediately at startup via standard `getenv` calls and determine the locations of all other configuration files. They are implemented in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c) where `cbm_config_open()` resolves the `CBM_CACHE_DIR` variable before opening the SQLite database.

### Core Environment Variables

| Variable | Default | Purpose |
|----------|---------|---------|
| `CBM_CACHE_DIR` | `~/.cache/codebase-memory-mcp` | Defines where the SQLite config DB, UI JSON, and index caches reside. All subsequent file-based configs resolve relative to this directory. |
| `CBM_LOG_LEVEL` | `info` | Controls verbosity (`debug`, `info`, `warn`, `error`, `none`). |
| `CBM_WORKERS` | Auto-detected | Overrides the number of indexing worker threads. |
| `CBM_ALLOWED_ROOT` | *unset* | Restricts `index_repository` to paths within this directory for security in multi-tenant environments. |
| `CBM_DIAGNOSTICS` | `false` | Enables periodic diagnostic dumps to `/tmp/cbm-diagnostics-<pid>.json`. |

Because these variables are evaluated before any file-based configuration loads, changing `CBM_CACHE_DIR` affects where the system looks for the SQLite database and UI JSON files.

## JSON Configuration Files

The system uses JSON files for **extension mapping** and **UI preferences**, allowing users to customize language detection without recompiling.

### Global Extension Mapping

The global configuration file lives at `$XDG_CONFIG_HOME/codebase-memory-mcp/config.json` (falling back to `~/.config/codebase-memory-mcp/config.json`). It contains an `extra_extensions` object that maps file extensions to language identifiers:

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

```

The function `cbm_userconfig_load()` in [`src/pipeline/pipeline.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pipeline.c) loads this file during startup, followed by `cbm_userconfig_load_extra_ext()` to populate the internal extension table.

### Per-Project Extension Mapping

Repository-specific overrides reside in `<repo-root>/.codebase-memory.json`. This file uses the same schema as the global configuration but takes precedence for overlapping keys. When `cbm_userconfig_load()` processes both files, the per-project mapping wins for any conflicting extensions, allowing different repositories to interpret the same file extension differently (e.g., `.svelte` as `javascript` in one project but `svelte` in another).

### UI Configuration JSON

The graphical interface stores its preferences in `${CBM_CACHE_DIR}/config.json`. Managed by `cbm_ui_config_load()` and `cbm_ui_config_save()` in [`src/ui/config.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/config.c), this file controls:

```json
{
  "ui_enabled": true,
  "ui_port": 9749
}

```

If the UI binary contains embedded assets and no configuration file exists, the UI auto-enables on first start.

## SQLite Runtime Database

For persistent settings that must survive across CLI invocations, the system uses a single-file SQLite database at `${CBM_CACHE_DIR}/_config.db`. The `codebase-memory-mcp config` sub-command provides the interface to this layer:

```bash
codebase-memory-mcp config set auto_index true
codebase-memory-mcp config get auto_index

```

The database is initialized in [`src/store/store.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/store/store.c) and accessed through `cbm_config_open()` in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c). Current supported keys include:

- **`auto_index`**: Boolean flag enabling automatic indexing when sessions start (default: `false`)
- **`auto_index_limit`**: Maximum file count for auto-indexing operations (default: `50000`)

This layer provides mutable state that environment variables and JSON files cannot easily offer, while remaining portable across system reboots.

## Configuration Precedence in Practice

When conflicts arise between these sources, the system applies a strict override hierarchy. Environment variables affect file paths immediately, JSON files provide static defaults, and the SQLite database offers user-modifiable persistence.

For example, if you set `CBM_CACHE_DIR=/tmp/cbm`, the system relocates both the SQLite database (to `/tmp/cbm/_config.db`) and the UI JSON (to [`/tmp/cbm/config.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main//tmp/cbm/config.json)) before loading them. Meanwhile, a per-project [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) can override global extension mappings regardless of where the cache directory resides.

## Practical Implementation Examples

### Redirecting the Cache Directory

Override the default cache location to use a temporary directory for a single session:

```bash
export CBM_CACHE_DIR=/tmp/cbm-cache
codebase-memory-mcp index /my/repo

# SQLite DB now at /tmp/cbm-cache/_config.db

# UI config at /tmp/cbm-cache/config.json

```

### Adding Global Language Support

Create `~/.config/codebase-memory-mcp/config.json` to treat `.svelte` files as JavaScript across all projects:

```json
{
  "extra_extensions": {
    ".svelte": "javascript"
  }
}

```

### Project-Specific Language Overrides

In a specific repository, create [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) to interpret `.svelte` as the `svelte` language instead:

```json
{
  "extra_extensions": {
    ".svelte": "svelte"
  }
}

```

The `cbm_userconfig_load()` function in [`src/pipeline/pipeline.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pipeline.c) merges this with the global map, giving priority to the local definition.

### Modifying Runtime Behavior

Enable automatic indexing for the next session using the CLI:

```bash
codebase-memory-mcp config set auto_index true
codebase-memory-mcp config get auto_index

# → true

```

### Accessing UI Configuration via API

When the UI server is running, inspect current settings via the HTTP endpoint defined in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c):

```bash
curl http://localhost:9749/api/ui-config

# {

#   "ui_enabled": true,

#   "ui_port": 9749

# }

```

## Summary

- **Environment variables** provide the highest precedence configuration, determining cache paths, log levels, and security restrictions before any files are read.
- **JSON files** handle extension-to-language mappings at both global (`~/.config/codebase-memory-mcp/config.json`) and per-project ([`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json)) scopes, with project settings overriding global ones.
- **SQLite database** at `${CBM_CACHE_DIR}/_config.db` persists runtime flags like `auto_index` and is managed via the `codebase-memory-mcp config` CLI command.
- **UI settings** reside in `${CBM_CACHE_DIR}/config.json` and are loaded by `cbm_ui_config_load()` in [`src/ui/config.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/config.c).
- The layered architecture ensures that environment variables can redirect file paths, while JSON files and SQLite provide persistent, hierarchical defaults.

## Frequently Asked Questions

### What takes precedence: environment variables or the JSON configuration files?

Environment variables take precedence over JSON files because they are evaluated first at process startup. For example, `CBM_CACHE_DIR` determines where the system looks for JSON and SQLite files, so changing this variable effectively redirects the entire configuration hierarchy before any file-based settings are loaded.

### How do I add support for a custom file extension in Codebase Memory?

Add an entry to the `extra_extensions` object in either the global JSON file (`~/.config/codebase-memory-mcp/config.json`) for system-wide changes, or in a [`.codebase-memory.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory.json) file at your repository root for project-specific overrides. The per-project file takes precedence for overlapping extensions, as implemented in `cbm_userconfig_load()` within [`src/pipeline/pipeline.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/pipeline/pipeline.c).

### Where does the `codebase-memory-mcp config` command store its settings?

The CLI stores runtime settings in a SQLite database located at `${CBM_CACHE_DIR}/_config.db`, defaulting to `~/.cache/codebase-memory-mcp/_config.db`. This database is initialized by `cbm_config_open()` in [`src/ui/http_server.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/ui/http_server.c) and accessed through the `config` sub-command to persist values like `auto_index` across sessions.

### Can I disable the web UI permanently?

Yes, set `ui_enabled` to `false` in `${CBM_CACHE_DIR}/config.json`, or delete the file entirely. If the UI binary contains embedded assets and no configuration file exists, the UI auto-enables on first start, but you can prevent this by explicitly disabling it via the JSON file or by removing the configuration to trigger the auto-enable logic only once.