codebase-memory-mcp-pro-knowledge-graph
Community fork of codebase-memory-mcp with incremental-reindex fixes — pure-C knowledge-graph MCP server for AI code exploration
How do I install this agent skill?
npx skills add https://github.com/reason-machines/mcp-skills --skill codebase-memory-mcp-pro-knowledge-graphIs this agent skill safe to install?
- Gen Agent Trust Hubfail
The skill provides instructions to download and execute code from an unverified third-party GitHub repository. This involves running build scripts and installing binaries locally, which poses a significant risk of remote code execution if the source repository is compromised or malicious.
- Socketpass
No alerts
- Snykwarn
Risk: MEDIUM · 1 issue
What does this agent skill do?
codebase-memory-mcp-pro Knowledge Graph
Skill by ara.so — MCP Skills collection.
Overview
codebase-memory-mcp-pro is a community fork of DeusData/codebase-memory-mcp that provides a pure-C knowledge graph MCP server for AI code exploration. It indexes codebases using tree-sitter AST analysis across 158 languages, building a persistent graph of functions, classes, call chains, and cross-file references.
Key improvements in this fork:
- Incremental-reindex correctness — preserves inbound cross-file
CALLSedges; editing a file no longer orphans calls into its symbols - Enhanced
exploretool — single-call blast-radius analysis with callers, neighbors, inline hotspot flags, and line-numbered source - Swift type fidelity —
struct/enum/actorare distinct graph labels; enum cases extracted asEnumCasenodes - Cypher aggregation fix — non-aggregate functions mixed with aggregates now group correctly
detect_changesblast radius —depthparameter produces transitive caller impact analysis
The fork ships no prebuilt binaries — you build from source to get all integrated fixes.
Installation
Build from Source
# Clone the fork
git clone https://github.com/win4r/codebase-memory-mcp-pro.git
cd codebase-memory-mcp-pro
# Build (first build compiles 158 tree-sitter grammars — takes a few minutes)
./scripts/build.sh
# → build/c/codebase-memory-mcp (reports version: dev)
# Install to PATH
cp build/c/codebase-memory-mcp ~/.local/bin/
# Add as stdio MCP server (available in all projects)
claude mcp add codebase-memory -s user -- ~/.local/bin/codebase-memory-mcp
Iterative rebuilds (much faster after first build):
make -j -f Makefile.cbm cbm
Verify Integration
Confirm the integrated fixes are live:
# Index a repository
codebase-memory-mcp cli index_repository '{"repo_path":"/path/to/repo"}'
# Test PR #465 — node properties survive WITH aggregation
codebase-memory-mcp cli query_graph '{
"project": "<name>",
"query": "MATCH (a)-[:CALLS]->(b) WITH b, count(a) AS c RETURN b.file_path, c LIMIT 1"
}'
# Non-empty file_path means you're running the cherry-picked build
⚠️ Do not run codebase-memory-mcp update — it pulls upstream and overwrites the integrated build. Use ./scripts/build.sh to update instead.
Core MCP Tools
The server exposes 15 MCP tools. Key tools in this fork:
explore (Fork Enhancement)
One-call blast-radius analysis — returns callers, neighbors, and line-numbered source:
// AI agent invocation
{
"name": "explore",
"arguments": {
"project": "my-project",
"symbol_name": "processOrder",
"include_source": true,
"max_callers": 20,
"max_neighbors": 10
}
}
Returns:
- Blast radius: attributed callers + inline fan-in hotspot flags
- Neighbors: 1-hop callees + same-file siblings
- Source: verbatim line-numbered code grouped by file
- Cypher escape-hatch: optional
cypher_queryparameter for custom graph traversal
index_repository
Build the knowledge graph:
{
"name": "index_repository",
"arguments": {
"repo_path": "/path/to/repo",
"project_name": "my-project" // optional, defaults to dir name
}
}
Incremental re-index (fork fix: preserves cross-file CALLS edges):
# Edit files, then re-run index_repository
# Inbound calls to edited symbols are preserved
query_graph
Execute Cypher queries against the knowledge graph:
{
"name": "query_graph",
"arguments": {
"project": "my-project",
"query": "MATCH (f:Function)-[:CALLS]->(g:Function) WHERE f.file_path =~ '.*service.*' RETURN f.name, g.name, g.file_path LIMIT 10"
}
}
Common patterns:
// Find all callers of a function
MATCH (caller)-[:CALLS]->(target:Function)
WHERE target.name = 'processPayment'
RETURN caller.name, caller.file_path
// Functions with most callers (hotspots)
MATCH (caller)-[:CALLS]->(target)
WITH target, count(caller) AS fan_in
WHERE fan_in > 5
RETURN target.name, target.file_path, fan_in
ORDER BY fan_in DESC
// Call chain between two symbols
MATCH path = shortestPath(
(a:Function {name: 'handleRequest'})-[:CALLS*..10]->(b:Function {name: 'saveToDatabase'})
)
RETURN [n in nodes(path) | n.name] AS call_chain
// Dead code detection (no inbound calls)
MATCH (f:Function)
WHERE NOT ()-[:CALLS]->(f)
AND f.visibility = 'public'
RETURN f.name, f.file_path
// Swift enum cases (fork feature)
MATCH (e:Enum)-[:CONTAINS]->(case:EnumCase)
WHERE e.name = 'AppError'
RETURN case.name, case.line_start
Fork fix: Aggregations now group correctly:
// This returns one row per edge type (not collapsed into one row)
MATCH (a)-[r]->(b)
RETURN type(r), count(*) AS edge_count
detect_changes
Detect modified files and impacted symbols:
{
"name": "detect_changes",
"arguments": {
"project": "my-project",
"since": "HEAD~5", // fork fix: honors since parameter
"depth": 2 // fork feature: transitive caller blast radius
}
}
Fork enhancement: depth parameter produces transitive caller blast radius:
impacted_symbolsincludes callers up todepthhops- Each symbol tagged with
hop(0 = changed, 1+ = caller) andtransitiveflag impacted_countdeduplicated across hops
Example response:
{
"changed_files": ["src/payment/processor.ts"],
"impacted_symbols": [
{
"name": "processPayment",
"file_path": "src/payment/processor.ts",
"hop": 0,
"transitive": false
},
{
"name": "handleCheckout",
"file_path": "src/checkout/handler.ts",
"hop": 1,
"transitive": true
},
{
"name": "completeOrder",
"file_path": "src/order/service.ts",
"hop": 2,
"transitive": true
}
],
"impacted_count": 12
}
trace_path
Find call paths between two symbols:
{
"name": "trace_path",
"arguments": {
"project": "my-project",
"from_symbol": "handleRequest",
"to_symbol": "saveToDatabase",
"max_depth": 10
}
}
get_code_snippet
Retrieve source code with line numbers:
{
"name": "get_code_snippet",
"arguments": {
"project": "my-project",
"file_path": "src/utils/validator.ts",
"start_line": 45,
"end_line": 60
}
}
Fork fix: Returns valid UTF-8 (handles non-UTF-8 source files gracefully).
Swift Enhancements (Fork)
Distinct Type Labels
Stock upstream lumps Swift struct/enum/actor as Class. This fork emits distinct labels:
// Find all Swift structs
MATCH (s:Struct)
WHERE s.file_path =~ '.*\\.swift$'
RETURN s.name, s.file_path
// Find all actors
MATCH (a:Actor)
RETURN a.name
// Enum with cases
MATCH (e:Enum)-[:CONTAINS]->(case:EnumCase)
WHERE e.name = 'NetworkError'
RETURN case.name
Enum Case Extraction
Enum cases (including multi-name case a, b, c lines) are extracted as EnumCase nodes:
// Source
enum Status {
case pending, processing // Multi-name case
case completed(Date)
case failed(Error)
}
// Query
MATCH (e:Enum {name: 'Status'})-[:CONTAINS]->(case:EnumCase)
RETURN case.name
// Returns: pending, processing, completed, failed
Static Method Dedup Fix
Fork fix: An enum's static func is no longer double-emitted as both Method and Function nodes.
CLI Usage
The binary supports both MCP stdio mode (for agents) and direct CLI invocation:
# MCP stdio mode (agent communication)
codebase-memory-mcp
# Direct CLI tool invocation
codebase-memory-mcp cli <tool_name> '<json_args>'
# Examples
codebase-memory-mcp cli index_repository '{"repo_path": "/path/to/repo"}'
codebase-memory-mcp cli query_graph '{
"project": "my-project",
"query": "MATCH (f:Function) RETURN f.name LIMIT 5"
}'
codebase-memory-mcp cli explore '{
"project": "my-project",
"symbol_name": "parseConfig",
"include_source": true
}'
Configuration
MCP Server Configuration
Add to ~/.config/claude/claude_desktop_config.json (or agent-specific config):
{
"mcpServers": {
"codebase-memory": {
"command": "/home/user/.local/bin/codebase-memory-mcp",
"args": [],
"env": {}
}
}
}
Environment Variables
# Optional: custom database location
export CBM_DB_PATH=/path/to/custom/db
# Optional: log level (debug, info, warn, error)
export CBM_LOG_LEVEL=info
Project-Specific Configuration
Create .codebase-memory.json in repository root:
{
"exclude_paths": [
"node_modules",
"vendor",
"build",
"dist",
".git",
"*.test.ts"
],
"include_extensions": [
".ts", ".tsx", ".js", ".jsx",
".py", ".go", ".rs", ".c", ".cpp", ".swift"
],
"max_file_size_kb": 1024
}
Real-World Patterns
Pattern 1: Impact Analysis Before Refactoring
// 1. Find the function
const exploreResult = await explore({
project: "my-api",
symbol_name: "validateUser",
include_source: true,
max_callers: 50
});
// 2. Check blast radius
const callerCount = exploreResult.callers.length;
const hasHighFanIn = callerCount > 10;
// 3. Query transitive impact
const impactResult = await query_graph({
project: "my-api",
query: `
MATCH (caller)-[:CALLS*1..3]->(target:Function)
WHERE target.name = 'validateUser'
RETURN DISTINCT caller.name, caller.file_path
`
});
// 4. Make informed decision
if (hasHighFanIn) {
// High-risk refactor: write comprehensive tests first
} else {
// Low-risk: proceed with confidence
}
Pattern 2: Dead Code Detection
// Find public functions with no callers
const deadCode = await query_graph({
project: "my-api",
query: `
MATCH (f:Function)
WHERE NOT ()-[:CALLS]->(f)
AND f.visibility = 'public'
AND f.file_path =~ '.*src/.*'
RETURN f.name, f.file_path, f.line_start
ORDER BY f.file_path
`
});
// Cross-reference with exports
const exports = await query_graph({
project: "my-api",
query: `
MATCH (m:Module)-[:EXPORTS]->(f)
RETURN f.name, m.file_path
`
});
// Candidates for deletion: deadCode NOT IN exports
Pattern 3: Incremental Re-index Workflow
#!/bin/bash
# safe-refactor.sh
# 1. Index current state
codebase-memory-mcp cli index_repository '{"repo_path": "."}'
# 2. Snapshot call graph
codebase-memory-mcp cli query_graph '{
"project": "my-api",
"query": "MATCH (a)-[:CALLS]->(b {name: \"targetFunc\"}) RETURN a.name, a.file_path"
}' > before.json
# 3. Make changes
vim src/core/target.ts
# 4. Re-index (fork: preserves inbound CALLS edges)
codebase-memory-mcp cli index_repository '{"repo_path": "."}'
# 5. Verify call graph integrity
codebase-memory-mcp cli query_graph '{
"project": "my-api",
"query": "MATCH (a)-[:CALLS]->(b {name: \"targetFunc\"}) RETURN a.name, a.file_path"
}' > after.json
# 6. Compare
diff before.json after.json
Pattern 4: Architecture Documentation
// Generate module dependency graph
const modules = await query_graph({
project: "my-api",
query: `
MATCH (m1:Module)-[:IMPORTS]->(m2:Module)
RETURN m1.file_path AS from, m2.file_path AS to
`
});
// Detect circular dependencies
const cycles = await query_graph({
project: "my-api",
query: `
MATCH path = (m:Module)-[:IMPORTS*2..10]->(m)
RETURN [n in nodes(path) | n.file_path] AS cycle
LIMIT 10
`
});
// Find architectural layers (no upward imports)
const layers = await query_graph({
project: "my-api",
query: `
MATCH (m:Module)
WHERE m.file_path =~ '.*/domain/.*'
AND NOT (m)-[:IMPORTS]->(:Module {file_path: ~'.*/infrastructure/.*'})
RETURN m.file_path AS clean_domain_module
`
});
Troubleshooting
Issue: "No such project"
Cause: Project not indexed or wrong name.
# List indexed projects
codebase-memory-mcp cli query_graph '{
"project": "any",
"query": "MATCH (p:Project) RETURN p.name"
}'
# Re-index with explicit name
codebase-memory-mcp cli index_repository '{
"repo_path": "/path/to/repo",
"project_name": "exact-name"
}'
Issue: Incremental re-index loses edges (upstream bug)
Solution: You're running stock upstream, not the fork. Rebuild from source:
cd codebase-memory-mcp-pro
./scripts/build.sh
cp build/c/codebase-memory-mcp ~/.local/bin/
Verify integration:
codebase-memory-mcp cli query_graph '{
"project": "test",
"query": "MATCH (a)-[:CALLS]->(b) WITH b, count(a) AS c RETURN b.file_path, c LIMIT 1"
}'
# Non-empty file_path = fork build
Issue: Cypher query returns unexpected single row
Cause: Aggregation bug in upstream (fixed in fork).
// This should return one row per edge type
MATCH (a)-[r]->(b)
RETURN type(r), count(*)
// Upstream: collapses into single row
// Fork: groups correctly by type(r)
Rebuild from fork source if you're seeing this.
Issue: Swift enums/structs labeled as Class
Solution: Fork emits distinct labels. Query with specific types:
// Fork
MATCH (s:Struct) RETURN s.name
// Upstream workaround (not recommended)
MATCH (s:Class)
WHERE s.kind = 'struct' // Property may not exist
RETURN s.name
Issue: Build fails on macOS with libgit2 ≥ 1.8
Solution: Already fixed in fork (PR #512 integrated). If still failing:
brew info libgit2 # Check version
# Ensure you're building from fork, not upstream
git remote -v # Should show win4r/codebase-memory-mcp-pro
./scripts/build.sh
Issue: UTF-8 errors in get_code_snippet
Solution: Fixed in fork (PR #526). Rebuild from source.
Issue: detect_changes ignores since parameter
Solution: Fixed in fork (PR #464). Rebuild from source.
Advanced: Custom Cypher Patterns
Find HTTP Route Handlers
MATCH (route:Route)-[:HANDLED_BY]->(handler:Function)
WHERE route.method = 'POST'
RETURN route.path, handler.name, handler.file_path
ORDER BY route.path
Cross-Service Call Analysis
MATCH (caller:Function)-[:HTTP_CALL]->(route:Route)
WHERE caller.file_path =~ '.*service-a/.*'
AND route.service = 'service-b'
RETURN caller.name, route.path, route.method
Complexity Analysis
MATCH (f:Function)
WHERE f.cyclomatic_complexity > 10
RETURN f.name, f.file_path, f.cyclomatic_complexity
ORDER BY f.cyclomatic_complexity DESC
LIMIT 20
Ownership Mapping (by directory)
MATCH (f:Function)
WITH split(f.file_path, '/')[0..3] AS module, count(f) AS function_count
RETURN module, function_count
ORDER BY function_count DESC
Integration with AI Agents
Claude Code / Cursor
// ~/.config/claude/claude_desktop_config.json
{
"mcpServers": {
"codebase-memory": {
"command": "/home/user/.local/bin/codebase-memory-mcp"
}
}
}
Aider
# .aider.conf.yml
mcp:
servers:
- name: codebase-memory
command: /home/user/.local/bin/codebase-memory-mcp
Generic MCP Client
import { MCPClient } from '@modelcontextprotocol/sdk';
const client = new MCPClient({
command: '/home/user/.local/bin/codebase-memory-mcp',
args: []
});
await client.connect();
const result = await client.callTool('explore', {
project: 'my-api',
symbol_name: 'processOrder'
});
console.log(result);
Performance Notes
- Linux kernel (28M LOC, 75K files): 3 minutes to index
- Average repository: milliseconds
- Graph queries: <1ms for simple patterns, <100ms for complex traversals
- Memory: RAM-first pipeline with LZ4 compression; memory released after indexing
Contributing to the Fork
This is a community fork tracking upstream. To contribute:
- Upstream PRs first: Submit fixes to DeusData/codebase-memory-mcp
- Fork-specific enhancements: Submit PRs to win4r/codebase-memory-mcp-pro
- Integration requests: Open an issue if an upstream PR should be cherry-picked into the fork
License
MIT License (unchanged from upstream). See LICENSE.
All credit for the original engine: DeusData. This fork exists to integrate fixes faster than upstream merge cycles.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/reason-machines/mcp-skills/codebase-memory-mcp-pro-knowledge-graph">View codebase-memory-mcp-pro-knowledge-graph on skillZs</a>