Your codebase's memory. Persistent organizational memory for AI coding agents — so they stop repeating your team's past mistakes.
PyPI version License: MIT Python 3.11+ MCP Compatible Status: alpha
lore demoAI coding agents (Claude Code, Cursor, Codex) can write code. They still don't know why your team made the decisions baked into your codebase. So they confidently suggest the exact thing that broke production last quarter.
lore ingests your git history, ADRs, and postmortems; extracts the why; and serves it back to your agent over MCP — so before it touches code, it can recall:
- what your team has already tried and reverted
- which conventions exist and why
- which postmortems are sitting one mistake away from repeating
You > Add Redis caching to the payment endpoint.
Claude > Before I touch this, I checked lore — 3 relevant past decisions:
1. [revert] Redis caching reverted on payment writes
Why: Stripe webhook race condition caused duplicate charges
commit a8f3b2c1 · 2026年03月12日
2. [convention] No in-memory caching on payment write paths
Why: Codifies ADR-014 so new contributors don't reintroduce the bug
docs/adr/ADR-014.md · 2026年04月02日
3. [incident] Duplicate-charge incident POST-221
Why: Stale cache during partial outage
docs/postmortems/POST-221.md · 2026年05月09日 · severity: high
Suggested alternative: database query caching
(see services/orders/cache.py)
That output isn't from a chatbot — it's a real MCP tool call that lore exposes to your agent.
Your AI agent has incredible coverage of:
- syntax
- frameworks
- public APIs
- general code patterns
It has zero coverage of the thing that actually matters in a mature codebase:
- Why a migration was rolled back two months ago
- Why Kafka was rejected in favor of Postgres LISTEN/NOTIFY
- Why there's a lint rule banning in-memory caches on
/payments - Why every onboarding engineer has to be told the same five things in their first week
That gap is where lore lives. The product thesis: the next breakout layer in AI tooling is persistent organizational reasoning, not better autocomplete.
┌──────────────────┐ ┌─────────────┐ ┌────────────────┐
│ Git history │ │ ADRs │ │ Postmortems │
│ (PRs, commits) │ │ (markdown) │ │ (markdown) │
└────────┬─────────┘ └──────┬──────┘ └────────┬───────┘
│ │ │
└───────────┬───────┴──────────────────┘
▼
┌────────────────────────┐
│ Signal pre-filter │ drops ~80% of routine work
└──────────┬─────────────┘
▼
┌────────────────────────┐
│ Decision extraction │ LLM (Anthropic | Groq | Gemini | Ollama)
│ (or heuristic mode) │ or pattern-based, zero-setup
└──────────┬─────────────┘
▼
┌────────────────────────┐
│ Embed (bge-small) │
└──────────┬─────────────┘
▼
┌────────────────────────┐
│ SQLite + sqlite-vec │ local-first, your data never leaves
│ + FTS5 (BM25) │ your machine unless you choose so
└──────────┬─────────────┘
▼
┌────────────────────────┐
│ Hybrid retrieval │ vector ⊕ keyword via RRF,
│ (RRF + boosts) │ then source / type / severity / recency
└──────────┬─────────────┘
▼
┌────────────────────────┐
│ MCP server │ recall_decision, find_postmortems,
│ (stdio transport) │ related_history
└──────────┬─────────────┘
▼
Claude Code · Cursor · Codex · any MCP client
pip install codelore
The package is
codelore; the command it installs islore.
Or from source:
git clone https://github.com/Hanishsaini/Lore.git cd Lore pip install -e .
Python 3.11+ required.
pip install codelore lore demo
lore demo loads a preloaded memory of a fictional payments platform and answers
the signature question against it — so you can feel the product before pointing it
at your own code. Ask it anything:
lore demo "why did we drop Kafka?" lore demo "how should we store money?"
(First run downloads a small embedding model, ~80 MB. No LLM or API key needed — the demo decisions are pre-extracted.)
cd your-project/ lore init lore ingest . lore ask "should I cache payment writes?"
That's it. The first run downloads a small embedding model (~80 MB).
These get priority at retrieval time — formal writeups outrank random commit messages.
lore ingest . --adrs docs/adr --postmortems docs/postmortemslore runs with whatever you have. It auto-detects in this order:
| Provider | Cost | Quality | Setup |
|---|---|---|---|
| Anthropic Claude | Paid | Highest | export ANTHROPIC_API_KEY=... |
| Groq | Free tier | High | export GROQ_API_KEY=... (signup, no credit card) |
| OpenRouter | Free models | High | export OPENROUTER_API_KEY=... (signup) |
| Google Gemini | Free tier | High | export GEMINI_API_KEY=... (signup) |
| DeepSeek | Free credits | High | export DEEPSEEK_API_KEY=... (signup) |
| NVIDIA NIM | Free tier | High | export NVIDIA_NIM_API_KEY=... (signup) |
| Ollama (local) | Free | Medium | ollama serve + ollama pull qwen2.5:7b |
| Heuristic fallback | — | Low | nothing — works out of the box |
Or skip exports entirely — use a .env file:
lore auto-loads ./.env (per-repo) and ~/.lore.env (global) on every run.
Real environment variables always win, so a .env never clobbers a shell export.
cp .env.example ~/.lore.env # then fill in one key echo 'GROQ_API_KEY=gsk_...' >> ~/.lore.env
.env is gitignored by default — your keys never get committed.
Force a specific provider:
export LORE_LLM_PROVIDER=openrouter # or: anthropic, groq, gemini, deepseek, nvidia, ollama
Override the model on a provider:
export LORE_OPENROUTER_MODEL=deepseek/deepseek-chat-v3:free export LORE_NVIDIA_MODEL=meta/llama-3.3-70b-instruct export LORE_DEEPSEEK_MODEL=deepseek-chat export LORE_OLLAMA_MODEL=qwen2.5:14b
Stitch multiple free keys together (useful when one rate-limits):
export GROQ_API_KEYS="key1,key2,key3" # lore rotates through them automatically on 429s
The same plural form works for every cloud provider: ANTHROPIC_API_KEYS,
OPENROUTER_API_KEYS, GEMINI_API_KEYS, DEEPSEEK_API_KEYS, NVIDIA_NIM_API_KEYS.
If the active LLM rate-limits, returns malformed JSON, or hits a network error, lore falls back to heuristic extraction for that one candidate — and tells you about it. You'll see a stderr warning on the first event plus a per-run summary at the end of ingestion:
[WARN] 3/127 candidates fell back to heuristics (rate_limit=2, bad_json=1).
Quality on those entries will be lower than the configured LLM.
That way you can't accidentally ship a "fully LLM-extracted" memory that was 40% heuristic without knowing it.
One command:
lore install claude-code
That writes (or merges into) ~/.claude/mcp_settings.json with an entry
pointing at your current directory. Restart Claude Code and you're done.
If you want to manage multiple lore instances (e.g. one per repo), pass
--name and --repo:
lore install claude-code --name lore-payments --repo /path/to/payments-service lore install claude-code --name lore-platform --repo /path/to/platform
Prefer to edit the config by hand? Run the server directly:
lore mcp --repo /abs/path/to/your/project
And add to ~/.claude/mcp_settings.json:
{
"mcpServers": {
"lore": {
"command": "lore",
"args": ["mcp", "--repo", "/abs/path/to/your/project"]
}
}
}Once installed, Claude Code can call:
recall_decision(query)— relevant past decisions for a proposed changefind_postmortems(query)— past incidents touching the same arearelated_history(query)— broader context across all decision types
Use with Cursor and Codex is identical — both speak MCP.
decision_type |
When it surfaces |
|---|---|
decision |
An explicit choice between options |
revert |
Something was tried and rolled back |
convention |
A team rule (e.g. "no in-memory caching on payments") |
incident |
A postmortem-worthy event |
tradeoff |
A deliberate compromise future engineers should understand |
Retrieval is opinionated: reverts and incidents outrank the decisions they invalidate when relevance ties. That's the whole point.
- Vector search via
bge-small-en-v1.5(384-dim, runs locally) - BM25 keyword search via SQLite FTS5
- Fused with Reciprocal Rank Fusion (k=60)
- Then boosted by:
- Source priority:
postmortem ≈ incident > adr > pr > git_commit > markdown - Decision type:
revert ≈ incident > convention > tradeoff > decision - Severity: high-severity incidents float up
- Recency: gentle 18-month half-life decay
- Extractor confidence
- Source priority:
Tuning lives in lore/search.py — every weight is a single constant you can change.
lore demo ["<question>"] # try lore on a preloaded memory, no setup lore init [path] # create .lore/memory.db lore ingest [path] [opts] # walk git + optional --adrs / --postmortems dirs lore ask "<question>" [-k 5] # query the memory lore status # counts by type and source lore mcp [--repo path] # run the MCP server (stdio) lore install claude-code [--repo p] # register lore with Claude Code (writes mcp_settings.json) lore version
| Variable | Purpose |
|---|---|
ANTHROPIC_API_KEY / ANTHROPIC_API_KEYS |
Use Claude for extraction (best quality) |
GROQ_API_KEY / GROQ_API_KEYS |
Use Groq Llama 3.3 (best free option) |
OPENROUTER_API_KEY / OPENROUTER_API_KEYS |
Use OpenRouter (gateway to many free models) |
GEMINI_API_KEY / GEMINI_API_KEYS |
Use Google Gemini (free tier) |
DEEPSEEK_API_KEY / DEEPSEEK_API_KEYS |
Use DeepSeek chat (free credits) |
NVIDIA_NIM_API_KEY / NVIDIA_NIM_API_KEYS |
Use NVIDIA NIM (free tier) |
OLLAMA_HOST |
Override default http://localhost:11434 |
LORE_OLLAMA_MODEL |
Override default qwen2.5:7b |
LORE_OPENROUTER_MODEL |
Override default meta-llama/llama-3.3-70b-instruct:free |
LORE_NVIDIA_MODEL |
Override default meta/llama-3.3-70b-instruct |
LORE_DEEPSEEK_MODEL |
Override default deepseek-chat |
LORE_LLM_PROVIDER |
Force anthropic | groq | openrouter | gemini | deepseek | nvidia | ollama |
v0.1 (current) — git + markdown ingestion, hybrid retrieval, MCP server, four LLM providers, heuristic fallback.
v0.2 — Launch polish
(削除)[shipped]lore install claude-code— one-command MCP config writer (削除ここまで)(削除) Surface fallback events so silent quality regressions are visible (削除ここまで)[shipped](削除)[shipped]lore demo— preloaded memory so you can feel the magic with zero ingestion (削除ここまで)(削除)[shipped].envauto-loading so keys don't need re-exporting (削除ここまで)- LLM-extraction quality eval set (golden 50)
lore install cursor/lore install codex
v0.3 — Distribution
- Linear / Jira / GitHub Discussions connectors
- Slack export ingestion (no auth required at first)
- VS Code extension wrapping the MCP integration
v0.4 — Team mode
- Hosted sync of decision graphs across a team
- Shared organizational memory with per-repo scoping
If you're a team that wants v0.4 early, open an issue.
Pre-alpha. Works end-to-end on real git histories. Quality scales with your extractor (LLM > heuristics) and with how much your team actually writes down.
If lore ask returns mediocre results on your codebase, the most common causes (in order):
- Heuristic-only mode — set any of the API keys above and re-ingest with
--force. - Your team writes one-line commit messages with no rationale. lore can only recall what was once written down.
- The memory is too small — try ingesting ADRs and postmortems too.
PRs welcome. The most valuable contributions right now:
- Connectors for new sources (Notion, Linear, Confluence, etc.)
- Provider plug-ins for additional LLMs (OpenAI, Mistral, OpenRouter)
- Eval datasets — real decision-recall pairs from your own codebase
- IDE / MCP-client integrations
To set up:
git clone https://github.com/Hanishsaini/Lore.git cd Lore python -m venv .venv && source .venv/bin/activate # or .venv\Scripts\activate on Windows pip install -e ".[dev]" pytest # 38 tests, ~1s, no model download
Tests are hermetic — store/search tests use synthetic embedding vectors, so the
suite never pulls the embedding model. Ranking invariants (relevance leads,
boosts only break ties) and the .env/JSON parsers are all covered.
MIT — see LICENSE.
Built with the conviction that AI coding agents will be the new operating layer for software development — and that the agents who remember will quietly outperform the ones who don't.