How the Codebase Memory MCP Configuration System Works with Environment Variables and JSON Files
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 and src/pipeline/pipeline.c, the system resolves configuration in this order:
- Environment variables (highest precedence)
- Global JSON extension map (
$XDG_CONFIG_HOME/codebase-memory-mcp/config.json) - Per-project JSON extension map (
<repo-root>/.codebase-memory.json) - CLI-managed SQLite database (
${CBM_CACHE_DIR}/_config.db) - 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 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:
{
"extra_extensions": {
".blade.php": "php",
".mjs": "javascript",
".twig": "html"
}
}
The function cbm_userconfig_load() in 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, this file controls:
{
"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:
codebase-memory-mcp config set auto_index true
codebase-memory-mcp config get auto_index
The database is initialized in src/store/store.c and accessed through cbm_config_open() in 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) before loading them. Meanwhile, a per-project .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:
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:
{
"extra_extensions": {
".svelte": "javascript"
}
}
Project-Specific Language Overrides
In a specific repository, create .codebase-memory.json to interpret .svelte as the svelte language instead:
{
"extra_extensions": {
".svelte": "svelte"
}
}
The cbm_userconfig_load() function in 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:
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:
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) scopes, with project settings overriding global ones. - SQLite database at
${CBM_CACHE_DIR}/_config.dbpersists runtime flags likeauto_indexand is managed via thecodebase-memory-mcp configCLI command. - UI settings reside in
${CBM_CACHE_DIR}/config.jsonand are loaded bycbm_ui_config_load()insrc/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 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.
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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →