How to Debug Issues in Codebase-Memory-MCP: Complete Troubleshooting Guide
Enable verbose logging with codebase-memory-mcp config set log_level debug, monitor ${CBM_CACHE_DIR}/logs/cbm-daemon.log for atomic timing counters, and use one-shot indexing with --verbose to isolate parsing failures without the background daemon.
Codebase-Memory-MCP is a pure-C knowledge-graph engine that persistently indexes repositories using Tree-Sitter parsers to build a queryable "code-memory" graph. When you need to debug issues in codebase-memory-mcp, you are typically tracing failures across three distinct layers: grammar parsing, AST extraction, or the coordination daemon. This guide provides the exact source file locations, configuration keys, and diagnostic commands required to pinpoint failures from the GraphQL UI down to the C implementation in DeusData/codebase-memory-mcp.
Understanding the Three-Layer Debugging Architecture
The debugging process maps directly to the engine's architecture. Each layer exposes specific entry points in the source tree:
- Parsing Layer – Uses vendored Tree-Sitter grammars in
internal/cbm/grammar_*.cto produce ASTs for 158 languages. Debug entry points includetree_sitter_*_language()definitions. - Extraction Layer – Walks ASTs to emit graph nodes and edges (
CALLS,IMPORTS). Inspectinternal/cbm/extract_*.c, particularlyextract_calls.candextract_defs.c. - Coordination Daemon – Background process
cbm-daemonthat watches files and serves the UI. Debug via daemon logs and the entry point ininternal/cbm/cbm.c(main()→cbm_server_start()).
Enable Verbose Logging for Real-Time Diagnostics
The fastest way to expose runtime behavior is through the built-in debug channel configured via the CLI.
codebase-memory-mcp config set log_level debug
This command updates the configuration (documented in docs/CONFIGURATION.md) and instructs the daemon to write detailed messages to ${CBM_CACHE_DIR}/logs/cbm-daemon.log. The log captures file-watch events, nanosecond timing counters (total_parse_ns, total_extract_ns), and atomic profiling data declared in internal/cbm/cbm.c.
To disable debug mode after troubleshooting:
codebase-memory-mcp config set log_level info
Inspect Daemon Logs and Atomic Counters
The daemon log exposes per-file performance metrics and initialization errors. Typical entries follow this structure:
[2026-07-26T12:34:56.123Z] INFO cbm-daemon: watching /my/project/src/main.c
[2026-07-26T12:35:01.456Z] DEBUG cbm-daemon: parse_time_ns=12345 extract_time_ns=6789 file=/my/project/src/main.c
- INFO lines indicate file-system watcher activity.
- DEBUG lines reveal
_Atomiccounter values fromcbm.c, showing exact parse and extract durations.
If the daemon fails to start, check the log for early-initialization warnings related to codebase-memory-mcp config set auto_index true conflicts or binary version mismatches stored in ${CBM_CACHE_DIR}/logs/daemon-conflicts.ndjson.
Run One-Shot Indexing for Isolated Testing
Bypass the daemon entirely to debug a single repository or file without background noise. The CLI mode prints debug lines directly to stdout.
codebase-memory-mcp index /path/to/repo --verbose
The --verbose flag streams the same metrics found in the daemon log, including nanosecond counters for each phase. This is essential when iterating on grammar fixes in internal/cbm/grammar_*.c because it avoids daemon restart overhead.
For granular testing after modifying extraction logic, target a single file:
codebase-memory-mcp index-file src/utils/helpers.c
This command uses the same extraction path as the daemon, so changes to extract_*.c reflect immediately without a full re-index.
Visual Debugging with the Built-In Graph UI
When the UI variant is installed, launch it to inspect graph topology visually:
codebase-memory-mcp --ui=true
Navigate to http://localhost:9749. The interface highlights nodes with failed edge resolution (e.g., missing CALLS relationships). Hovering over a node displays underlying AST node IDs, which you can cross-reference with source locations in internal/cbm/extract_calls.c. The front-end fetches data via hooks defined in graph-ui/src/hooks/useGraphData.ts, allowing you to verify if the backend is emitting the expected JSON-RPC payloads.
Debugging Language-Specific Extraction Failures
If a specific language produces incorrect or missing nodes, trace the pipeline through its grammar and extraction files.
- Locate the grammar definition in
internal/cbm/grammar_*.c(e.g.,grammar_c.cfor C,grammar_python.cfor Python). - Verify the
tree_sitter_*_language()function is registered in the build. - Insert temporary debug prints in the corresponding
extract_*.cfile to inspectTSNodetypes during traversal.
For example, to debug missing call edges in C code, modify internal/cbm/extract_calls.c:
static void extract_call_edge(CBMContext *ctx, TSNode node) {
const char *name = ts_node_string(node);
fprintf(stderr, "[debug] extract_call_edge: node=%s\n", name);
/* existing logic … */
}
Recompile and run codebase-memory-mcp index-file on a test case to see the raw AST node strings emitted to stderr.
Verify Graph Consistency with Diagnostic Commands
Use the built-in diagnostic suite to detect logical errors in the knowledge graph:
codebase-memory-mcp diagnose --check-orphans --check-cycles
This command scans for:
- Orphan nodes – Entities with no incoming
CALLSedges (potential dead code or extraction failures). - Cycles – Invalid circular dependencies in what should be a DAG-structured call graph.
The output lists specific node IDs that fail validation, allowing you to grep the extraction logs for the corresponding file paths.
Common Debugging Pitfalls and Solutions
| Symptom | Root Cause | Resolution |
|---|---|---|
| Missing nodes for a language | Grammar not compiled into the binary. | Re-run make to embed the Tree-Sitter grammar from internal/cbm/grammar_*.c, or add the missing language to the vendored/ directory. |
| Undefined edge types | extract_calls.c failed to emit a CALLS edge due to type-resolution failure. |
Add debug prints around extract_call_edge() and verify the TSNode resolves to a valid function identifier. |
| Daemon fails to start | Version conflict in ${CBM_CACHE_DIR} from a previous MCP process. |
Delete ${CBM_CACHE_DIR}/logs/daemon-conflicts.ndjson and restart. |
| Excessive parse time | Pathological grammar or large preprocessed files. | Enable incremental parsing: codebase-memory-mcp config set incremental true to reuse previous parse trees. |
Summary
- Enable debug logging via
codebase-memory-mcp config set log_level debugand monitor${CBM_CACHE_DIR}/logs/cbm-daemon.logfor_Atomiccounters. - Use one-shot indexing (
codebase-memory-mcp index --verbose) to test changes without daemon overhead. - Debug language parsers by inspecting
internal/cbm/grammar_*.cand inserting prints ininternal/cbm/extract_*.c. - Validate graph integrity with
codebase-memory-mcp diagnose --check-orphans --check-cycles. - Visualize failures at
http://localhost:9749when running with--ui=true.
Frequently Asked Questions
How do I enable debug logging in codebase-memory-mcp?
Run codebase-memory-mcp config set log_level debug to switch the daemon to verbose mode. This writes parse timings, file-watch events, and atomic counter values to ${CBM_CACHE_DIR}/logs/cbm-daemon.log. Refer to docs/CONFIGURATION.md for the full list of configuration keys.
Why does the cbm-daemon fail to start?
The daemon typically fails due to a version conflict lockfile in ${CBM_CACHE_DIR}/logs/daemon-conflicts.ndjson or corrupted auto-index state. Delete the conflicts file and clear the cache directory, then restart. Check the daemon log for specific initialization errors emitted from cbm_server_start() in internal/cbm/cbm.c.
How can I debug a specific language parser that is missing nodes?
First, confirm the grammar is vendored in internal/cbm/grammar_*.c (e.g., grammar_python.c). Then insert fprintf(stderr, ...) statements in the corresponding extract_*.c file (such as extract_defs.c) to print TSNode types and symbol names during AST traversal. Recompile and test with codebase-memory-mcp index-file on a source file from that language.
What causes missing CALLS edges in the extracted graph?
Missing edges usually indicate a failure in internal/cbm/extract_calls.c where extract_call_edge() could not resolve a function identifier from the TSNode. Enable --verbose indexing to see if the parser correctly identified the node type, then add debug prints to verify the symbol name is being extracted before the edge emission logic.
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 →