___ _ _
/ __\___ __| | ___ __ _ _ __ __ _ _ __ | |__
/ / / _ \ / _` |/ _ \/ _` | '__/ _` | '_ \| '_ \
/ /__| (_) | (_| | __/ (_| | | | (_| | |_) | | | |
Local code graph index for AI coding assistants.
Parses your repo into a graph of files, functions, classes, Terraform resources, and Markdown documentation -- then exposes it as an MCP server so Claude Code, Cursor, Codex, and Gemini can do symbol-level lookups instead of reading entire files.
Result: 60-90% fewer tokens on typical navigation tasks.
Python 3.11, 3.12, 3.13, or 3.14. Since v0.4.2 Kuzu is an optional
extra (pip install cgh[kuzu]), so the default install no longer pulls a
package that lacks cp3.14 wheels. The DuckDB backend ships wheels on every
supported Python and is the default everywhere. Existing Kuzu repos are
auto-migrated to DuckDB on the next cgh init. Use CGH_DB=kuzu (with
the extra installed) to keep using Kuzu if you have a reason to.
The install scripts detect your environment (macOS, Linux, WSL, Git Bash, or
native Windows), install cgh, and offer to add the cgh command to your PATH.
macOS, Linux, WSL, Git Bash (install.sh):
curl -fsSL https://raw.githubusercontent.com/altikva/cgh/main/install.sh | bashWindows PowerShell (install.ps1):
irm https://raw.githubusercontent.com/altikva/cgh/main/install.ps1 | iex# From PyPI (most users)
pip install cgh
# Isolated install that also handles PATH for you
pipx install cgh # or: uv tool install cgh
# From source (for development)
git clone https://github.com/altikva/cgh.git
cd cgh
uv pip install -e . # or: pip install -e .Optional extras (none are required; the core install is lean and works on Python 3.11 through 3.14):
pip install "cgh[langs]" # C# and Ruby parsers (tree-sitter grammars)
pip install "cgh[lsp]" # precise cross-file Python call resolution (jedi)
pip install "cgh[kuzu]" # the legacy Kuzu graph backend (DuckDB is the default)
# Combine extras in one bracket, comma-separated:
pip install "cgh[langs,lsp]"Quote the package spec ("cgh[...]") so zsh and bash do not try to glob the brackets. The same form works with pipx install, uv tool install, uv pip install, and from a source checkout: pip install -e ".[langs,lsp]".
cgh --version
cgh init # initialize in any project
cgh serve # start the MCP server for Claude / Cursor / Codex / Geminipip install drops the cgh executable in a Scripts directory that is not
always on PATH (common on Windows). Two fixes:
# Run it as a module, no PATH change needed
python -m cgh --version
# Or add the cgh command's directory to your PATH
python -m cgh ensurepathpipx install cgh and uv tool install cgh avoid this by managing PATH
themselves. The Python import name is still codegraph (e.g.
from codegraph.parsers import ...); only the CLI is named cgh, same
pattern as pip install pillow then import PIL.
# 1. Initialize (interactive wizard)
cgh init
# 2. Build the graph
cgh index
# 3. Check what was indexed
cgh stats
# 4. Start the MCP server for your AI tool
cgh serve --watch --reindexAI Assistant (Claude / Cursor / Codex / Gemini)
| symbol_lookup("process_data")
| search_docs("reconciliation")
| context_for_task("fix auth bug")
v
MCP server (codegraph) <-- stdio, no network
| SQL graph query + BM25 FTS
v
DuckDB graph DB (.codegraph/graph.duckdb) <-- embedded, file-based (default)
-- or Kuzu graph.db via CGH_DB=kuzu
SQLite FTS5 (.codegraph/fts.db) <-- BM25 full-text search
| indexed from
v
Your source files (.py / .ts / .tf / .md / .vue)
^
File watcher (watchdog) <-- live incremental updates on save
Instead of reading services.py (800 tokens) to find where verify_token is defined, your AI calls symbol_lookup("verify_token") and gets back:
{
"file": "src/auth/services.py",
"lines": "42-55",
"kind": "function",
"doc": "Verify a JWT token, raise on expiry."
}Then reads only lines 42-55.
All commands accept --root <DIR> to target a different project. The CLI is cgh; the Python import is codegraph (see Install above).
Interactive wizard that detects AI tools, installs MCP configs, and indexes the project.
cgh init
cgh init --yes # accept all defaults (non-interactive) ___ _ _
/ __\___ __| | ___ __ _ _ __ __ _ _ __ | |__
/ / / _ \ / _` |/ _ \/ _` | '__/ _` | '_ \| '_ \
/ /__| (_) | (_| | __/ (_| | | | (_| | |_) | | | |
\____/\___/ \__,_|\___|\__, |_| \__,_| .__/|_| |_|
|___/ |_|
Project: /home/user/my-project
Detecting AI tools...
> Claude Code detected
> Cursor detected
- Codex CLI not found
- Gemini CLI not found
? Install MCP server for: (space to toggle, enter to confirm)
[x] Claude Code (MCP server + hooks)
[x] Cursor (MCP server + hooks)
+ .mcp.json (MCP server)
+ .claude/settings.json (post-commit hook)
+ .cursor/mcp.json (MCP server)
Files to index:
python 142 files >>>>>>>>>>>>>>>>>>>>>>>>>>>>
typescript 8 files >>
terraform 12 files >>
markdown 23 files >>>>>
? Index 185 files now? Yes
...indexing...
+-----------------------+
| codegraph is ready! |
| |
| cgh stats |
| cgh search X |
| cgh serve |
| cgh parsers |
| cgh --help |
+-----------------------+
Build or rebuild the full code graph. Uses git ls-files for file discovery.
cgh index
cgh index --verbose Indexing (git ls-files) [################........] 142/185 api/handlers/donation_handler.py 3.2s
+--------------------+--------+
| Index Summary | |
+--------------------+--------+
| Files indexed | 185 |
| Files skipped | 3 |
| Errors | 0 |
| Elapsed | 4.1s |
| Method | git_ls |
+--------------------+--------+
Start the MCP server over stdio. This is the command AI tools invoke.
cgh serve --root . --watch --reindexFlags:
--watch-- enable live file watcher (watchdog, debounced)--reindex-- rebuild the graph before accepting connections
Generate integration files for a specific AI tool without the interactive wizard.
cgh setup claude
cgh setup cursor
cgh setup codex
cgh setup gemini
cgh setup allFuzzy search symbols (functions, classes, doc sections) by name.
cgh search "Handler"
cgh search "Handler" --limit 5
cgh search "Handler" --json Search: Handler
+------+----------------------------+-------------------------------+
| Type | Symbol | Location |
+------+----------------------------+-------------------------------+
| fn | DonationHandler | api/handlers/donation.py:12 |
| fn | ReceiptHandler | api/handlers/receipt.py:8 |
| cls | BaseHandler | api/handlers/base.py:15 |
| fn | PaymentHandler | api/handlers/payment.py:22 |
+------+----------------------------+-------------------------------+
Find the exact definition of a symbol.
cgh lookup verify_token fn verify_token api/middleware/auth.py:42-55
Show all functions that call a given function (tree view).
cgh callers verify_tokenverify_token is called by:
+-- get_current_user api/dependencies.py:18
+-- require_role api/middleware/auth.py:72
+-- portal_auth api/routers/portal.py:34
Show all functions that a given function calls (tree view).
cgh callees get_current_userget_current_user calls:
+-- verify_token api/middleware/auth.py:42
+-- load_user_by_id api/managers/user_manager.py:15
+-- build_current_user api/dependencies.py:30
Display the heading structure of a Markdown file as a tree.
cgh outline CLAUDE.md
cgh outline docs/ARCHITECTURE.mdCLAUDE.md
+-- ondonne-api -- FastAPI Backend L1
| +-- Project overview L5
| +-- Tech stack L30
| +-- Architecture -- 4-layer request flow L45
| | +-- Entity registration (factory pattern) L52
| +-- Provider architecture (plugin system) L60
| | +-- Mobile Money provider architecture L85
| | +-- Payment routing strategy L110
| +-- Multi-tenancy model L200
| +-- User roles & access control (RBAC) L215
Visualize the code graph in the browser as interactive Mermaid diagrams.
cgh graph # overview (default)
cgh graph imports # file import graph
cgh graph calls --symbol verify # call graph filtered to a symbol
cgh graph classes # class inheritance tree
cgh graph docs # documentation structure
cgh graph imports --file auth.py # imports for a specific file
cgh graph calls --mermaid # output raw Mermaid to stdout
cgh graph imports --html out.html # save to file instead of opening browser
cgh graph overview --max-nodes 20 # limit nodesScopes: overview, imports, calls, classes, docs, layers (layer-to-layer dependency diagram)
+--------------------------------------------+
| codegraph |
| |
| Opened in browser |
| File: /tmp/codegraph/codegraph-calls.html|
| Scope: calls |
| Nodes: 40 max |
+--------------------------------------------+
cgh graph layers --mermaid prints the layer-dependency diagram, which renders inline on GitHub:
graph TD
presentation["presentation"]:::layer
application["application"]:::layer
test["test"]:::layer
other["other"]:::layer
presentation -->|2| other
application -->|1| other
test -->|2| other
classDef layer fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
Display graph nodes, edges, MCP call stats, FTS index size, and storage.
cgh stats
cgh stats --json Graph Nodes
Type Count
File 185 ##########..........
Function 1,204 ####################
Class 85 ####................
TFResource 14 #...................
TFVar 9 ...................
MdSection 230 ########............
Total 1,727
Graph Edges
Relationship Count
CALLS 3,412
IMPORTS 892
DEFINES_FN 1,204
DEFINES_CLASS 85
INHERITS 47
HAS_METHOD 312
DEFINES_SECTION 230
MD_REFS_SYMBOL 89
Total 6,271
Index Info
FTS symbols 1,533
graph.duckdb 2.5 MB
fts.db 2.1 MB
call_log.db 48 KB
Total storage 4.7 MB
MCP Tool Calls
Tool Calls Avg ms Max ms Errors
context_for_task 42 18.3 45.2 0
symbol_lookup 38 2.1 8.4 0
search_symbols 15 3.5 12.1 0
fts_search 12 4.2 15.3 0
find_callers 8 1.8 4.2 0
Total 115 0
View MCP tool call history with latency and status.
cgh logs
cgh logs --tool symbol_lookup
cgh logs --errors
cgh logs --limit 10
cgh logs --json
cgh logs --clear Call Logs (last 10)
Time Tool Latency Size Args
2026-04-11 14:32:01 OK symbol_lookup 2.1ms 142B name=verify_token
2026-04-11 14:31:58 OK context_for_task 18ms 1,204B task=fix auth bug
2026-04-11 14:31:45 OK fts_search 4.2ms 892B query=donation handler
2026-04-11 14:30:12 ERR find_callers 1.2ms 0B fn_name=nonexistent
Show recent MCP activity grouped by day.
cgh history
cgh history --days 14 Activity -- Last 7 Day(s)
Date Calls Errors Top Tools
2026-04-11 42 0 context_for_task(18), symbol_lookup(12), fts_search(8)
2026-04-10 31 1 symbol_lookup(15), find_callers(8), search_docs(5)
2026-04-09 28 0 context_for_task(12), search_symbols(9), graph_stats(4)
Total: 101 calls, 1 errors across 3 day(s)
Show files changed since the last index, categorized by parseability.
cgh diff
cgh diff --since HEAD~3
cgh diff --since main Changed Files (parseable) since HEAD
File Language
api/routers/donations.py .py
api/handlers/receipt_handler.py .py
CLAUDE.md .md
+ 2 non-parseable changed file(s)
+----------------------------------------------+
| 3 parseable changed | 0 new unindexed | 2 other |
+----------------------------------------------+
Report the blast radius of changes since a git ref, for CI and PR bots. Diffs the changed files, then reports the symbols they define, what transitively imports them (grouped by role/layer), the endpoints touched, and the tests to run. Reads the graph read-only, so no MCP server needs to be running; keep the index fresh with cgh index in CI.
cgh impact --since HEAD~1 # human-readable summary
cgh impact --since main --format md # markdown for a PR comment
cgh impact --since main --json # machine-parseable on clean stdout## cgh impact (since `HEAD~1`)
**Changed files (1)**
- `api/models/donation.py`
**Impacted files (3)**
- application (1)
- `api/handlers/receipt_handler.py` `handler`
- presentation (1)
- `api/routers/donations.py` `router`
- test (1)
- `tests/test_receipt.py` `test`
**Endpoints touched (1)**
- `POST /donations` (api/routers/donations.py)
**Tests to run (1)**
- `tests/test_receipt.py`
List all registered language parsers.
cgh parsers Registered Parsers
Language Extensions Extracts Description
python .py functions, classes, imports Python source files (tree-sitter)
typescript .ts .tsx .js .mjs functions, classes, imports TypeScript/JavaScript (tree-sitter)
terraform .tf resources, variables, outputs Terraform HCL files
markdown .md .mdx sections, links, code_refs Markdown documentation
vue .vue functions, classes, imports Vue SFC files
Total: 9 file extensions supported
Health check that verifies all codegraph components are working.
cgh doctor Health Check
Component Status
.codegraph/ dir OK initialized
graph.duckdb OK accessible
fts.db OK accessible
call_log.db OK accessible
config.toml OK valid
parsers OK 5 parser(s) loaded
git OK found
.cghignore !! not found (optional)
MCP server OK ready
+-----------------------------+
| All 9 checks passed. |
+-----------------------------+
Vacuum SQLite databases and reclaim disk space.
cgh compact Compact Results
Database Before After Saved
fts.db 2.3 MB 2.1 MB -200 KB
call_log.db 52 KB 48 KB -4 KB
graph.duckdb 2.5 MB 2.5 MB --
+----------------------------------+
| Reclaimed: 204 KB |
+----------------------------------+
Index the repo then watch for file changes indefinitely.
cgh watch
cgh watch --verbose Initial index done -- 185 files in 4.1s
Watching for changes... (Ctrl-C to stop)
Manage extra directories included in the graph (multi-repo support).
cgh add-dir list # list configured extra dirs
cgh add-dir add ../frontend # add a directory
cgh add-dir add ../infra # add another
cgh add-dir remove ../frontend # remove a directory Extra directories:
OK ../ondonne-frontend (/home/user/ondonne-frontend)
OK ../ondonne-infra (/home/user/ondonne-infra)
Federate sub-repos that each have their own .codegraph/ index. The parent indexes only files outside any subrepo and queries fan out to each child's read-only DB at runtime. Each result is tagged with a scope field (parent or the child's name). See the Federation section for the full model.
cgh federate add ./apps/api ./apps/web # declare subrepos
cgh federate list # status table (status, owner, git, path)
cgh federate verify # exits 1 if any child is unhealthy
cgh federate up # spawn each child's own watcher
cgh federate down # stop them all
cgh federate remove ./apps/api # un-federate+------------------+--------+-----------+-----+------------------+
| subrepo | status | owner | git | path |
+------------------+--------+-----------+-----+------------------+
| ondonne-frontend | ok | up :54052 | yes | ./ondonne-frontend |
| ondonne-infra | ok | down | yes | ./ondonne-infra |
+------------------+--------+-----------+-----+------------------+
cgh init auto-detects nested .codegraph/ directories and offers to federate them on the spot.
Index files that are in .gitignore, bypassing all ignore rules. Requires confirmation.
cgh force-index build/output.py docs/generated/
cgh force-index build/output.py --yes # skip confirmation+-----------------------------------+
| Force Index |
| |
| build/output.py |
| docs/generated/ |
| |
| Bypasses .gitignore and |
| .git/info/exclude |
+-----------------------------------+
Continue? [y/N] y
Force-indexed 4 file(s)
When you work in a parent folder that holds several sub-projects, each with its own .git and its own .codegraph/ index, you don't want the parent to re-index everything. Per-child .gitignore semantics get lost, large trees (node_modules, vendor) get walked, duplicate work explodes. The federation model fixes this:
- The parent only indexes files outside any declared subrepo (its README, top-level configs, cross-repo docs).
- Each subrepo keeps its own
.codegraph/as the canonical index for its own code. - At MCP query time, the parent fans out read-only queries to each child's DB and aggregates results, tagging every hit with a
scopefield (parentor the child's basename).
# In each subrepo (one-time)
cd apps/api && cgh init && cgh index
# In the parent
cd ../..
cgh init # auto-detects nested .codegraph/, offers to federate
cgh federate add ./apps/api ./apps/web # (or declare manually)
cgh federate list # status + owner state per child
cgh index # parent indexes only its own files
cgh serve --background --watch # parent owner federates queries to children
cgh federate up # optional: spawn each child's own watcher so their indexes stay live| MCP tool | Behavior |
|---|---|
symbol_lookup, search_symbols, find_callers, find_callees |
Concat results, each tagged with scope |
imports_of, subgraph |
Concat. Cross-repo IMPORTS edges are NOT inferred (each scope's graph is canonical for its own files) |
pattern_search |
Runs ripgrep in each scope's tree |
fts_search |
Concat then sort by score (BM25 not renormalized across repos) |
search_docs, doc_outline, doc_refs |
Concat |
architecture_overview |
Returns {by_scope: {parent: {...}, child1: {...}}} when subrepos are present |
domain_map, endpoints |
Concat with per-result scope tag |
find_dead_code |
Per-scope analysis. A symbol "dead" in scope X may be called from scope Y. The response carries an explicit note field reminding you not to delete blindly. |
knowledge_*, memory_*, plan_*, all write-side tools (index, force_index, incremental_reindex, add_directory), and context_for_task stay parent-local. Each project keeps its own knowledge / memory / plans store.
If a child's DB is locked or unavailable (its own owner is mid-write, the child got deleted from disk), the response carries partial: true and warnings: [{scope, error}]. Results from other scopes still flow. Re-query in a moment if you need full coverage.
Owners are independent: the parent reads child DBs directly as files, it does NOT auto-spawn child owners. Use cgh federate up to ensure every child has its own watcher running, or accept that a child without a live owner may serve slightly stale data.
When running as an MCP server (cgh serve), codegraph exposes 47 tools.
| Tool | Description |
|---|---|
architecture_overview(max_files_per_role?) |
Compact map of all files grouped by layer (presentation/application/domain/infra/test/doc) and role (handler/router/component/store/…) with 1-line summaries: no Read needed |
domain_map(keyword, limit_per_role?) |
Every file whose path / role / module_doc mentions the keyword, grouped by role |
endpoints(path_pattern?, method?) |
List HTTP endpoints (FastAPI, Flask, Nuxt, Express, Django urls, NestJS, Spring, Gin/Echo) with their handlers: works cross-repo when extra_dirs is configured |
| Tool | Description |
|---|---|
symbol_lookup(name, role?, layer?) |
Find where a function, class, TF resource, or doc section is defined; optional role / layer filters |
find_callers(fn_name) |
Find all functions that call fn_name |
find_callees(fn_name) |
Find all functions that fn_name calls |
imports_of(file_path) |
List modules imported by a file |
search_symbols(query, limit?, role?, layer?) |
Fuzzy search across all symbol types; optional role / layer filters |
subgraph(file_path, depth?) |
Find files related within N import hops (blast radius) |
graph_stats() |
Node and edge counts per type |
| Tool | Description |
|---|---|
file_summary(file_path) |
One-shot orientation for a file: role/layer/lang, its functions and classes with line ranges, what it imports, and who imports it |
impact_of(symbol_or_file, max_depth?) |
Reverse blast radius: everything that transitively calls or imports the target, grouped by role/layer, with reaching endpoints |
path_between(src, dst, edge?) |
Shortest path between two symbols/files over CALLS or IMPORTS |
import_cycles(limit?) |
Detect import cycles (strongly-connected components) in the file import graph |
tests_for(symbol_or_file) |
Test files that exercise the target (inferred from imports/calls + role, not coverage) |
untested(role?, layer?) |
Source files that no test file imports |
hotspots(limit?) |
Change-risk ranking: git churn x import centrality x recency |
who_knows(file_path) |
Top authors of a file by commit count and recency (from git history) |
| Tool | Description |
|---|---|
search_docs(query, limit?) |
Search Markdown by heading title or body content |
doc_outline(file_path) |
Table of contents of a Markdown file |
doc_refs(symbol_name) |
Find all docs that reference a code symbol |
| Tool | Description |
|---|---|
fts_search(query, limit?, kind?) |
BM25-ranked full-text search over names + docstrings |
context_for_task(task, max_nodes?) |
Build ranked context from graph + FTS for any task |
find_dead_code(file_path?, include_private?) |
Find symbols with no incoming edges (potentially unused) |
| Tool | Description |
|---|---|
scan_repo(verbose?) |
Full re-index of the entire repo |
index_changed_files(since?) |
Re-index only files changed since a git ref |
force_index(paths, confirmed?) |
Index files bypassing .gitignore (requires confirmation) |
| Tool | Description |
|---|---|
visualize_graph(scope, file_path?, symbol_name?, max_nodes?, format?) |
Generate Mermaid or Graphviz diagrams |
| Tool | Description |
|---|---|
call_stats() |
MCP tool usage statistics (calls, latency, errors) |
live_graph_stats() |
Polling-friendly snapshot: node counts + FTS size + scan freshness + timestamp |
| Tool | Description |
|---|---|
scan_status() |
Is the graph in sync with git HEAD? Returns fresh, indexed_sha, behind_by, changed_files |
incremental_reindex() |
Surgical reindex: compares per-file git blob SHAs and touches only what actually changed since the last scan |
add_directory(path) |
Hot-add an external directory (sibling repo) to the graph: persists to config, scans, extends the watcher. No restart needed. |
codegraph supports any language through a plugin system. Adding a new language requires one file and zero configuration changes.
| Language | Parser | Extensions | Extracts |
|---|---|---|---|
| Python | tree-sitter | .py |
functions, classes, imports, calls, inheritance, docstrings |
| TypeScript | tree-sitter | .ts .tsx |
functions, classes, imports, calls, inheritance |
| JavaScript | tree-sitter | .js .mjs |
functions, classes, imports, calls |
| Vue | tree-sitter | .vue |
functions, classes, imports (SFC script block) |
| Go | tree-sitter | .go |
functions, methods, structs, interfaces, imports, calls |
| Rust | tree-sitter | .rs |
functions, structs, enums, traits, impl methods, use, calls |
| Java | tree-sitter | .java |
classes, interfaces, methods, constructors, imports, calls |
| Terraform | regex + brace tracker | .tf |
resources, variables, outputs, depends_on |
| Markdown | regex | .md .mdx |
headings, internal links, code symbol references |
| Config data | stdlib + PyYAML | .json .yaml .yml .toml |
top-level keys as sections (CI jobs, k8s kinds, compose services, package.json scripts, pyproject tables) |
| SQL | regex | .sql |
CREATE TABLE / ALTER TABLE as table sections with columns |
| C# (optional) | tree-sitter | .cs |
classes, interfaces, structs, enums, records, methods, usings, calls |
| Ruby (optional) | tree-sitter | .rb |
classes, modules, methods, requires, calls |
C# and Ruby ship in the optional langs extra (pip install cgh[langs]) so the core install stays lean and Python-3.14-safe. When the extra is absent, those file types are simply skipped.
- Create a file in
codegraph/parsers/(e.g.,rust.py) - Subclass
BaseParser - Decorate with
@register_parser - Done -- auto-discovered on import
from codegraph.parsers import register_parser
from codegraph.parsers.base import BaseParser, FileIndex, SymbolDef, ClassDef, ImportRef
@register_parser(".rs")
class RustParser(BaseParser):
lang = "rust"
extensions = [".rs"]
extracts = ["functions", "structs", "traits", "impls"]
description = "Rust source files"
tree_sitter_lang = "rust" # optional: auto-installs grammar
def parse(self, path: Path) -> FileIndex:
# Parse the file and return a FileIndex
...See docs/PARSERS.md for a complete walkthrough.
codegraph uses a layered config system. See docs/CONFIGURATION.md for all options.
- Hardcoded defaults
- Global:
~/.codegraph/config.toml - Project:
.codegraph/config.toml - Environment variables
- CLI flags
# .codegraph/config.toml
[codegraph]
ignore_dirs = [".git", "node_modules", "__pycache__", ".venv"]
ignore_patterns = ["*.min.js", "*.bundle.js"]
max_file_size_kb = 500
extra_dirs = ["../frontend"]
# precise_calls = true # resolve Python calls cross-file via jedi (needs cgh[lsp])
[parsers]
# enabled = ["python", "typescript", "markdown"]
# disabled = ["terraform"]
[mcp]
auto_watch = true
reindex_on_start = true| Variable | Description |
|---|---|
CODEGRAPH_ROOT |
Override project root |
CODEGRAPH_DIR |
Override .codegraph/ location |
CGH_DB |
Graph backend: duckdb (default) or kuzu |
CGH_PRECISE_CALLS |
1 to resolve Python calls cross-file via jedi (needs cgh[lsp]) |
Optional file at the project root. Same syntax as .gitignore. Patterns listed here are excluded from indexing in addition to .gitignore.
Add to .mcp.json (auto-generated by cgh init):
{
"mcpServers": {
"codegraph": {
"command": "codegraph",
"args": ["serve", "--root", ".", "--watch", "--reindex"],
"env": {
"CODEGRAPH_AUTH_KEY": "<auto-generated key from .codegraph/auth.key>"
}
}
}
}See integrations/claude-code.md for hooks setup and best practices.
Add to .cursor/mcp.json:
{
"mcpServers": {
"codegraph": {
"command": "codegraph",
"args": ["serve", "--root", ".", "--watch", "--reindex"],
"env": {
"CODEGRAPH_AUTH_KEY": "<auto-generated key from .codegraph/auth.key>"
}
}
}
}See integrations/cursor.md for .cursorrules instructions.
See integrations/codex.md for AGENTS.md instructions.
See integrations/gemini.md for GEMINI.md instructions.
cgh init # interactive: detects tools, installs configs
cgh setup all # non-interactive: generates all integration filesFile --IMPORTS-----------> File
File --DEFINES_FN--------> Function
File --DEFINES_CLASS-----> Class
File --DEFINES_RESOURCE--> TFResource
File --DEFINES_TFVAR-----> TFVar
File --DEFINES_SECTION---> MdSection
Function --CALLS---------> Function
Class --HAS_METHOD-------> Function
Class --INHERITS---------> Class
TFResource --TF_DEPENDS--> TFResource
MdSection --CONTAINS_SECTION--> MdSection (heading hierarchy)
MdSection --MD_LINKS_TO-------> File (internal doc links)
MdSection --MD_REFS_SYMBOL----> Function (code references in docs)
MdSection --MD_REFS_CLASS-----> Class (code references in docs)
| Task | Without codegraph | With codegraph |
|---|---|---|
Find where process_data is defined |
Read 3-5 files (~2,000 tokens) | symbol_lookup (< 50 tokens) |
Find all callers of save_record |
Read every candidate file | find_callers (< 50 tokens) |
Understand blast radius of utils.py |
Read imports manually | subgraph (< 100 tokens) |
| Find docs about reconciliation | Read all .md files |
search_docs (< 50 tokens) |
| Build context for a task | 5-10 file reads (~5,000 tokens) | context_for_task (< 200 tokens) |
cgh init generates a cryptographic auth key at .codegraph/auth.key (auto-added to .gitignore). The owner process and every worker / CLI caller read that file and send it as a Bearer token to the owner's loopback HTTP bridge, which compares it in constant time. The file contents are the shared secret: there is no environment-variable hand-off.
# Key is auto-managed -- no manual steps needed
cgh init # generates the key and the .codegraph/ index dirThe key file has 600 permissions and the .codegraph/ directory is 700 (owner-only). Never commit either to git.
- CALLS resolution is name-based by default. A call is linked to a same-file function of that name, falling back to all repo functions with that name only when there is no same-file match, so cross-file call edges are best-effort. For Python you can opt into precise cross-file resolution with
pip install cgh[lsp]andprecise_calls = true(jedi-backed); other languages stay name-based. - Terraform HCL uses regex, not a full grammar. Complex meta-arguments may be missed.
- JS/TS imports resolve to local files only. Relative imports (
import x from "./utils"), tsconfigpathsaliases, and workspace packages do create aFile -> FileIMPORTS edge. Bare external packages (import react) are not resolved to a node, and cross-repo edges are not inferred (each federated scope is canonical for its own files). - Markdown code refs are heuristic. PascalCase and snake_case patterns are matched, so a ref can be a false positive.
- Large repos take minutes to index. DuckDB (the default backend) is several times faster than the old Kuzu path, but a first scan of a very large tree is still bound by parsing every file. Incremental updates stay fast (well under a second per changed file), and a pull or merge reindexes only the changed files via the git hooks.
Dual-licensed under MIT and CC BY-NC-SA 4.0: both licenses apply together and you must comply with both. In practice that means non-commercial use, share-alike derivatives, attribution, and no warranty. Copyright (c) 2026 ALTIKVA. See LICENSE or the canonical notice at https://www.altikva.com/licenses/LICENSE-1.0.