Your codebase's memory. Persistent organizational memory for AI coding agents.
Project description
lore
Your codebase's memory. Persistent organizational memory for AI coding agents — so they stop repeating your team's past mistakes.
AI 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
The killer demo
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.
Why lore exists
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.
How it works
┌──────────────────┐ ┌─────────────┐ ┌────────────────┐
│ 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
Install
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.
Try it in 60 seconds (no API key, no setup)
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.)
Quickstart on your own repo
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).
Also ingest ADRs and postmortems
These get priority at retrieval time — formal writeups outrank random commit messages.
lore ingest . --adrs docs/adr --postmortems docs/postmortems
Pick an LLM (or none)
lore 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.
Transparent fallback
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.
Use with Claude Code
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.
What lore tracks
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.
Retrieval is hybrid and opinionated
- 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.
CLI reference
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
Configuration (environment variables)
| 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 |
Roadmap
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 writerSurface 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.
Status
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.
Contributing
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.
License
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.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codelore-0.1.0.tar.gz.
File metadata
- Download URL: codelore-0.1.0.tar.gz
- Upload date:
- Size: 41.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b676bcbca8e1058b7c0525f2e82592ba43ce3c33f71129104aa89347955f07ca
|
|
| MD5 |
3d7421aae66f5e1e3bacbdf40ce8fa82
|
|
| BLAKE2b-256 |
001d394ff97fd818c1a31eb5b8c1d212aca3b5fbdd72c788a478baf2e3131ebb
|
File details
Details for the file codelore-0.1.0-py3-none-any.whl.
File metadata
- Download URL: codelore-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2ae8fa0370df87ca2bed1d5d08a81d36ae984adc073e6c3fc028a89fa3c1bbd
|
|
| MD5 |
21e7e3962d2fd9accd592389fd7f79c3
|
|
| BLAKE2b-256 |
a0b3748760b0c746e56af4a68cb59b5b3dc5760c2713a11869af1ca5c7583dc9
|