How to Debug Indexing Issues and Capture Performance Diagnostics in Codebase-Memory-MCP
Enable MCP_LOG=debug and MCP_INDEXER_LOG=trace to capture verbose output, set MCP_METRICS=1 to write performance data to CSV, and query the HTTP endpoints /status and /coverage for real-time diagnostics.
The Codebase-Memory-MCP system builds a cross-language codebase graph by orchestrating a native indexer subprocess and persisting results in SQLite. When you need to debug indexing issues or capture diagnostics for performance problems, the project provides built-in instrumentation via environment variables, CLI flags, and a live HTTP diagnostics interface.
Diagnostic Architecture Overview
The system collects diagnostics through several coordinated components:
MCP CLI Entry Point (src/mcp/mcp.c): The main driver parses arguments, spawns the native indexer, and orchestrates the pipeline. It handles --log-level flags and writes the metrics.csv and coverage reports.
Index Supervisor (src/mcp/index_supervisor.c): This component supervises the indexer subprocess, restarting it on crash and forwarding the child’s stdout/stderr to the parent process.
HTTP Diagnostics Server (src/ui/http_server.c): Implements REST endpoints including /status, /metrics, and /coverage that expose live indexing state and historical data.
Enabling Verbose Logging
CLI and Supervisor Logs
Set the MCP_LOG environment variable to debug or pass --log-level=debug to see the full command line passed to the indexer and high-level progress messages. In src/mcp/mcp.c, the argument parser routes these flags to the logging subsystem.
MCP_LOG=debug ./mcp index /path/to/repo
Indexer Process Tracing
To capture the native indexer’s internal operations—including every file it opens, language detection events, and parse errors—set MCP_INDEXER_LOG=trace. The supervisor in src/mcp/index_supervisor.c forwards the child’s output to the parent’s stdout.
MCP_INDEXER_LOG=trace ./mcp index /path/to/repo
Capturing Performance Metrics
Enable MCP_METRICS=1 to flush timing and memory statistics to a CSV file after each run. You can also use --metrics-file=<path> to specify a custom location. The metrics struct in src/mcp/mcp.c accumulates wall-clock time, CPU usage, and bytes read across phases.
MCP_METRICS=1 ./mcp index /path/to/repo --metrics-file=./run-metrics.csv
The resulting CSV includes columns such as discover_ms, parse_ms, db_write_ms, and memory_used, matching the format found in scripts/soak-ql-mac-fixed/metrics.csv. Analyze this file to identify bottlenecks in the discovery, parsing, or database write phases.
Analyzing Coverage Reports and Missed Files
After indexing, MCP generates a coverage CSV listing files the indexer could not fully process, such as binary files, parse errors, or symlink loops. This file is written to the coverage/ directory by default. In src/mcp/mcp.c, the code path that adds a "missed-graph skeleton" populates these entries with reasons for partial coverage.
When a file cannot be fully indexed, the system creates a missed-graph node recorded in the coverage data. The React UI component in graph-ui/src/components/GraphTab.tsx visualizes these as a "Missed skeleton" cluster, helping you spot patterns like large generated headers or unsupported language constructs.
Query the coverage data via the HTTP UI:
curl http://localhost:8080/coverage | head
Live HTTP Diagnostics
Start the HTTP server with --http-port=<port> to expose real-time endpoints:
./mcp serve --http-port=8080
Available endpoints:
/status: Returns JSON withindexedProjects,indexingInProgress, andindexingFailedfields, corresponding to the UI strings defined ingraph-ui/src/lib/i18n.ts./metrics: Exposes current performance counters./coverage: Returns the coverage CSV data.
Query the status endpoint for a quick health check:
curl http://localhost:8080/status | jq .
Step-by-Step Debugging Workflow
Follow this sequence to diagnose indexing failures or performance degradation:
- Enable verbose logging: Run with
MCP_LOG=debug MCP_INDEXER_LOG=traceto see the exact commands and file operations. - Capture metrics: Set
MCP_METRICS=1and specify a metrics file to record per-phase timings. - Inspect coverage: Check the generated CSV under
coverage/or via/coverageto identifyparse_partialentries. - Query HTTP status: Start the server with
--http-portand monitor/statusfor real-time state. - Visualize missed files: Open the React UI and examine the "Missed skeleton" panel rendered by
GraphTab.tsxto identify file patterns causing issues.
Common Pitfalls and Solutions
Indexer exits with code 137: This indicates an out-of-memory (OOM) error while parsing a huge file. Check metrics.csv for a spike in memory_used and consider adjusting the MCP_MAX_FILE_SIZE limit defined in src/foundation/limits.h.
Many parse_partial entries in coverage: Files contain syntax errors or unsupported language constructs. Review the specific paths in the coverage CSV and verify if the language front-end is registered in the CBM grammar table under internal/cbm/vendored/grammars/.
UI shows "Indexing failed" without details: The indexer process terminated unexpectedly. Enable MCP_INDEXER_LOG=trace to see the stderr output, and check the supervisor’s restart logic in src/mcp/index_supervisor.c.
Unexpectedly slow performance: Excessive symlink traversal or redundant re-parsing of unchanged files. Verify that the incremental pipeline in src/pipeline/pipeline_incremental.c is skipping unchanged files correctly, and ensure the timestamp cache is not being cleared on each run.
Summary
- Enable
MCP_LOG=debugfor CLI verbosity andMCP_INDEXER_LOG=tracefor indexer subprocess details. - Set
MCP_METRICS=1to generate performance CSVs with per-phase timing and memory usage fromsrc/mcp/mcp.c. - Inspect coverage CSVs to find partially indexed files and visualize them in the UI via the missed-graph skeleton.
- Use
--http-portto expose/status,/metrics, and/coverageendpoints for real-time monitoring. - Check exit code 137 in metrics data to diagnose OOM errors, and verify incremental indexing logic in
src/pipeline/pipeline_incremental.cfor performance issues.
Frequently Asked Questions
How do I enable debug logging for the MCP indexer?
Set the environment variable MCP_LOG=debug or pass the --log-level=debug flag when running the index command. This outputs high-level progress messages and the exact command line passed to the indexer subprocess. For deeper tracing of the native indexer itself, add MCP_INDEXER_LOG=trace, which the supervisor in src/mcp/index_supervisor.c forwards from the child process.
What does exit code 137 indicate when running the indexer?
Exit code 137 indicates the process was killed by the system, typically due to an out-of-memory (OOM) error while parsing a large file. Examine the memory_used column in your metrics CSV to confirm a spike, and consider reducing the MCP_MAX_FILE_SIZE value in src/foundation/limits.h or increasing available system memory.
Where can I find the performance metrics after an indexing run?
When you set MCP_METRICS=1, the system writes a CSV file to the path specified by --metrics-file (or a default location). This file, structured like scripts/soak-ql-mac-fixed/metrics.csv, contains columns for discover_ms, parse_ms, db_write_ms, and memory_used, allowing you to pinpoint which phase of indexing consumes the most resources.
How do I view which files were only partially indexed?
Partially indexed files appear in the coverage CSV generated under the coverage/ directory. These entries are created in src/mcp/mcp.c when the indexer cannot fully process a file. You can view this data via the /coverage HTTP endpoint or visualize it in the React UI under the "Missed skeleton" cluster handled by graph-ui/src/components/GraphTab.tsx.
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 →