About
LeanKG: Stop Burning Tokens. Start Coding Lean.
README
LeanKG
Enterprise-ready code knowledge graph for AI coding agents
Multi-repo · env governance · incidents & services · req↔code · −65% tokens / −85% tool calls
Live Demo · Docs · pkg.go.dev · Changelog
What is LeanKG?
LeanKG is a code knowledge graph for AI coding agents, shipped as a single CGO-free Go binary
(github.com/FreePeak/LeanKG, root module — see pkg.go.dev).
Where agents usually rebuild structure with grep → open files → huge context, LeanKG returns a
targeted subgraph (callers, dependents, blast radius, tests, docs) plus a team layer (env,
services, incidents, requirements) over MCP. The Rust engine was removed at the parity cutover;
build with make go-build, test with make go-test. See docs/prd.md for the
parity ledger.
| Without | With LeanKG |
|---|---|
| Many tool calls, large context | Surgical subgraph + TOON (~40% smaller payloads) |
| No blast radius | Severity-graded impact |
| Keyword only | Keyword + HNSW semantic + ontology |
| Single-repo guesswork | Multi-repo index + ops tools |
Get Started
# 1. Per project: one-shot index, then an incremental embed (sqlite default — zero config,
# store at .leankg/leankg.db). In a git repo root it reads the HEAD commit's objects, so
# uncommitted, untracked and ignored files are not indexed. Add --no-embed to skip the embed.
cd your-project
leankg index .
# 2. Wire up an AI client — one command (claude-code | cursor | codex | gemini | opencode | omp).
# The stdio entry is `serve --stdio --memory`: the agent gets the code graph AND the
# markdown memory layer (per-project at <project>/.leankg/memory), no second server.
leankg install --target claude-code # `connect claude-code` is the same writer
# Restart the client afterwards so it picks the entry up.
# 3. ...or serve MCP over HTTP yourself (endpoint /mcp; GET /health returns 200 when ready)
leankg serve --http 127.0.0.1:9699 --rest 127.0.0.1:8080 --memory
leankg install --target claude-code --http --url http://127.0.0.1:9699/mcp
Semantic (L3) search is the one optional layer: it needs embeddings. Set
LEANKG_EMBED_PROVIDER (see docs/embedding.md and
.env.example); leankg index then embeds incrementally after
indexing. Until an embed runs, queries answer from exact + fuzzy matches.
Self-check any deployment: leankg doctor — prints the store path, element and
file counts and the write watermark (exit 0 pass / 2 fail).
MCP over HTTP: the server resolves the project from its process cwd — run it
from the checkout or pass --project DIR to pin one.
Installation
None — sqlite is the default storage engine. No Postgres, no Docker.
Postgres remains available as an explicit opt-in (LEANKG_DB_ENGINE=postgres + LEANKG_PG_URL) for server-scale deployments, but nothing in the default flow touches it.
Published module — the engine is a Go module, so the toolchain installs both
binaries from pkg.go.dev straight into $(go env GOPATH)/bin:
go install github.com/FreePeak/LeanKG/cmd/leankg@latest # server + CLI
go install github.com/FreePeak/LeanKG/cmd/leankg-embed@latest # embedding pipeline
Prebuilt archives — releases
carry leankg-<os>-<arch>.tgz for linux/darwin × amd64/arm64, both binaries at the
archive root plus a .sha256. leankg update follows the same channel.
From a checkout — requires Go 1.25+ and git; installs to
~/.local/bin (pass a PREFIX to change it):
git clone https://github.com/FreePeak/LeanKG.git && cd LeanKG
scripts/install-go.sh # or: make install-go
# Or fetch and run the installer directly (clones over HTTPS, same behavior):
curl -fsSL https://raw.githubusercontent.com/FreePeak/LeanKG/main/scripts/install-go.sh | bash
Container — Dockerfile is a three-stage CGO-free build: engine binaries, then a demo graph baked from a slice of this repo, then an unprivileged runtime that serves that store read-only.
docker build -t leankg .
docker run --rm -p 8080:10000 -e PORT=10000 leankg # dashboard + its /api on :8080
MCP surface
Discover with query — it routes down the ladder by default (L1 exact → L2 keyword → L3 semantic; a natural-language question goes straight from an L1 miss to L3, which fuses keyword and vector ranks), degrades instead of erroring, and every answer carries retrieval{rung,reason} + freshness.
| Question | How |
|---|---|
| Any identifier (default) | query "Alpha" (exact, then fuzzy fallback) |
| Session start memory | query action=memory args.command=session_recall |
| Session end retain | import action=memory command=session_retain |
| Blast radius | leankg impact <file> or query --action impact --to <qn> |
| Who calls X? | query --action callers --to <qn> |
| How A↔B? | query --action path --to <qn> |
| Element details | query --action explain --to <qn> |
| Pattern search | query --action pattern --pattern "func $_(...)" |
| PRD traceability | leankg prd-trace FR-3T-01 |
| File (compressed) | query --action read --path src/main.go |
3 tools: import (index/PRD/memory/session/ontology/read) · query (ladder + graph verbs + actions) · status (inventory/freshness/config).
Features
- MCP-native — search, impact, call graphs, ontology, architecture, team knowledge
- SQLite default (zero-config — no Postgres, no Docker required) with an opt-in Postgres/pgvector backend (
LEANKG_DB_ENGINE=postgres+LEANKG_PG_URL) - Ontology — concept catalog + procedural layer (workflows, steps, decision points, failure modes),
query --action ontology,POST /api/v1/ontology/match, and req↔code traceability vialeankg prd/prd-trace - Impact & deps —
contains,calls,importsedges; BFS blast radius (leankg impact) - Multi-repo server — MCP HTTP
127.0.0.1:9699;LEANKG_PROJECT_DIRSserves many projects, selected per request by?project=<dir|name>(REST and MCP) or the MCPprojecttool argument; with neither, a multi-project server refuses rather than answering from the wrong graph. sqlite default, PG opt-in - Env governance —
query --action env_conflicts, per-env snapshots,leankg obsidian - Ops & ownership —
query --action service_context/incidents,leankg incident/note/team-map - Req ↔ code —
leankg prd/prd-trace,query --action prd, ontology traceability matrix - Web UI v2 — Force / Tree / Circles explorer (
cd ui-v2 && npm run dev; the embedded build is served byleankg serve --ui) - Deploy — single CGO-free binary, no runtime deps: Dockerfile builds a read-only demo image for Render,
/healthanswers container probes, and--ui/--http/--rest/--rpceach bind their own address - Languages — 40 profiles: Go, Rust, TypeScript/TSX, JavaScript/JSX, Python, Markdown, Java, Kotlin, Swift, Objective-C, Dart, C/C++, C#, PHP, Ruby, Scala, Perl, Lua, Haskell, Elixir, Crystal, CUDA, Cypher, Elm, Erlang, F#, GLSL, HLSL, Nim, OCaml, SQL, PowerShell, Q#, Solidity, SystemVerilog, Verilog, Zig
- Agent economics — A/B −65% tokens, −85% tool calls, 2.5× vs grep/cat; peers in this space are mostly personal / single-repo. Deep dives (archived): competitive analysis · ROI vs Graphify · research matrix
Embeddings
Semantic (L3) search needs embeddings; see docs/embedding.md for providers (local / openai / deterministic), the EmbeddingGemma 2 + Hugging Face Storage Bucket bulk path, and the .env.example variable list. The catalog rows (model id, pinned revision, dimensions, prefixes) live in internal/embed/catalog.go.
Performance
- Go cold time-to-first-value — 17.8s (macOS arm64); CI budget 300s, gate "Cold TTFV" in
.github/workflows/ci.yml, per-run numbers in thettfv-go-coldartifact. - Quickstart happy path — 1.4s warm on a generated 10-file Go fixture (index 0.05s, server bind 1.08s, first query 0.05s, doctor 0.03s);
scripts/quickstart_smoke.shruns the same steps locally (QUICKSTART_DRY_RUN=1prints the plan).
CLI
leankg index . # one-shot index + incremental embed -> .leankg/leankg.db (--no-embed skips the embed)
leankg index --hook <dir> # SessionStart mode: skips over LEANKG_HOOK_MAX_FILES (10000) files or LEANKG_HOOK_MAX_EMBED (500) elements needing vectors
leankg writer # index once, then watch; a git-backed store re-indexes on each new commit (unsaved edits do not change the graph)
leankg query "parseConfig" # name lookup (exact, then fuzzy) — JSON out
leankg query "parseConfig" --compress # one line per result
leankg impact src/main.go --depth 3 # blast radius of a file or element
leankg status # health, inventory, freshness, embed state
leankg doctor # store path, element/file counts, watermark
leankg connect claude-code # MCP entry: claude-code|cursor|codex|gemini|opencode|omp
leankg install --target cursor # same wiring, flag form (--register-cwd: async claude-code SessionStart hook running `index --hook`)
leankg serve --stdio # MCP over stdio (what harnesses spawn)
leankg serve --http 127.0.0.1:9699 # MCP over streamable HTTP (/mcp, /health)
leankg serve --rest 127.0.0.1:8080 # REST API (/health, /api/v1/*)
leankg serve --ui 127.0.0.1:8081 # embedded dashboard (/api/* data API served here)
leankg serve --rpc 127.0.0.1:9090 # ConnectRPC (gRPC + gRPC-Web + JSON)
leankg version
A non-loopback bind is refused. leankg serve --http/--rest/--rpc <non-loopback>
exits with an error unless a bearer token is configured, because with no token
every caller resolves to Admin — the project graph, the file reader and the
memory write path would all be open to the LAN. Two ways out: bind a loopback
address (the default), or configure a token first
(leankg auth token create, or LEANKG_TOKEN_ADMIN / LEANKG_TOKEN_CONTRIBUTOR
/ LEANKG_TOKEN_VIEWER). --ui is the one deliberately public listener (the
container demo serves it --read-only against a disposable baked graph), so it
keeps a warning instead of a refusal.
UI hot-reload: cd ui-v2 && npm install && npm run dev → http://127.0.0.1:5173
Full usage: leankg help and leankg <command> --help. Archived CLI reference: docs/archive/cli-reference.md
Known limits
- Call edges are package-scoped. No import/type resolution, so a same-name call in the same package resolves and cross-package dispatch is best-effort; the upgrade path is tree-sitter symbol tables.
- Heuristic guards in
internal/index/relations.go: files ≥ 1 MiB are skipped as vendored/minified bundles, call targets shorter than 4 characters are dropped as noise, and outgoing calls are capped per element and per file. - The unit of scope is a repository. A portfolio root (tens of thousands of nested files) is not a project; register its children one at a time.
--uibinds an unauthenticated data API (query/read/import routes). Bind it loopback or front it with a proxy — the public demo container serves it--read-onlyagainst a disposable baked graph.
Troubleshooting
| Issue | Fix |
|---|---|
| Wrong project served | Start the server with --project DIR (query/impact also honor LEANKG_PROJECT) |
| Embeddings / cold embed | leankg-embed status, then leankg-embed full (provider env: LEANKG_EMBED_*) |
Requirements: macOS or Linux · Go 1.25+ only when building from source. No Docker, no Postgres — sqlite is the default store.
Documentation
The documentation set lives in docs/ — a single unified PRD (docs/prd.md) + task tracker (docs/prd-task-tracker.md). All historical design docs, analyses, reports, and plans are preserved under docs/archive/.
| Doc | |
|---|---|
| PRD | Unified product requirements + HLD (single SoT) |
| Task tracker | Done / in-progress / todo |
| Architecture (archived) | Design & data model (historical) |
| MCP tools (archived) | Tool catalog (historical) |
| CLI (archived) | All commands (historical) |
| Benchmarks (archived) | Methodology (historical) |
| Embeddings | Providers + EmbeddingGemma 2 / Hugging Face bulk path |
| AGENTS.md | Agent notes |
Contributing
- Fork + feature branch (prefer a worktree)
- Update docs when behavior changes
go build ./... && go vet ./... && go test ./...- Open a PR with summary + test plan
License
Installing LeanKG
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/FreePeak/LeanKGFAQ
Is LeanKG MCP free?
Yes, LeanKG MCP is free — one-click install via Unyly at no cost.
Does LeanKG need an API key?
No, LeanKG runs without API keys or environment variables.
Is LeanKG hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install LeanKG in Claude Desktop, Claude Code or Cursor?
Open LeanKG on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Unyly Deploy
Deploy sites and MCP servers to Unyly straight from your AI agent
by UnylyAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiPayMCP
Lightweight payments layer for MCP servers: turn tools into paid endpoints with a two-line decorator. [PyPI](https://pypi.org/project/paymcp/) · [npm](https://w
by blustAIServer For Power BI
Enables exploring Microsoft Fabric / Power BI workspaces and semantic models, and executing ad-hoc DAX queries.
by Mitsubishi-FusoTemplate MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Compare LeanKG with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
