# CodeGraph ### Supercharge Claude Code, Cursor, Codex, and OpenCode with Semantic Code Intelligence **~35% cheaper · ~70% fewer tool calls · 100% local** [![npm version](https://img.shields.io/npm/v/@colbymchenry/codegraph.svg)](https://www.npmjs.com/package/@colbymchenry/codegraph) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Self-contained](https://img.shields.io/badge/Node.js-bundled%20%C2%B7%20none%20required-brightgreen.svg)](https://nodejs.org/) [![Windows](https://img.shields.io/badge/Windows-supported-blue.svg)](#) [![macOS](https://img.shields.io/badge/macOS-supported-blue.svg)](#) [![Linux](https://img.shields.io/badge/Linux-supported-blue.svg)](#) [![Claude Code](https://img.shields.io/badge/Claude_Code-supported-blueviolet.svg)](#) [![Cursor](https://img.shields.io/badge/Cursor-supported-blueviolet.svg)](#) [![Codex CLI](https://img.shields.io/badge/Codex_CLI-supported-blueviolet.svg)](#) [![opencode](https://img.shields.io/badge/opencode-supported-blueviolet.svg)](#)
### Get Started **No Node.js required** — one command grabs the right build for your OS: ```bash # macOS / Linux curl -fsSL https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.sh | sh # Windows (PowerShell) irm https://raw.githubusercontent.com/colbymchenry/codegraph/main/install.ps1 | iex ``` Already have Node? Use npm instead (works on any version): ```bash npx @colbymchenry/codegraph # zero-install, or: npm i -g @colbymchenry/codegraph ``` CodeGraph bundles its own runtime — nothing to compile, no native build, works the same everywhere.
The interactive installer auto-configures your agent(s) — Claude Code, Cursor, Codex CLI, opencode.
#### Initialize Projects ```bash cd your-project codegraph init -i ``` ![1_C_VYnhpys0UHrOuOgpgoyw](https://github.com/user-attachments/assets/f168182f-4d9a-44e0-94d7-08d018cc8a3a)
--- ## Why CodeGraph? When Claude Code explores a codebase, it spawns **Explore agents** that scan files with grep, glob, and Read — consuming tokens on every tool call. **CodeGraph gives those agents a pre-indexed knowledge graph** — symbol relationships, call graphs, and code structure. Agents query the graph instantly instead of scanning files. ### Benchmark Results Tested across **7 real-world open-source codebases** spanning 7 languages, comparing an agent (Claude Code, headless) answering one architecture question **with** and **without** CodeGraph. Each cell is the savings at the **median of 4 runs per arm**. > **Average: 35% cheaper · 59% fewer tokens · 49% faster · 70% fewer tool calls** | Codebase | Language | Cost | Tokens | Time | Tool calls | |----------|----------|------|--------|------|------------| | **VS Code** | TypeScript · ~10k files | 35% cheaper | 73% fewer | 41% faster | 72% fewer | | **Excalidraw** | TypeScript · ~600 | 47% cheaper | 73% fewer | 60% faster | 86% fewer | | **Django** | Python · ~2.7k | 34% cheaper | 64% fewer | 59% faster | 81% fewer | | **Tokio** | Rust · ~700 | 52% cheaper | 81% fewer | 63% faster | 89% fewer | | **OkHttp** | Java · ~640 | 17% cheaper | 41% fewer | 36% faster | 64% fewer | | **Gin** | Go · ~150 | 22% cheaper | 23% fewer | 34% faster | 19% fewer | | **Alamofire** | Swift · ~100 | 38% cheaper | 59% fewer | 51% faster | 77% fewer | The gains scale with codebase size: on large repos the agent answers from the index in a handful of calls with **zero file reads**, while the no-CodeGraph agent fans out across grep/find/Read (and the sub-agents it spawns). On a small repo like Gin (~150 files) native search is already cheap, so the margin narrows.
Full benchmark details **Methodology.** Each arm is `claude -p` (Claude Opus 4.7, Claude Code v2.1.145) run headlessly against the repo with `--strict-mcp-config`: **WITH** = CodeGraph's MCP server enabled, **WITHOUT** = an empty MCP config. Built-in Read/Grep/Bash stay available to both. Same question per repo, **4 runs per arm, median reported**. Cost = the run's `total_cost_usd`; Tokens = total tokens processed (input incl. cached + output); Time = wall-clock; Tool calls = every tool invocation, including those inside any sub-agents the model spawns. Repos cloned at `--depth 1` and indexed by the same CodeGraph build that served them. **Queries:** | Codebase | Query | |----------|-------| | VS Code | "How does the extension host communicate with the main process?" | | Excalidraw | "How does Excalidraw render and update canvas elements?" | | Django | "How does Django's ORM build and execute a query from a QuerySet?" | | Tokio | "How does tokio schedule and run async tasks on its runtime?" | | OkHttp | "How does OkHttp process a request through its interceptor chain?" | | Gin | "How does gin route requests through its middleware chain?" | | Alamofire | "How does Alamofire build, send, and validate a request?" | **Raw medians — WITH → WITHOUT:** | Codebase | Cost | Tokens | Time | Tool calls | |----------|------|--------|------|------------| | VS Code | $0.42 → $0.64 | 393k → 1.4M | 1m 0s → 1m 43s | 7 → 23 | | Excalidraw | $0.54 → $1.02 | 851k → 3.2M | 1m 17s → 3m 14s | 12 → 83 | | Django | $0.41 → $0.62 | 499k → 1.4M | 1m 0s → 2m 25s | 9 → 48 | | Tokio | $0.50 → $1.04 | 657k → 3.4M | 1m 5s → 2m 56s | 9 → 75 | | OkHttp | $0.36 → $0.44 | 352k → 596k | 45s → 1m 11s | 5 → 14 | | Gin | $0.36 → $0.46 | 431k → 562k | 47s → 1m 11s | 7 → 8 | | Alamofire | $0.61 → $0.99 | 1.1M → 2.6M | 1m 19s → 2m 41s | 15 → 64 | **Why CodeGraph wins:** with the index available, the agent answers directly — `codegraph_context` to map the area, then one `codegraph_explore` for the relevant source — and stops, usually with zero file reads. Without it, the agent (and the Explore sub-agents it spawns) spends most of its budget on discovery (find/ls/grep) before reading the right code. CodeGraph only helps when queried *directly*, so its instructions steer agents to answer directly rather than delegate exploration to file-reading sub-agents — otherwise a sub-agent reads files regardless and CodeGraph becomes overhead.
--- ## Key Features | | | |---|---| | **Smart Context Building** | One tool call returns entry points, related symbols, and code snippets — no expensive exploration agents | | **Full-Text Search** | Find code by name instantly across your entire codebase, powered by FTS5 | | **Impact Analysis** | Trace callers, callees, and the full impact radius of any symbol before making changes | | **Always Fresh** | File watcher uses native OS events (FSEvents/inotify/ReadDirectoryChangesW) with debounced auto-sync — the graph stays current as you code, zero config | | **19+ Languages** | TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, C, C++, Swift, Kotlin, Dart, Lua, Luau, Svelte, Liquid, Pascal/Delphi | | **Framework-aware Routes** | Recognizes web-framework routing files and links URL patterns to their handlers across 13 frameworks | | **100% Local** | No data leaves your machine. No API keys. No external services. SQLite database only | --- ## Framework-aware Routes CodeGraph detects web-framework routing files and emits `route` nodes linked by `references` edges to their handler classes or functions. Querying callers of a view/controller now surfaces the URL pattern that binds it. | Framework | Shapes recognized | |---|---| | **Django** | `path()`, `re_path()`, `url()`, `include()` in `urls.py` (CBV `.as_view()`, dotted paths) | | **Flask** | `@app.route('/path', methods=[...])`, blueprint routes | | **FastAPI** | `@app.get(...)`, `@router.post(...)`, all standard methods | | **Express** | `app.get(...)`, `router.post(...)` with middleware chains | | **NestJS** | `@Controller` + `@Get/@Post/...`, GraphQL `@Resolver` + `@Query/@Mutation`, `@MessagePattern`/`@EventPattern`, `@SubscribeMessage` | | **Laravel** | `Route::get()`, `Route::resource()`, `Controller@action`, tuple syntax | | **Rails** | `get '/x', to: 'users#index'`, hash-rocket `=>` syntax | | **Spring** | `@GetMapping`, `@PostMapping`, `@RequestMapping` on methods | | **Gin / chi / gorilla / mux** | `r.GET(...)`, `router.HandleFunc(...)` | | **Axum / actix / Rocket** | `.route("/x", get(handler))` | | **ASP.NET** | `[HttpGet("/x")]` attributes on action methods | | **Vapor** | `app.get("x", use: handler)` | | **React Router** / **SvelteKit** | Route component nodes | --- ## Quick Start ### 1. Run the Installer ```bash npx @colbymchenry/codegraph ``` The installer will: - Ask which agent(s) to configure — auto-detects installed ones from: **Claude Code**, **Cursor**, **Codex CLI**, **opencode** - Prompt to install `codegraph` on your PATH (so agents can launch the MCP server) - Ask whether configs apply to all your projects or just this one - Write each chosen agent's MCP server config + an instructions file (e.g. `CLAUDE.md`, `.cursor/rules/codegraph.mdc`, `~/.codex/AGENTS.md`) - Set up auto-allow permissions when Claude Code is one of the targets - Initialize your current project (local installs only) **Non-interactive (scripting / CI):** ```bash codegraph install --yes # auto-detect agents, install global codegraph install --target=cursor,claude --yes # explicit target list codegraph install --target=auto --location=local # detected agents, project-local codegraph install --print-config codex # print snippet, no file writes ``` | Flag | Values | Default | |---|---|---| | `--target` | `auto`, `all`, `none`, or csv (`claude,cursor,...`) | prompt | | `--location` | `global`, `local` | prompt | | `--yes` | (boolean) | prompt every step | | `--no-permissions` | (boolean) skip Claude auto-allow list | permissions on | | `--print-config ` | dump snippet for one agent and exit | — | ### 2. Restart Your Agent Restart your agent (Claude Code / Cursor / Codex CLI / opencode) for the MCP server to load. ### 3. Initialize Projects ```bash cd your-project codegraph init -i ``` Builds the per-project knowledge graph index. Also wires up any project-local agent surfaces (e.g. Cursor's `.cursor/rules/codegraph.mdc`) so a single global `codegraph install` works in every project you open — no need to re-run the installer per project. That's it — your agent will use CodeGraph tools automatically when a `.codegraph/` directory exists.
Manual Setup (Alternative) **Install globally:** ```bash npm install -g @colbymchenry/codegraph ``` **Add to `~/.claude.json`:** ```json { "mcpServers": { "codegraph": { "type": "stdio", "command": "codegraph", "args": ["serve", "--mcp"] } } } ``` **Add to `~/.claude/settings.json` (optional, for auto-allow):** ```json { "permissions": { "allow": [ "mcp__codegraph__codegraph_search", "mcp__codegraph__codegraph_context", "mcp__codegraph__codegraph_callers", "mcp__codegraph__codegraph_callees", "mcp__codegraph__codegraph_impact", "mcp__codegraph__codegraph_node", "mcp__codegraph__codegraph_status", "mcp__codegraph__codegraph_files" ] } } ```
Global Instructions Reference The installer automatically adds these instructions to `~/.claude/CLAUDE.md`: ```markdown ## CodeGraph CodeGraph builds a semantic knowledge graph of codebases for faster, smarter code exploration. ### If `.codegraph/` exists in the project **NEVER call `codegraph_explore` or `codegraph_context` directly in the main session.** These tools return large amounts of source code that fills up main session context. Instead, ALWAYS spawn an Explore agent for any exploration question (e.g., "how does X work?", "explain the Y system", "where is Z implemented?"). **When spawning Explore agents**, include this instruction in the prompt: > This project has CodeGraph initialized (.codegraph/ exists). Use `codegraph_explore` as your PRIMARY tool — it returns full source code sections from all relevant files in one call. > > **Rules:** > 1. Follow the explore call budget in the `codegraph_explore` tool description — it scales automatically based on project size. > 2. Do NOT re-read files that codegraph_explore already returned source code for. The source sections are complete and authoritative. > 3. Only fall back to grep/glob/read for files listed under "Additional relevant files" if you need more detail, or if codegraph returned no results. **The main session may only use these lightweight tools directly** (for targeted lookups before making edits, not for exploration): | Tool | Use For | |------|---------| | `codegraph_search` | Find symbols by name | | `codegraph_callers` / `codegraph_callees` | Trace call flow | | `codegraph_impact` | Check what's affected before editing | | `codegraph_node` | Get a single symbol's details | ### If `.codegraph/` does NOT exist At the start of a session, ask the user if they'd like to initialize CodeGraph: "I notice this project doesn't have CodeGraph initialized. Would you like me to run `codegraph init -i` to build a code knowledge graph?" ```
--- ## How It Works ``` ┌─────────────────────────────────────────────────────────────────┐ │ Claude Code │ │ │ │ "Implement user authentication" │ │ │ │ │ ▼ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ │ Explore Agent │ ──── │ Explore Agent │ │ │ └────────┬────────┘ └────────┬────────┘ │ │ │ │ │ └───────────┼────────────────────────┼─────────────────────────────┘ │ │ ▼ ▼ ┌───────────────────────────────────────────────────────────────────┐ │ CodeGraph MCP Server │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Search │ │ Callers │ │ Context │ │ │ │ "auth" │ │ "login()" │ │ for task │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ └────────────────┼────────────────┘ │ │ ▼ │ │ ┌───────────────────────┐ │ │ │ SQLite Graph DB │ │ │ │ • 387 symbols │ │ │ │ • 1,204 edges │ │ │ │ • Instant lookups │ │ │ └───────────────────────┘ │ └───────────────────────────────────────────────────────────────────┘ ``` 1. **Extraction** — [tree-sitter](https://tree-sitter.github.io/) parses source code into ASTs. Language-specific queries extract nodes (functions, classes, methods) and edges (calls, imports, extends, implements). 2. **Storage** — Everything goes into a local SQLite database (`.codegraph/codegraph.db`) with FTS5 full-text search. 3. **Resolution** — After extraction, references are resolved: function calls → definitions, imports → source files, class inheritance, and framework-specific patterns. 4. **Auto-Sync** — The MCP server watches your project using native OS file events. Changes are debounced (2-second quiet window), filtered to source files only, and incrementally synced. The graph stays fresh as you code — no configuration needed. --- ## CLI Reference ```bash codegraph # Run interactive installer codegraph install # Run installer (explicit) codegraph init [path] # Initialize in a project (--index to also index) codegraph uninit [path] # Remove CodeGraph from a project (--force to skip prompt) codegraph index [path] # Full index (--force to re-index, --quiet for less output) codegraph sync [path] # Incremental update codegraph status [path] # Show statistics codegraph query # Search symbols (--kind, --limit, --json) codegraph files [path] # Show file structure (--format, --filter, --max-depth, --json) codegraph context # Build context for AI (--format, --max-nodes) codegraph affected [files...] # Find test files affected by changes (see below) codegraph serve --mcp # Start MCP server ``` ### `codegraph affected` Traces import dependencies transitively to find which test files are affected by changed source files. ```bash codegraph affected src/utils.ts src/api.ts # Pass files as arguments git diff --name-only | codegraph affected --stdin # Pipe from git diff codegraph affected src/auth.ts --filter "e2e/*" # Custom test file pattern ``` | Option | Description | Default | |--------|-------------|---------| | `--stdin` | Read file list from stdin | `false` | | `-d, --depth ` | Max dependency traversal depth | `5` | | `-f, --filter ` | Custom glob to identify test files | auto-detect | | `-j, --json` | Output as JSON | `false` | | `-q, --quiet` | Output file paths only | `false` | **CI/hook example:** ```bash #!/usr/bin/env bash AFFECTED=$(git diff --name-only HEAD | codegraph affected --stdin --quiet) if [ -n "$AFFECTED" ]; then npx vitest run $AFFECTED fi ``` --- ## MCP Tools When running as an MCP server, CodeGraph exposes these tools to Claude Code: | Tool | Purpose | |------|---------| | `codegraph_search` | Find symbols by name across the codebase | | `codegraph_context` | Build relevant code context for a task | | `codegraph_callers` | Find what calls a function | | `codegraph_callees` | Find what a function calls | | `codegraph_impact` | Analyze what code is affected by changing a symbol | | `codegraph_node` | Get details about a specific symbol (optionally with source code) | | `codegraph_files` | Get indexed file structure (faster than filesystem scanning) | | `codegraph_status` | Check index health and statistics | --- ## Library Usage ```typescript import CodeGraph from '@colbymchenry/codegraph'; const cg = await CodeGraph.init('/path/to/project'); // Or: const cg = await CodeGraph.open('/path/to/project'); await cg.indexAll({ onProgress: (p) => console.log(`${p.phase}: ${p.current}/${p.total}`) }); const results = cg.searchNodes('UserService'); const callers = cg.getCallers(results[0].node.id); const context = await cg.buildContext('fix login bug', { maxNodes: 20, includeCode: true, format: 'markdown' }); const impact = cg.getImpactRadius(results[0].node.id, 2); cg.watch(); // auto-sync on file changes cg.unwatch(); // stop watching cg.close(); ``` --- ## Configuration The `.codegraph/config.json` file controls indexing: ```json { "version": 1, "languages": ["typescript", "javascript"], "exclude": ["node_modules/**", "dist/**", "build/**", "*.min.js"], "frameworks": [], "maxFileSize": 1048576, "extractDocstrings": true, "trackCallSites": true } ``` | Option | Description | Default | |--------|-------------|---------| | `languages` | Languages to index (auto-detected if empty) | `[]` | | `exclude` | Glob patterns to ignore | `["node_modules/**", ...]` | | `frameworks` | Framework hints for better resolution | `[]` | | `maxFileSize` | Skip files larger than this (bytes) | `1048576` (1MB) | | `extractDocstrings` | Extract docstrings from code | `true` | | `trackCallSites` | Track call site locations | `true` | ## Supported Languages | Language | Extension | Status | |----------|-----------|--------| | TypeScript | `.ts`, `.tsx` | Full support | | JavaScript | `.js`, `.jsx`, `.mjs` | Full support | | Python | `.py` | Full support | | Go | `.go` | Full support | | Rust | `.rs` | Full support | | Java | `.java` | Full support | | C# | `.cs` | Full support | | PHP | `.php` | Full support | | Ruby | `.rb` | Full support | | C | `.c`, `.h` | Full support | | C++ | `.cpp`, `.hpp`, `.cc` | Full support | | Swift | `.swift` | Full support | | Kotlin | `.kt`, `.kts` | Full support | | Scala | `.scala`, `.sc` | Full support (classes, traits, methods, type aliases, Scala 3 enums) | | Dart | `.dart` | Full support | | Svelte | `.svelte` | Full support (script extraction, Svelte 5 runes, SvelteKit routes) | | Vue | `.vue` | Full support (script + script-setup extraction, Nuxt page/API/middleware routes) | | Liquid | `.liquid` | Full support | | Pascal / Delphi | `.pas`, `.dpr`, `.dpk`, `.lpr` | Full support (classes, records, interfaces, enums, DFM/FMX form files) | | Lua | `.lua` | Full support (functions, methods with receivers, local variables, `require` imports, call edges) | | Luau | `.luau` | Full support (everything in Lua, plus `type`/`export type` aliases, typed signatures, and Roblox instance-path `require`) | ## Troubleshooting **"CodeGraph not initialized"** — Run `codegraph init` in your project directory first. **Indexing is slow** — Check that `node_modules` and other large directories are excluded. Use `--quiet` to reduce output overhead. **Indexing is slow, or MCP hits `database is locked`** — both trace to the SQLite backend. `codegraph` picks the best available, in order: native `better-sqlite3` (fastest; an `optionalDependencies` native module), then Node's built-in `node:sqlite` (Node ≥ 22.5), then a bundled WASM build. Run `codegraph status` and read the **`Backend:`** and **`Journal:`** lines: - `Backend: native` or `node:sqlite` with `Journal: wal` — fast path with lock-free concurrent reads; nothing to do. - `Backend: wasm` — the native module didn't load *and* `node:sqlite` is unavailable (Node < 22.5). WASM is 5-10x slower and has no WAL, so heavy concurrent use can briefly hit `database is locked`. The simplest fix is Node ≥ 22.5 (you get `node:sqlite` automatically); otherwise restore the native backend: ```bash # macOS xcode-select --install # installs the C compiler # Linux (Debian / Ubuntu) sudo apt install build-essential python3 make # Linux (RHEL / Fedora) sudo yum groupinstall "Development Tools" # Then rebuild on any platform: npm rebuild better-sqlite3 # Or force-include as a hard dep: npm install better-sqlite3 --save ``` After the fix, `codegraph status` should show `Backend: native`. - `Journal:` shows anything other than `wal` on a `native` / `node:sqlite` backend — WAL couldn't be enabled on this filesystem (common on network shares and WSL2 `/mnt`), so reads can block on writes. Move the project (with its `.codegraph/` folder) onto a local disk. **MCP server not connecting** — Ensure the project is initialized/indexed, verify the path in your MCP config, and check that `codegraph serve --mcp` works from the command line. **Missing symbols** — The MCP server auto-syncs on save (wait a couple seconds). Run `codegraph sync` manually if needed. Check that the file's language is supported and isn't excluded by config patterns. ## Star History Star History Chart ## License MIT ---
**Made for AI coding agents — Claude Code, Cursor, Codex CLI, and opencode** [Report Bug](https://github.com/colbymchenry/codegraph/issues) · [Request Feature](https://github.com/colbymchenry/codegraph/issues)