A Go MCP server for code intelligence with SQLite indexing and auto-sync.
Based on colbymchenry/codegraph — official 8 MCP tools + affected extension.
Current version: 0.9.5. Index logic version 19.
Pipeline: extract → park cross-file refs → ResolveAll → scrub pure-noise failed refs → SynthesizeAll (callback / React / JSX / bridge / C fn-pointer / GoFrame). Nodes carry qualified_name / signature / visibility / is_exported / return_type. Vue/Svelte/Astro SFCs get a file component + script/frontmatter + template component refs. IndexAll uses a file-level worker pool (CODEGRAPH_INDEX_WORKERS). Optional shared daemon (one writer per project, N thin stdio proxies). Extractor logic bumps raise the index schema revision: the daemon's first start after an upgrade detects the mismatch and automatically wipes + fully rebuilds the index (no manual step; see Indexing).
Alignment: steps 1–9 done incl. 7.5 (logic 19). Not full feature-parity — see /root/codegraph-go-comparison.md (next: step 10 eval).
- 1 MCP tool
codegraph(action router):action=explore(PRIMARY),node,search,callers/callees/impact,files,status,affected/communities,store_fact/search_facts. Same capabilities as 0.7 multi-tool surface; one schema for lower prompt cost. - node dual mode:
filealone = Read-like numbered source + dependents;name= body + trail; overloads return every body in one call - projectPath on every tool: walk up to nearest
.codegraph/and query that project’s index (no cross-project DB bleed) - Graph-first queries: callers / callees / impact walk the SQLite call graph (rg only as labeled fallback); optional
filepins overloads - Extract → unresolved_refs → ResolveAll → scrub → SynthesizeAll: cross-file calls parked then linked; pure framework noise without a project symbol is scrubbed
- Path aliases / monorepo: tsconfig/jsconfig
paths,@/fallbacks, package/pnpm workspaces, go.mod module+replace, Cargo workspace members - Dynamic-dispatch edges: callback / EventEmitter / React-render / JSX-child / bridge / C fn-pointer / GoFrame route (heuristic + synthesizedBy)
- Smart explore: Flow path + source for a bag of symbols; size-tier output budget
- SQLite indexing: symbols, edges, files, unresolved_refs in
.codegraph/codegraph.db - FTS5 full-text search: plain identifiers in
searchhit FTS first (no separate search_fts tool) - Tree-sitter AST parsing: Go / TypeScript / JavaScript / Python with qualified_name, signature, is_exported, visibility, return_type (syntax-keyword call filter only)
- SFC support: Vue / Svelte / Astro — file component, multi-script/frontmatter, opening-tag template refs (HTML natives skipped, kebab→Pascal,
@click/v-on) - Parallel index: IndexAll worker pool (
CODEGRAPH_INDEX_WORKERS, default min(8, cores-1)); DB writes serialized - Noise rules:
ShouldParkRefkeeps real symbols even if named likeemit; scrub after resolve - Regex fallback: Rust (use/fn/impl + pub/signature + cargo map), Java, C#, Ruby, PHP, C, C++, Swift, Kotlin, Scala, Dart, Lua, Luau, R, Objective-C, Liquid, Pascal/Delphi
- Framework route detection: Gin, chi, gorilla/mux, Express, NestJS, Flask, FastAPI, Django, Laravel, Rails, Spring, ASP.NET, Axum, actix, Rocket, Vapor, Play
- Cross-language bridging: CGo (Go↔C), Python ctypes/cffi/Cython, React Native/Expo, Swift↔ObjC
- Home-mode indexing: workdir=
$HOMEonly enters project-like top-level dirs - Shared daemon (optional): one process per project root owns SQLite + watcher; MCP hosts attach via Unix socket proxy.
CODEGRAPH_NO_DAEMON=1keeps the old embedded mode. Idle exit default 300s (CODEGRAPH_DAEMON_IDLE_TIMEOUT_MS). - content_hash incremental: SHA-256 of file bytes; unchanged content skips re-extract even if mtime moved
- Git-assist sync: after cold index,
git statuspicks up edits missed while nothing was watching (no hooks installed) - Portable index paths: files/nodes stored relative to workdir (schema 17+); safe to move/copy the tree after reindex
- Auto-sync: file watcher with 2-second debounce on every configured workdir; new directories are watched recursively
- Staleness warning: warns when referenced files are pending sync
- Index skip rules: indexing applies built-in skip rules (internal skip.go) and does not parse
.gitignore; search tools run ripgrep, which respects ignore files by default and only sweep ignored files whenno_ignore=trueis passed - Agent fact storage:
store_fact/search_factstools let agents attach cross-session findings, decisions, and notes to code symbols; facts survive index rebuilds
Aligned steps 1–9 (including optional 7.5 C fn-pointer + GoFrame synthesis). Remaining: step 10 evaluation/docs wrap-up.
| Item | Value |
|---|---|
| Display version | 0.9.5 |
| Index logic | 19 |
| Feature parity | not claimed (step 10 open) |
Single source of truth: /root/codegraph-go-comparison.md.
# Prerequisites
which rg # ripgrep must be on PATH
go version # Go 1.25+
# Build
cd codegraph-go
go build -o codegraph-go ./cmd/codegraph-go
# Install
# Recommended: run ./deploy.sh — it installs to $HOME/.local/bin/codegraph-go.
cp codegraph-go ~/.local/bin/codegraph-goA Pi-specific TypeScript adapter is maintained in integrations/pi/. The Go binary remains a generic stdio MCP server; the adapter owns Pi lifecycle, tool registration, dynamic index-root context, and output budgets.
codegraph-go -workdir /path/to/project| Flag | Default | Description |
|---|---|---|
-workdir |
current directory | Workspace root |
-no-sync |
false | Disable auto-sync file watcher |
One tool: codegraph. Required: action. Optional common fields: path, projectPath, max / max_results, glob, etc. (see tool schema).
| action | Purpose |
|---|---|
explore |
PRIMARY. Overview or query= bag of names → Flow + source (treat as already Read) |
node |
file alone = Read-like source + dependents; name = body + trail |
search |
Symbol FTS or ripgrep (pattern); literal by default — regex=true for regex, no_ignore=true to include ignored files |
callers / callees / impact |
Call graph; optional file pin |
files |
Glob listing |
status |
Index health |
affected |
Tests affected by changed files |
communities |
Module/community structure |
store_fact / search_facts |
Cross-session facts |
projectPath (absolute path inside a project) selects the nearest .codegraph/ index.
| Host | Invoke |
|---|---|
| Any MCP client | tool codegraph + action |
| Grok | cg__codegraph or cg-eqi12__codegraph + action (config keys mcp_servers.cg / cg-eqi12) |
| Pi | extension tool codegraph + action (see integrations/pi/) |
On first run, codegraph-go indexes the entire project. The index includes:
- Nodes: functions, methods, classes, structs, interfaces, variables, constants
- Edges: calls, imports, extends, implements
The file watcher automatically re-indexes changed files within 2 seconds.
Extractor logic changes (new node kinds, edge fixes, call-site corrections, …)
make old rows wrong or incomplete, so they raise the index schema revision.
On startup the daemon compares the on-disk revision against the binary's
constant: a mismatch wipes the symbol index and rebuilds it in full, with no
manual step. Upgrading to a release with new extraction semantics therefore
rebuilds automatically on the first start after the upgrade — the rebuild
runs inside the daemon while it holds the index lock, takes as long as the
initial index, and queries may return partial results while it runs
(status shows the pending rebuild).
Incremental re-indexing only applies to files added or changed after that rebuild: the content_hash gate skips re-extraction of unchanged files, so an index built by older logic is never "self-healed" by incremental sync — only files whose content changes get re-extracted under the new semantics.
For Go, TypeScript, JavaScript, and Python, codegraph-go uses tree-sitter for accurate AST-based extraction. This provides:
- Better method detection (including struct methods with receivers)
- More accurate call graph (handles method calls, selector expressions)
- Proper handling of nested functions and closures
For other languages, regex-based extraction is used as a fallback.
codegraph-go detects web framework routing patterns and creates route nodes:
- Go: Gin, chi, gorilla/mux
- JavaScript: Express
- Python: Flask, FastAPI, Django
Routes are stored as nodes with kind route, where the name is METHOD /path and the body is the handler function name.
codegraph-go detects cross-language calls and creates bridge edges:
- CGo: Go ↔ C via
import "C"andC.functionName() - Python ctypes: Python → C via
ctypes.CDLL() - Python cffi: Python → C via
ffi.cdef()andffi.dlopen() - Python Cython: Python → C via
cdef extern from - React Native: JS → Native via
NativeModulesand TurboModules - Expo: JS → Native via
requireNativeModule()
codegraph-go/
├── cmd/codegraph-go/main.go # Entry point
├── internal/db/
│ ├── schema.sql # SQLite schema
│ ├── connection.go # Database connection
│ ├── root.go # FindNearestCodeGraphRoot
│ └── query.go # nodes, edges, files, unresolved_refs
├── internal/extraction/
│ ├── common.go # Language detection
│ ├── extractor.go # Regex extraction (+ Rust use/fn)
│ ├── treesitter.go # Tree-sitter AST (Go, TS, JS, Python)
│ ├── frameworks.go # Framework route detection
│ ├── bridge.go # Cross-language bridging
│ └── orchestrator.go # Index builder → ResolveAll
├── internal/resolution/
│ ├── resolver.go # pending refs → edges
│ ├── name_matcher.go
│ ├── import_resolver.go
│ ├── path_aliases.go # tsconfig/jsconfig paths
│ ├── go_module.go # go.mod module + replace
│ ├── workspace_packages.go
│ └── cargo_workspace.go
├── internal/server/
│ ├── server.go # MCP server handler
│ ├── tools.go # Tool dispatcher
│ ├── project.go # Project management
│ └── output.go # Response formatting
├── internal/sync/
│ └── watcher.go # File watcher with debounce
├── internal/tools/
│ ├── graph.go # explore / callers / callees / impact
│ ├── node.go
│ ├── status.go
│ └── affected.go
├── testdata/parity/ # go, ts, py, alias, gomod, cargo, synth_*
MIT