by drewdrewH
Builds a semantic graph of TypeScript codebases, enabling AI assistants to perform deep, cross‑file reasoning, impact analysis, and natural‑language queries.
Code Graph Context creates a rich code graph from TypeScript projects. It parses source files with ts‑morph, stores AST nodes and framework‑level semantics in Neo4j, and augments each node with vector embeddings (local or OpenAI). The resulting graph lets AI models answer natural‑language questions, run impact analysis, detect dead code, and coordinate multi‑agent refactorings.
npx -y code-graph-context (or install globally).code-graph-context init sets up a Neo4j Docker container, a Python side‑car for embeddings, and downloads the default embedding model.NEO4J_URI, OPENAI_ENABLED, etc.) can be added to ~/.claude.json or a project‑local .mcp.json.parse_typescript_project tool (or ask Claude “Parse this project”) to populate the graph.search_codebase, impact_analysis, traverse_from_node, or natural‑language‑to‑Cypher to retrieve information.swarm_post_task and let multiple agents coordinate via pheromones.impact_analysis before changing a function to see blast radius.Q: Do I need an OpenAI key?
A: No. The default setup uses a local embedding model via a Python side‑car. OpenAI can be enabled by setting OPENAI_ENABLED=true and providing an API key.
Q: How does the server start?
A: After init, the Neo4j container runs automatically. The MCP server itself is the code-graph-context CLI; it can be invoked via npx as shown in the serverConfig.
Q: Can I use this with frameworks other than NestJS? A: Yes. The parser is config‑driven; you can supply custom schema files to recognize React, Angular, or any domain‑specific patterns.
Q: What happens if I change the embedding model? A: Vector dimensions change, so you must drop existing indexes and re‑parse the project with the new model configured.
Q: Is it safe for large monorepos? A: The tool supports streaming import, parallel workers, and incremental updates, making it suitable for codebases with thousands of files.
Give your AI coding assistant a photographic memory of your codebase.
Code Graph Context is an MCP server that builds a semantic graph of your TypeScript codebase, enabling Claude to understand not just individual files, but how your entire system fits together.
Config-Driven & Extensible: Define custom framework schemas to capture domain-specific patterns beyond the included NestJS support. The parser is fully configurable to recognize your architectural patterns, decorators, and relationships.
┌─────────────────────────────────────────────────────────────┐
│ YOUR CODEBASE │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Service │ │Controller│ │ Module │ │ Entity │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
└───────┼─────────────┼─────────────┼─────────────┼──────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ CODE GRAPH CONTEXT │
│ │
│ AST Parser ──► Neo4j Graph ──► Vector Embeddings │
│ (ts-morph) (Relationships) (Local or OpenAI) │
│ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ CLAUDE CODE │
│ │
│ "What services depend on UserService?" │
│ "What's the blast radius if I change this function?" │
│ "Find all HTTP endpoints that accept a UserDTO" │
│ "Refactor this across all 47 files that use it" │
│ │
└─────────────────────────────────────────────────────────────┘
| Without Code Graph | With Code Graph |
|---|---|
| Claude reads files one at a time | Claude understands the entire dependency tree |
| "What uses this?" requires manual searching | Instant impact analysis with risk scoring |
| Refactoring misses edge cases | Graph traversal finds every reference |
| Large codebases overwhelm context | Semantic search finds exactly what's relevant |
| Multi-file changes are error-prone | Swarm agents coordinate parallel changes |
TypeScript Source → AST Parser (ts-morph) → Neo4j Graph + Vector Embeddings → MCP Tools
Core Components:
src/core/parsers/typescript-parser.ts - AST parsing with ts-morphsrc/storage/neo4j/neo4j.service.ts - Graph storage and queriessrc/core/embeddings/embeddings.service.ts - Embedding service (local sidecar or OpenAI)src/mcp/mcp.server.ts - MCP server and tool registrationDual-Schema System:
Nodes have both coreType (AST) and semanticType (framework meaning), enabling queries like "find all controllers" while maintaining AST precision.
No API keys required. Local embeddings work out of the box using a Python sidecar.
npm install -g code-graph-context
code-graph-context init # Sets up Neo4j + Python sidecar + downloads embedding model
The init command handles everything:
claude mcp add --scope user code-graph-context -- code-graph-context
That's it. No API keys needed. Restart Claude Code and you're ready to go.
Want to use OpenAI instead? See Embedding Configuration below.
In Claude Code, say:
"Parse this project and build the code graph"
Claude will run parse_typescript_project and index your codebase.
Claude Code stores MCP server configs in JSON files. The location depends on scope:
| Scope | File | Use Case |
|---|---|---|
| User (global) | ~/.claude.json |
Available in all projects |
| Project | .claude.json in project root |
Project-specific config |
| Local | .mcp.json in project root |
Git-ignored local overrides |
If you prefer to edit the config files directly:
~/.claude.json (user scope - recommended):
{
"mcpServers": {
"code-graph-context": {
"command": "code-graph-context"
}
}
}
With OpenAI (optional):
{
"mcpServers": {
"code-graph-context": {
"command": "code-graph-context",
"env": {
"OPENAI_ENABLED": "true",
"OPENAI_API_KEY": "sk-your-key-here"
}
}
}
}
From source installation:
{
"mcpServers": {
"code-graph-context": {
"command": "node",
"args": ["/absolute/path/to/code-graph-context/dist/cli/cli.js"]
}
}
}
| Variable | Required | Default | Description |
|---|---|---|---|
NEO4J_URI |
No | bolt://localhost:7687 |
Neo4j connection URI |
NEO4J_USER |
No | neo4j |
Neo4j username |
NEO4J_PASSWORD |
No | PASSWORD |
Neo4j password |
EMBEDDING_MODEL |
No | Qwen/Qwen3-Embedding-0.6B |
Local embedding model (see Embedding Configuration) |
EMBEDDING_SIDECAR_PORT |
No | 8787 |
Port for local embedding server |
EMBEDDING_DEVICE |
No | cpu |
Device for embeddings (cpu or mps). CPU is default to avoid MPS memory bloat |
EMBEDDING_HALF_PRECISION |
No | false |
Set true for float16 (uses ~0.5x memory) |
OPENAI_ENABLED |
No | false |
Set true to use OpenAI instead of local |
OPENAI_API_KEY |
No* | - | Required when OPENAI_ENABLED=true |
Find code by describing what you need, not by memorizing file paths:
"Find where user authentication tokens are validated"
"Show me the database connection pooling logic"
"What handles webhook signature verification?"
Before you refactor, understand the blast radius:
┌─────────────────────────────────────────────────────────────┐
│ Impact Analysis: UserService.findById() │
├─────────────────────────────────────────────────────────────┤
│ Risk Level: HIGH │
│ │
│ Direct Dependents (12): │
│ └── AuthController.login() │
│ └── ProfileController.getProfile() │
│ └── AdminService.getUserDetails() │
│ └── ... 9 more │
│ │
│ Transitive Dependents (34): │
│ └── 8 controllers, 15 services, 11 tests │
│ │
│ Affected Files: 23 │
│ Recommendation: Add deprecation warning before changing │
└─────────────────────────────────────────────────────────────┘
Explore relationships in any direction:
UserController
│
├── INJECTS ──► UserService
│ │
│ ├── INJECTS ──► UserRepository
│ │ │
│ │ └── MANAGES ──► User (Entity)
│ │
│ └── INJECTS ──► CacheService
│
└── EXPOSES ──► POST /users
│
└── ACCEPTS ──► CreateUserDTO
Find code that can be safely removed:
Dead Code Analysis: 47 items found
├── HIGH confidence (23): Exported but never imported
│ └── formatLegacyDate() in src/utils/date.ts:45
│ └── UserV1DTO in src/dto/legacy/user.dto.ts:12
│ └── ... 21 more
├── MEDIUM confidence (18): Private, never called
└── LOW confidence (6): May be used dynamically
Identify DRY violations across your codebase:
Duplicate Groups Found: 8
Group 1 (Structural - 100% identical):
├── validateEmail() in src/auth/validation.ts:23
└── validateEmail() in src/user/validation.ts:45
Recommendation: Extract to shared utils
Group 2 (Semantic - 94% similar):
├── parseUserInput() in src/api/parser.ts:78
└── sanitizeInput() in src/webhook/parser.ts:34
Recommendation: Review for consolidation
Execute complex, multi-file changes with parallel AI agents.
The swarm system enables multiple Claude agents to work on your codebase simultaneously, coordinating through the code graph without stepping on each other.
┌──────────────────┐
│ ORCHESTRATOR │
│ │
│ "Add JSDoc to │
│ all services" │
└────────┬─────────┘
│
┌─────────────┼─────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Worker 1 │ │ Worker 2 │ │ Worker 3 │
│ │ │ │ │ │
│ Claiming │ │ Working │ │ Claiming │
│ AuthSvc │ │ UserSvc │ │ PaySvc │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└─────────────┼─────────────┘
│
▼
┌─────────────────────────────┐
│ PHEROMONE TRAILS │
│ │
│ AuthService: [claimed] │
│ UserService: [modifying] │
│ PayService: [claimed] │
│ CacheService: [available] │
│ │
└─────────────────────────────┘
Agents leave markers on code nodes that decay over time—like ants leaving scent trails:
| Pheromone | Half-Life | Meaning |
|---|---|---|
exploring |
2 min | "I'm looking at this" |
claiming |
1 hour | "This is my territory" |
modifying |
10 min | "I'm actively changing this" |
completed |
24 hours | "I finished work here" |
warning |
Never | "Don't touch this" |
blocked |
5 min | "I'm stuck" |
Self-healing: If an agent crashes, its pheromones decay and the work becomes available again.
Explicit task management with dependencies:
┌─────────────────────────────────────────────────────────────┐
│ TASK QUEUE │
├─────────────────────────────────────────────────────────────┤
│ [available] Add JSDoc to UserService priority: high │
│ [claimed] Add JSDoc to AuthService agent: worker1 │
│ [blocked] Update API docs ─────────────────► depends on ──┤
│ [in_progress] Add JSDoc to PaymentService agent: worker2 │
│ [completed] Add JSDoc to CacheService ✓ │
└─────────────────────────────────────────────────────────────┘
| Tool | Purpose |
|---|---|
swarm_post_task |
Add a task to the queue |
swarm_get_tasks |
Query tasks with filters |
swarm_claim_task |
Claim/start/release a task |
swarm_complete_task |
Complete/fail/request review |
swarm_pheromone |
Leave a marker on a code node |
swarm_sense |
Query what other agents are doing |
swarm_cleanup |
Remove pheromones after completion |
// Orchestrator decomposes the task and creates individual work items
swarm_post_task({
projectId: "backend",
swarmId: "swarm_rename_user",
title: "Update UserService.findUserById",
description: "Rename getUserById to findUserById in UserService",
type: "refactor",
createdBy: "orchestrator"
})
// Workers claim and execute tasks
swarm_claim_task({ projectId: "backend", swarmId: "swarm_rename_user", agentId: "worker_1" })
// ... do work ...
swarm_complete_task({ taskId: "task_1", agentId: "worker_1", action: "complete", summary: "Renamed method" })
For optimal swarm execution, install the included Claude Code skill that teaches agents the coordination protocol:
# Copy to your global skills directory
mkdir -p ~/.claude/skills
cp -r skills/swarm ~/.claude/skills/
Or for a specific project:
cp -r skills/swarm .claude/skills/
The skill provides:
Once installed, just say "swarm" or "parallel agents" and Claude will use the skill automatically.
See skills/swarm/SKILL.md for the full documentation.
| Tool | Description |
|---|---|
| Discovery | |
list_projects |
List parsed projects in the database |
search_codebase |
Semantic search using vector embeddings |
traverse_from_node |
Explore relationships from a node |
natural_language_to_cypher |
Convert questions to Cypher queries |
| Analysis | |
impact_analysis |
Assess refactoring risk (LOW/MEDIUM/HIGH/CRITICAL) |
detect_dead_code |
Find unreferenced exports and methods |
detect_duplicate_code |
Find structural and semantic duplicates |
| Parsing | |
parse_typescript_project |
Build the graph from source |
check_parse_status |
Monitor async parsing jobs |
start_watch_project |
Auto-update graph on file changes |
stop_watch_project |
Stop file watching |
list_watchers |
List active file watchers |
| Swarm | |
swarm_post_task |
Add task to the queue |
swarm_get_tasks |
Query tasks |
swarm_claim_task |
Claim/start/release tasks |
swarm_complete_task |
Complete/fail/review tasks |
swarm_pheromone |
Leave coordination markers |
swarm_sense |
Query what others are doing |
swarm_cleanup |
Clean up after swarm completion |
| Utility | |
test_neo4j_connection |
Verify database connectivity |
Pattern 1: Discovery → Focus → Deep Dive
list_projects → search_codebase → traverse_from_node → traverse (with skip for pagination)
Pattern 2: Pre-Refactoring Safety
search_codebase("function to change") → impact_analysis(nodeId) → review risk level
Pattern 3: Code Health Audit
detect_dead_code → detect_duplicate_code → prioritize cleanup
Pattern 4: Multi-Agent Work
swarm_post_task → swarm_claim_task → swarm_complete_task → swarm_get_tasks(includeStats) → swarm_cleanup
All query tools require projectId for isolation. You can use:
proj_a1b2c3d4e5f6 (auto-generated)my-backend (from package.json)/path/to/project (resolved automatically)// These all work:
search_codebase({ projectId: "my-backend", query: "auth" })
search_codebase({ projectId: "proj_a1b2c3d4e5f6", query: "auth" })
search_codebase({ projectId: "/path/to/my-backend", query: "auth" })
Deep understanding of NestJS patterns:
@Controller, @Get, @Post, etc.)@Injectable)@Module)@IsString, @IsEmail, etc.)NestJS-Specific Relationships:
INJECTS - Dependency injectionEXPOSES - Controller exposes HTTP endpointMODULE_IMPORTS, MODULE_PROVIDES, MODULE_EXPORTS - Module systemGUARDED_BY, TRANSFORMED_BY, INTERCEPTED_BY - MiddlewareThe parser is config-driven. Define your own framework patterns:
// Example: Custom React schema
const REACT_SCHEMA = {
name: 'react',
decoratorPatterns: [
{ pattern: /^use[A-Z]/, semanticType: 'ReactHook' },
{ pattern: /^with[A-Z]/, semanticType: 'HOC' },
],
nodeTypes: [
{ coreType: 'FunctionDeclaration', condition: (node) => node.name?.endsWith('Provider'), semanticType: 'ContextProvider' },
],
relationships: [
{ type: 'PROVIDES_CONTEXT', from: 'ContextProvider', to: 'ReactHook' },
]
};
The dual-schema system means every node has:
coreType: AST-level (ClassDeclaration, FunctionDeclaration)semanticType: Framework meaning (NestController, ReactHook)This enables queries like "find all hooks that use context" while maintaining AST precision for refactoring.
Local embeddings are the default — no API key needed. The Python sidecar starts automatically on first use and runs a local model for high-quality code embeddings.
The sidecar runs on CPU by default to avoid MPS memory pool bloat on Apple Silicon (MPS can pre-allocate 10+ GB even for small models). CPU is fast enough for models under 1B params. It also auto-shuts down after 3 minutes of inactivity to free memory, and restarts lazily when needed (~15-20s).
GPU acceleration: Set
EMBEDDING_DEVICE=mpsto use Apple Silicon GPU for larger models (1B+ params). Only recommended on machines with 32+ GB RAM.Half precision: Set
EMBEDDING_HALF_PRECISION=trueto load the model in float16, roughly halving memory usage.
Set via the EMBEDDING_MODEL environment variable:
| Model | Dimensions | RAM (fp16) | Quality | Best For |
|---|---|---|---|---|
Qwen/Qwen3-Embedding-0.6B (default) |
1024 | ~1.2 GB | Best | Default, code-aware, MTEB-Code #1 |
Qodo/Qodo-Embed-1-1.5B |
1536 | ~4.5 GB | Great | Machines with 32+ GB RAM |
BAAI/bge-base-en-v1.5 |
768 | ~250 MB | Good | General purpose, low RAM |
sentence-transformers/all-MiniLM-L6-v2 |
384 | ~100 MB | OK | Minimal RAM, fast |
nomic-ai/nomic-embed-text-v1.5 |
768 | ~300 MB | Good | Code + prose mixed |
sentence-transformers/all-mpnet-base-v2 |
768 | ~250 MB | Good | Balanced quality/speed |
BAAI/bge-small-en-v1.5 |
384 | ~65 MB | OK | Smallest footprint |
Example: Use a lightweight model on a low-memory machine:
claude mcp add --scope user code-graph-context \
-e EMBEDDING_MODEL=BAAI/bge-base-en-v1.5 \
-- code-graph-context
Switching models requires re-parsing — vector index dimensions are locked per model. Drop existing indexes first:
DROP INDEX embedded_nodes_idx IF EXISTS;
DROP INDEX session_notes_idx IF EXISTS;
Then re-parse your project with the new model configured.
If you prefer OpenAI embeddings (higher quality, requires API key):
claude mcp add --scope user code-graph-context \
-e OPENAI_ENABLED=true \
-e OPENAI_API_KEY=sk-your-key-here \
-- code-graph-context
# Check the server is registered
claude mcp list
# Verify Neo4j is running
docker ps | grep neo4j
# Test manually
code-graph-context status
"Failed to generate embedding" — The local sidecar may not have started. Check:
# Verify Python deps are installed
code-graph-context status
# Re-run init to fix sidecar setup
code-graph-context init
Out of memory (large model on 16GB machine) — Switch to a lighter model:
claude mcp add --scope user code-graph-context \
-e EMBEDDING_MODEL=BAAI/bge-base-en-v1.5 \
-- code-graph-context
Using OpenAI and getting auth errors — Ensure your key is configured:
claude mcp remove code-graph-context
claude mcp add --scope user code-graph-context \
-e OPENAI_ENABLED=true \
-e OPENAI_API_KEY=sk-your-key-here \
-- code-graph-context
For large codebases, increase memory limits:
# Stop and recreate with more memory
code-graph-context stop
code-graph-context init --memory 4G
Use async mode for large projects:
parse_typescript_project({
projectPath: "/path/to/project",
tsconfigPath: "/path/to/project/tsconfig.json",
async: true // Returns immediately, poll with check_parse_status
})
code-graph-context init [options] # Set up Neo4j + Python sidecar + embedding model
code-graph-context status # Check Docker/Neo4j/sidecar status
code-graph-context stop # Stop Neo4j container
Init options:
-p, --port <port> - Bolt port (default: 7687)--http-port <port> - Browser port (default: 7474)--password <password> - Neo4j password (default: PASSWORD)-m, --memory <size> - Heap memory (default: 2G)-f, --force - Recreate containergit clone https://github.com/drewdrewH/code-graph-context.git
cd code-graph-context
npm install
npm run build
npm run dev # Watch mode
Conventional Commits: feat|fix|docs|refactor(scope): description
MIT - see LICENSE
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by modelcontextprotocol
A Model Context Protocol server for Git repository interaction and automation.
by zed-industries
A high‑performance, multiplayer code editor designed for speed and collaboration.
by modelcontextprotocol
Model Context Protocol Servers
by modelcontextprotocol
A Model Context Protocol server that provides time and timezone conversion capabilities.
by cline
An autonomous coding assistant that can create and edit files, execute terminal commands, and interact with a browser directly from your IDE, operating step‑by‑step with explicit user permission.
by upstash
Provides up-to-date, version‑specific library documentation and code examples directly inside LLM prompts, eliminating outdated information and hallucinated APIs.
by daytonaio
Provides a secure, elastic infrastructure that creates isolated sandboxes for running AI‑generated code with sub‑90 ms startup, unlimited persistence, and OCI/Docker compatibility.
by continuedev
Enables faster shipping of code by integrating continuous AI agents across IDEs, terminals, and CI pipelines, offering chat, edit, autocomplete, and customizable agent workflows.
by github
Connects AI tools directly to GitHub, enabling natural‑language interactions for repository browsing, issue and pull‑request management, CI/CD monitoring, code‑security analysis, and team collaboration.
{
"mcpServers": {
"code-graph-context": {
"command": "npx",
"args": [
"-y",
"code-graph-context"
],
"env": {}
}
}
}claude mcp add code-graph-context npx -y code-graph-context