Comindly indexes a whole team's repositories into one versioned knowledge graph, then serves it to coding agents (Claude Code, Cursor, …) over MCP. Unlike grep or per-repo search, it answers structural, cross-repo questions deterministically:
- Who breaks if I change this? — org-wide blast radius (
ripple) - What's the minimal context to change X safely? — token-budgeted read-set (
context_pack) - How does this flow work? — a call-trace walkthrough (
flow) - Where across the org is this used / how do I …? — hybrid search + a pre-generated question catalog
Written in Rust. One static binary. No server to run, no per-developer re-indexing.
Why it's different
- Deterministic graph, not fuzzy RAG. Calls, imports, inheritance and instantiation come from the AST (tree-sitter) — exact, reproducible, cheap to build. Python, TypeScript/JavaScript, Go, Java, Kotlin and Rust. Where a repo has a SCIP index (or a SCIP indexer is installed), its compiler-grade answers take precedence.
- Cross-repo by design. A global symbol identity (SCIP scheme) links a definition in one repo to
its users in every other.
ripplegives blast radius across the whole org. - Built once, read everywhere. CI builds a new atomically-versioned index (local dir or S3); every agent reads the same fresh artifact. Incremental — only changed files/symbols are recomputed.
- Graph-aware hybrid search. Local static embeddings (Model2Vec) + BM25 + a dependency-graph centrality signal no pure search tool has.
- Provider-agnostic LLM enrichment. Optional summaries, question catalogs, and flow walkthroughs via Rig — OpenAI, any OpenAI-compatible endpoint, or a local model.
Install
Prebuilt binaries (macOS arm64/x64, Linux x64/arm64) are published to
GitHub Releases on each vX.Y.Z tag:
|
Or from source (needs Rust 1.95 or newer, plus protoc and cmake):
&&
# Try the deterministic engine on any repo, no network/S3 needed:
Quick start
Zero-config: with no --index-dir, comindly reads and writes a default index location
(~/.local/share/comindly, XDG-aware — see comindly config path).
Explicit location — a local dir or s3://…, shared across a team. The same --index-dir
builds and reads it (comindly manages the internal dataset layout):
# 1. Build the org index from several repos (embeddings + LLM enrichment/flows/guide run by
# default when OPENAI_API_KEY is set; add --no-enrich / --no-flows / --no-guide to skip, or --no-llm for all)
# 2. Explore / search the prebuilt index (instant, no re-parse)
# 3. Serve it to an agent over MCP
Register it with your agent. Claude Code:
Cursor, Codex, VS Code and other MCP clients: see Getting started,
or open comindly ui --web → Connect, which fills in your index path and checks your setup.
MCP tools (15):
- Navigate:
search,find,zoom,thread,flow,repos,suggest. - Before a change:
ripple(blast radius, across repos and service contracts),context_pack(minimal read-set + known constraints),preflight(constraints, dead ends, contracts, missing companions for a planned edit),contracts(HTTP routes, queues, buckets, tables and who uses them),guide(measured conventions and recipes). - Reasoning ledger:
why(recorded decisions, failed attempts and constraints about a symbol),remember,review.
Results are handed to the agent as markdown by default (structured JSON is also attached; use serve --format json for raw JSON). Hooks, the ledger, self-enforcing constraints, signing and privacy are described in the docs (guides).
In the app
comindly app (macOS) or comindly ui --web shows the same graph to people: the org map, contracts, the
ledger, packages and search. Shown here on the example shop in examples/acme.
Commands
| Command | Purpose |
|---|---|
comindly index <repo> [--enrich] [--flows] [--guide] [--no-embed] [--incremental] |
Index a single repo (embeds by default) |
comindly link <repos…> [--enrich] [--flows] [--guide] [--no-embed] [--incremental] |
Link several repos (cross-repo edges + blast radius) |
comindly explore <focus> [--index-dir <dir>] |
Zoom, blast radius, and context pack for a symbol |
comindly search <query…> [--repo <name>] [--index-dir <dir>] [--format md|table] |
Graph-aware hybrid code search |
comindly find <query> [--repo <name>…] [--index-dir <dir>] |
Locate symbols by name/path substring |
comindly repos [--index-dir <dir>] |
List indexed repositories + symbol counts |
comindly stats [--repo <name>…] [--index-dir <dir>] |
Per-repo stats: symbols, edges, kinds, enrichment coverage |
comindly guide [--repo <name>…] [-o <file>] [--index-dir <dir>] |
Per-repo inferred coding style guides (built with --guide) |
comindly flow <focus> [--index-dir <dir>] |
Pre-generated flow walkthrough + live call trace |
comindly changed <repo> [--since <sha>] |
Files changed since a commit (git diff) |
comindly serve [--index-dir <dir>] [--format md|json] |
MCP server over stdio |
comindly contracts [--type http|sqs|sns|s3|table] [--dangling] |
Service contracts with providers and consumers (FastAPI, Next.js, Express, Spring MVC, Feign, RestTemplate, WebClient, Go net/http/gin/echo/chi, axum, actix, reqwest, httpx/requests/fetch/axios, boto3, SQL; Terraform queues/topics/buckets and subscriptions) |
comindly packages [--skew] |
Internal packages: publisher, consumers, version skew |
comindly conventions [--repo <name>] |
Measured conventions, org baseline, recipes from history, and the team's own (each with an id) |
comindly conventions add "<rule>" [--repo <name>] [--dimension <d>] | edit <id> "<rule>" | rm <id> | restore <id> |
Add a team convention, rewrite or hide one (measured ones can be restored); stored under <index>/_conventions/, untouched by re-indexing |
comindly preflight [repo] [--base <rev>] [--strict] |
Before committing or in MR CI: constraints, dead ends, failing checks, contracts, blast radius, missing companions (MR job) |
comindly remember <kind> --on <symbol> --title … |
Record a decision, failed attempt, constraint, gotcha, intent or question |
comindly why <symbol> |
Reasoning blame for a symbol (status, trust, evidence) |
comindly review <id> <confirm|archive|invalidate|supersede|dispute> [--reason "…"] |
Act on a ledger record; comindly erase <id> deletes one |
comindly ledger [--inbox] [--check] [--compact] |
All ledger records, only those needing review, evaluate constraint checks (non-zero exit on a violated must, for CI), or fold the inbox into the Lance snapshot |
comindly erase <id…> | --actor <id|me> [--yes] |
Erase ledger records (and relations about them) for good, including old snapshot versions; dry run without --yes |
comindly doctor |
Check this machine's setup: index and ledger reachable, local mirror, hooks, LLM key, GitLab token, signing, SCIP indexers |
comindly hook claude <event> / comindly init-hooks claude |
Claude Code hook adapter / config snippet |
comindly eval graph [--scip <dir>] |
Graph quality on the gold fixture (precision/recall per edge kind) |
comindly repos [add <folders…> [--branch b] | remove <names…> | scan <dir>] |
Indexed repositories, and the list comindly link indexes when given no folders |
comindly app [--index-dir <dir>] |
The UI in its own window (macOS) |
comindly team [set k=v… | key] |
Team settings stored with the index (LLM, embedding model, LLM steps); key stores your own API key |
comindly join <index> [--profile p] |
Use a team's index on this machine |
comindly ui [--web [--port 7878] [--open]] [--index-dir <dir>] |
Terminal UI (incl. a ledger timeline), or a local web UI on 127.0.0.1 (overview, contracts, ledger review, explorer with a neighbourhood graph, conventions) |
comindly config <path|init> |
Show or scaffold the config file |
Run comindly <command> --help for the full flags of any subcommand.
--index-dir is a local directory or an s3://… path; it is optional and defaults to the
configured index location. All build steps default on (embed, enrich, flows, guide);
each has a config.toml default and a --x / --no-x override (CLI wins). Embeddings are local;
enrich/flows/guide call an LLM (cost + send code, need OPENAI_API_KEY) — they skip
automatically with a warning when no key is set, so a keyless index still builds the graph +
search. Cap LLM cost with max_enrich / max_flows in config.toml.
How it works
Build the index once (in CI or locally); every consumer reads the same versioned artifact.
flowchart LR
subgraph SRC["Sources (git)"]
R1["pkg-common"]
R2["service-a / service-b / …"]
end
subgraph IDX["Index — incremental"]
P["parse<br/>tree-sitter"]
RS["resolve<br/>cross-repo SCIP"]
G["git<br/>changed files only"]
end
subgraph ART["Versioned LanceDB artifact (local dir or S3)"]
GR["graph<br/>symbols · edges"]
SE["search<br/>vectors · BM25"]
EN["enrichment<br/>summaries · queries · flows"]
end
subgraph USE["Consume — instant"]
MCP["comindly serve<br/>MCP · 15 tools"]
CLI["comindly search / explore / flow"]
end
SRC --> IDX --> ART --> USE
AGENT(["coding agent"]) -. ripple / context_pack .-> MCP
Single crate, one module per stage — see ARCHITECTURE.md for the design and the
competitive landscape.
src/model.rs SCIP identity, Symbol/Edge model
src/parse.rs tree-sitter walk → symbols, structure, per-file facts
src/lang/ per-language adapters: Python, TypeScript/JS, Go, Java, Kotlin, Rust
src/packages.rs module names from pyproject / package.json / tsconfig / go.mod / Cargo.toml
src/resolve.rs binder: imports, re-exports, type flow, inheritance — within and across repos
src/scip.rs SCIP ingestion (existing index.scip or installed indexers)
src/eval.rs graph-quality eval on a gold fixture (`comindly eval graph`)
src/conventions.rs measured coding conventions + org baseline; src/recipes.rs change recipes from history
src/ledger.rs reasoning ledger: decisions, failed attempts, constraints anchored to symbols (`why`, `remember`)
src/checks.rs compiled constraint checks evaluated on the graph and manifests (`ledger --check`, preflight)
src/web.rs local web UI (`comindly ui --web`): JSON API + the embedded React app from ui/
src/git.rs git change detection (incremental)
src/index.rs versioned LanceDB store: symbols, edges, search, enrichment, flows, style guide
src/graph.rs in-memory petgraph: ripple / thread / zoom / context_pack
src/embed.rs Model2Vec embeddings + code-aware hybrid ranking
src/search.rs hybrid retrieval (BM25 + vector + graph centrality)
src/llm.rs LLM summaries / questions / flow walkthroughs (opt-in, provider-agnostic via Rig)
src/mcp.rs MCP server (15 tools)
src/main.rs the comindly binary (CLI)
CI
.github/workflows/comindly-index.yml (and
docs/guides/ci.md, with a GitLab variant) builds the shared index on a schedule: it clones
the listed repos and runs comindly link … [--enrich] [--incremental], publishing the result
as a downloadable artifact (or to S3). Lance's version manifest is the atomic "latest" pointer every
consumer reads.
Configuration
Persistent, non-secret defaults live in config.toml (comindly config path shows where; comindly config init scaffolds it). Precedence, highest first: CLI flag → environment variable → config
file → built-in default.
= "~/.local/share/comindly" # default --index-dir (local path or s3://…)
= "gpt-6-luna" # any OpenAI-compatible model id
= "minishlab/potion-base-8M"
= "md" # default when --format is absent (search: md|table, serve: md|json)
= true # index/link step defaults; CLI --x / --no-x override
= true # LLM per-symbol summaries + queries (cost + sends code)
= true # LLM flow walkthroughs (cost + sends code)
= true # evidence-based style guide (cost + sends code)
# llm_base_url = "http://localhost:11434/v1" # Ollama / vLLM / LiteLLM proxy
# max_enrich = 200 # cap --enrich symbols (omit = no cap, whole codebase)
# max_flows = 50 # cap --flows narrations (omit = no cap)
# scip = "auto" # auto | require | off
# cache_ttl_secs = 300 # how often serve/ui check for a new index version; hooks' local mirror
# signing_key = "~/.ssh/id_ed25519.pub" # sign ledger records (default: git user.signingkey)
# allowed_signers = "~/.config/git/allowed_signers" # verify them (default: git config)
Environment overrides: COMINDLY_INDEX_DIR, COMINDLY_LLM_MODEL, COMINDLY_EMBED_MODEL,
COMINDLY_LLM_BASE_URL, COMINDLY_FORMAT.
Secrets stay in the environment, never the file: --enrich/--flows use an LLM via Rig
(default OpenAI, OPENAI_API_KEY; any OpenAI-compatible endpoint via COMINDLY_LLM_BASE_URL). For an
s3://… index, AWS credentials/region come from the standard AWS environment (AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY, AWS_REGION, or an SSO profile).
Status
Engine: parse → resolve (tree-sitter + SCIP) → index → graph → embed → enrich → search → serve,
git-incremental at repo and org level. On top: the service-contract graph (HTTP, queues, topics,
buckets, tables, Terraform), conventions and recipes, the reasoning ledger (records, staleness,
self-enforcing checks, signing, erasure), preflight, and terminal and web
UIs. Progress and open items: docs/design/roadmap.md.
Development
Pre-commit hooks (fmt + clippy + basic file checks) live in .pre-commit-config.yaml — install
with pre-commit install, or the Rust-native prek install (both read the same file).
License
MIT.