Pre-indexed code graph for AI coding tools. Cuts token usage, prevents missed functions/files during development and QA.
Pairs with dotagent: dotagent owns intent / policy / memory, dotgraph owns structural facts.
┌─────────────┐
│ Claude │ ─┐
│ Codex │ ─┼─→ reads CLAUDE.md (dotagent)
│ Cursor │ ─┘ then queries dotgraph MCP
└─────────────┘
│
▼ MCP (stdio)
┌─────────────┐
│ dotgraph │ ─── SQLite (.dotgraph/graph.db)
│ serve │ • nodes (functions, tables, keys,
└─────────────┘ topics, endpoints, ...)
• edges (CALLS, READS_TABLE,
WRITES_KEY, HANDLES, ...)
• 3-tier confidence per edge
Phases 0 – 9 shipped. 77 tests passing. Dogfooded on this repo: 8× token reduction vs naive grep+read on a representative task.
| Phase | What | Status |
|---|---|---|
| 0 | scaffold + TS | ✅ |
| 1 | Python + 5 MCP tools + resolver | ✅ |
| 3 | Sequelize · Mongoose · SQLAlchemy · raw SQL (sqlglot) | ✅ |
| 4 | Redis key + Kafka topic extractors | ✅ |
| 5 | Framework routes — Express, FastAPI, Flask | ✅ |
| 6 | dotagent integration: mcp-config, reconcile CLIs, manifest rules |
✅ |
| 7 | Watch mode, Vue SFC, MCP smoke test, benchmark | ✅ |
| 8 | Multi-repo workspace + backend↔frontend HTTP linking | ✅ |
| 9 | Java + Spring + Prisma + NestJS + Django + Migrations | ✅ |
pip install -e .[mcp,sql,dev] # editable install with all extras
dotgraph index . # build the graph
dotgraph status # show stats
dotgraph search processPayment # find a symbol
dotgraph watch . # auto-reindex on file changesWire into Claude Code:
dotgraph mcp-config --tool claude > .claude/settings.json # or paste manually
# then restart Claude Code; it will see the dotgraph MCP serverWire into Cursor / Codex similarly via --tool cursor / --tool codex.
| Tool | Purpose | When AI calls it |
|---|---|---|
search |
symbol lookup via FTS | "where is X defined?" |
context_pack |
curated starting set for a task description | first call of every task |
impact |
blast radius — callers, callees, tests, data | before editing any function |
reconcile |
diff claimed impact vs actual | before commit |
find_refs |
grep-grade safety net for dynamic patterns | when reflection suspected |
Every response carries {indexed_at, dirty} so the AI knows when to
re-trust the graph.
TypeScript / TSX / JS / JSX, Python, Java, Vue SFC (<script> blocks).
- Sequelize —
sequelize.define(),class extends Model, ORM op calls - Prisma —
schema.prismamodel blocks with@@maphonoured - Mongoose —
mongoose.model(), collection ops - SQLAlchemy —
__tablename__,Column(),session.query()+ chains - Raw SQL — sqlglot-parsed string literals, MySQL/MSSQL/Postgres dialects
- Migrations — plain
.sql, Sequelize migrations (queryInterface.*), Alembic (op.create_table/add_column/...). Tables defined here become the authoritative_schemasource of truth.
- Redis — node-redis, ioredis, redis-py; key patterns normalised (
user:{id}:profile→user:_v:profile) - Kafka — kafkajs, node-rdkafka, kafka-python; producer + consumer
- HTTP clients — fetch, axios, ky, got, requests, httpx (the backend↔frontend matching glue)
- Express (Node) — full HTTP verb coverage
- NestJS (Node) —
@Controller+@Get/@Post/...with prefix join - FastAPI (Python) — decorator-based
- Flask (Python) —
@app.routeincludingmethods=[]splits - Django (Python) —
urlpatternswithpath,re_path,url - Spring (Java) —
@RequestMappingclass prefix + per-method mappings
dotgraph workspace init/index/status/search/impact/links- Cross-repo edges joined on shared identifiers (Kafka topic, table name, Redis key pattern, MongoDB collection)
- Backend ↔ frontend HTTP linking: every framework's path-param
syntax (
:id/{id}/<int:id>/${id}) collapses to the same canonicalMETHOD /path/:_vso endpoints in backend repos auto-match api_call nodes in frontend repos
dotgraph runs tree-sitter parsers against your source, extracts a typed
node/edge graph into SQLite (with FTS5 for fast search), then exposes
five focused MCP tools over stdio. Extractors are plugin-style: one for
each language and each ORM / framework. The resolver does a conservative
pass after extraction, emitting CALLS / HANDLES edges where a name
maps uniquely to one node — same-file matches get EXTRACTED confidence,
project-wide unique matches get INFERRED. Anything ambiguous stays in
the unresolved table and surfaces via find_refs.
- dotagent never writes to dotgraph's store. Read-only via MCP.
- dotgraph never reads dotagent's files. Pure git-derived.
- Every dotagent entry that makes a structural claim carries a dotgraph snapshot hash.
Full integration guide: docs/dotgraph-integration.md.
dotagent and other downstream consumers (CI hooks, IDE plugins, etc.) probe the following dotgraph surfaces. They will not change without a release note explicitly flagging the break.
| surface | shape / contract |
|---|---|
| index location | .dotgraph/graph.db at the repo root |
dotgraph --version |
dotgraph, version X.Y.Z (Click default; one space, "version", one space, semver) |
dotgraph status --json |
dict with at minimum files, dirty_files, nodes, edges, unresolved, db, last_indexed |
dotgraph emit-docs --target all |
writes 5 files into <cwd>/docs/: dependency-map.md, db-impact-map.md, redis-key-registry.md, kafka-topics.md, endpoints.md |
dotgraph reconcile |
accepts --paths, --symbols, --claimed-tables, --claimed-keys, --claimed-topics, --claimed-callers, --claimed-collections. Always emits JSON to stdout |
| MCP tool names | search, context_pack, impact, reconcile, find_refs (verbatim, no rename) |
Additive changes are safe; renames / removals require a major bump.
python scripts/benchmark.py . --task "add a redis cache layer to processPayment"On this repo: naive grep+read pulls 19 files / ~15.7k tokens; dotgraph
context_pack returns 25 ranked symbols / ~2k tokens. 8× reduction at
1ms latency.
MIT.