- name
- codebase-memory-mcp-pro-knowledge-graph
- description
- Community fork of codebase-memory-mcp with incremental-reindex fixes — pure-C knowledge-graph MCP server for AI code exploration
- triggers
- ["index this codebase","build a knowledge graph of this project","find all callers of this function","trace the call path between these symbols","query the code graph with Cypher","explore the blast radius of this change","detect changes since last commit","show me the architecture of this module"]
# codebase-memory-mcp-pro Knowledge Graph
> Skill by [ara.so](https://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 `CALLS` edges; editing a file no longer orphans calls into its symbols
- **Enhanced `explore` tool** — single-call blast-radius analysis with callers, neighbors, inline hotspot flags, and line-numbered source
- **Swift type fidelity** — `struct`/`enum`/`actor` are distinct graph labels; enum cases extracted as `EnumCase` nodes
- **Cypher aggregation fix** — non-aggregate functions mixed with aggregates now group correctly
- **`detect_changes` blast radius** — `depth` parameter produces transitive caller impact analysis
The fork ships **no prebuilt binaries** — you build from source to get all integrated fixes.
## Installation
### Build from Source
```bash
# 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):
```bash
make -j -f Makefile.cbm cbm
```
### Verify Integration
Confirm the integrated fixes are live:
```bash
# 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:
```typescript
// 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_query` parameter for custom graph traversal
### `index_repository`
Build the knowledge graph:
```typescript
{
"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):
```bash
# Edit files, then re-run index_repository
# Inbound calls to edited symbols are preserved
```
### `query_graph`
Execute Cypher queries against the knowledge graph:
```typescript
{
"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:**
```cypher
// 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:
```cypher
// 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:
```typescript
{
"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_symbols` includes callers up to `depth` hops
- Each symbol tagged with `hop` (0 = changed, 1+ = caller) and `transitive` flag
- `impacted_count` deduplicated across hops
Example response:
```json
{
"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:
```typescript
{
"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:
```typescript
{
"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:
```cypher
// 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:
```swift
// Source
enum Status {
case pending, processing // Multi-name case
case completed(Date)
case failed(Error)
}
```
```cypher
// 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:
```bash
# 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):
```json
{
"mcpServers": {
"codebase-memory": {
"command": "/home/user/.local/bin/codebase-memory-mcp",
"args": [],
"env": {}
}
}
}
```
### Environment Variables
```bash
# 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:
```json
{
"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
```typescript
// 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
```typescript
// 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
`
Voir sur GitHub