{"id":"b466eeff-07ee-4c08-b53f-dfebadd8e2c7","slug":"hanishsaini-lore","kind":"mcp","name":"Lore","summary":"Persistent decision memory for AI coding agents (Claude Code, Cursor, Codex) over MCP. Local-first, open-source.","owner":"Hanishsaini","repoUrl":"https://github.com/Hanishsaini/Lore","license":"MIT","licenseTier":"permissive","trust":"community","stars":1,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-05-19T17:11:07.000Z","addedAt":"2026-10-21T08:54:58.294Z","logoUrl":"https://avatars.githubusercontent.com/u/135587474?u=833fa59114bf6e31358d98a1c5f68e4f13d2f60a&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["developer-tools","memory-knowledge","databases"],"tags":["ai-agents","ai-coding-assistant","anthropic","claude-code","cursor","developer-tools","llm-tools","memory"],"runtime":"python","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-23T03:40:13.910Z","sample":false,"url":"https://conduits.dev/tools/hanishsaini-lore","language":"Python","transports":["stdio"],"install":{"pypi":"codelore"},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# lore\n\n> **Your codebase's memory.**\n> Persistent organizational memory for AI coding agents — so they stop repeating your team's past mistakes.\n\n[![PyPI version](https://img.shields.io/pypi/v/codelore.svg)](https://pypi.org/project/codelore/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)\n[![MCP Compatible](https://img.shields.io/badge/MCP-compatible-7c3aed)](https://modelcontextprotocol.io)\n[![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)]()\n\n<img width=\"400\" height=\"208\" alt=\"lore demo\" src=\"https://github.com/user-attachments/assets/56b4eb70-981f-442b-aff1-a727afea7e7d\" />\n\nAI 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.\n\n**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:\n\n- what your team has already tried and reverted\n- which conventions exist and why\n- which postmortems are sitting one mistake away from repeating\n\n---\n\n## The killer demo\n\n```text\nYou    >  Add Redis caching to the payment endpoint.\n\nClaude > Before I touch this, I checked lore — 3 relevant past decisions:\n\n         1. [revert]      Redis caching reverted on payment writes\n            Why:          Stripe webhook race condition caused duplicate charges\n            commit a8f3b2c1  ·  2026-03-12\n\n         2. [convention]  No in-memory caching on payment write paths\n            Why:           Codifies ADR-014 so new contributors don't reintroduce the bug\n            docs/adr/ADR-014.md  ·  2026-04-02\n\n         3. [incident]    Duplicate-charge incident POST-221\n            Why:          Stale cache during partial outage\n            docs/postmortems/POST-221.md  ·  2026-05-09  ·  severity: high\n\n         Suggested alternative: database query caching\n         (see services/orders/cache.py)\n```\n\nThat output isn't from a chatbot — it's a real MCP tool call that lore exposes to your agent.\n\n---\n\n## Why lore exists\n\nYour AI agent has incredible coverage of:\n\n- syntax\n- frameworks\n- public APIs\n- general code patterns\n\nIt has **zero coverage** of the thing that actually matters in a mature codebase:\n\n- *Why* a migration was rolled back two months ago\n- *Why* Kafka was rejected in favor of Postgres LISTEN/NOTIFY\n- *Why* there's a lint rule banning in-memory caches on `/payments`\n- *Why* every onboarding engineer has to be told the same five things in their first week\n\nThat gap is where lore lives. The product thesis: **the next breakout layer in AI tooling is persistent organizational reasoning, not better autocomplete.**\n\n---\n\n## How it works\n\n```\n    ┌──────────────────┐  ┌─────────────┐  ┌────────────────┐\n    │   Git history    │  │ ADRs        │  │ Postmortems    │\n    │  (PRs, commits)  │  │ (markdown)  │  │  (markdown)    │\n    └────────┬─────────┘  └──────┬──────┘  └────────┬───────┘\n             │                   │                  │\n             └───────────┬───────┴──────────────────┘\n                         ▼\n              ┌────────────────────────┐\n              │   Signal pre-filter    │   drops ~80% of routine work\n              └──────────┬─────────────┘\n                         ▼\n              ┌────────────────────────┐\n              │  Decision extraction   │   LLM (Anthropic | Groq | Gemini | Ollama)\n              │  (or heuristic mode)   │   or pattern-based, zero-setup\n              └──────────┬─────────────┘\n                         ▼\n              ┌────────────────────────┐\n              │   Embed (bge-small)    │\n              └──────────┬─────────────┘\n                         ▼\n              ┌────────────────────────┐\n              │  SQLite + sqlite-vec   │   local-first, your data never leaves\n              │     + FTS5 (BM25)      │   your machine unless you choose so\n              └──────────┬─────────────┘\n                         ▼\n              ┌────────────────────────┐\n              │   Hybrid retrieval     │   vector ⊕ keyword via RRF,\n              │   (RRF + boosts)       │   then source / type / severity / recency\n              └──────────┬─────────────┘\n                         ▼\n              ┌────────────────────────┐\n              │      MCP server        │   recall_decision, find_postmortems,\n              │     (stdio transport)  │   related_history\n              └──────────┬─────────────┘\n                         ▼\n          Claude Code  ·  Cursor  ·  Codex  ·  any MCP client\n```\n\n---\n\n## Install\n\n```bash\npip install codelore\n```\n\n> The package is `codelore`; the command it installs is `lore`.\n\nOr from source:\n\n```bash\ngit clone https://github.com/Hanishsaini/Lore.git\ncd Lore\npip install -e .\n```\n\nPython 3.11+ required.\n\n---\n\n## Try it in 60 seconds (no API key, no setup)\n\n```bash\npip install codelore\nlore demo\n```\n\n`lore demo` loads a preloaded memory of a fictional payments platform and answers\nthe signature question against it — so you can feel the product before pointing it\nat your own code. Ask it anything:\n\n```bash\nlore demo \"why did we drop Kafka?\"\nlore demo \"how should we store money?\"\n```\n\n(First run downloads a small embedding model, ~80 MB. No LLM or API key needed —\nthe demo decisions are pre-extracted.)\n\n## Quickstart on your own repo\n\n```bash\ncd your-project/\nlore init\nlore ingest .\nlore ask \"should I cache payment writes?\"\n```\n\nThat's it. The first run downloads a small embedding model (~80 MB).\n\n### Also ingest ADRs and postmortems\n\nThese get **priority** at retrieval time — formal writeups outrank random commit messages.\n\n```bash\nlore ingest . --adrs docs/adr --postmortems docs/postmortems\n```\n\n---\n\n## Pick an LLM (or none)\n\nlore runs with whatever you have. It auto-detects in this order:\n\n| Provider | Cost | Quality | Setup |\n|---|---|---|---|\n| **Anthropic Claude** | Paid | Highest | `export ANTHROPIC_API_KEY=…` |\n| **Groq** | **Free tier** | High | `export GROQ_API_KEY=…` ([signup, no credit card](https://console.groq.com)) |\n| **OpenRouter** | **Free models** | High | `export OPENROUTER_API_KEY=…` ([signup](https://openrouter.ai/keys)) |\n| **Google Gemini** | **Free tier** | High | `export GEMINI_API_KEY=…` ([signup](https://aistudio.google.com)) |\n| **DeepSeek** | Free credits | High | `export DEEPSEEK_API_KEY=…` ([signup](https://platform.deepseek.com/api_keys)) |\n| **NVIDIA NIM** | **Free tier** | High | `export NVIDIA_NIM_API_KEY=…` ([signup](https://build.nvidia.com/settings/api-keys)) |\n| **Ollama** (local) | Free | Medium | `ollama serve` + `ollama pull qwen2.5:7b` |\n| Heuristic fallback | — | Low | nothing — works out of the box |\n\n**Or skip exports entirely — use a `.env` file:**\n\nlore auto-loads `./.env` (per-repo) and `~/.lore.env` (global) on every run.\nReal environment variables always win, so a `.env` never clobbers a shell export.\n\n```bash\ncp .env.example ~/.lore.env     # then fill in one key\necho 'GROQ_API_KEY=gsk_...' >> ~/.lore.env\n```\n\n`.env` is gitignored by default — your keys never get committed.\n\n**Force a specific provider:**\n\n```bash\nexport LORE_LLM_PROVIDER=openrouter   # or: anthropic, groq, gemini, deepseek, nvidia, ollama\n```\n\n**Override the model on a provider:**\n\n```bash\nexport LORE_OPENROUTER_MODEL=deepseek/deepseek-chat-v3:free\nexport LORE_NVIDIA_MODEL=meta/llama-3.3-70b-instruct\nexport LORE_DEEPSEEK_MODEL=deepseek-chat\nexport LORE_OLLAMA_MODEL=qwen2.5:14b\n```\n\n**Stitch multiple free keys together** (useful when one rate-limits):\n\n```bash\nexport GROQ_API_KEYS=\"key1,key2,key3\"\n# lore rotates through them automatically on 429s\n```\n\nThe same plural form works for every cloud provider: `ANTHROPIC_API_KEYS`,\n`OPENROUTER_API_KEYS`, `GEMINI_API_KEYS`, `DEEPSEEK_API_KEYS`, `NVIDIA_NIM_API_KEYS`.\n\n### Transparent fallback\n\nIf the active LLM rate-limits, returns malformed JSON, or hits a network error,\nlore falls back to heuristic extraction for that one candidate — and **tells you\nabout it**. You'll see a stderr warning on the first event plus a per-run\nsummary at the end of ingestion:\n\n```text\n[WARN] 3/127 candidates fell back to heuristics (rate_limit=2, bad_json=1).\nQuality on those entries will be lower than the configured LLM.\n```\n\nThat way you can't accidentally ship a \"fully LLM-extracted\" memory that\nwas 40% heuristic without knowing it.\n\n---\n\n## Use with Claude Code\n\n**One command:**\n\n```bash\nlore install claude-code\n```\n\nThat writes (or merges into) `~/.claude/mcp_settings.json` with an entry\npointing at your current directory. Restart Claude Code and you're done.\n\nIf you want to manage multiple lore instances (e.g. one per repo), pass\n`--name` and `--repo`:\n\n```bash\nlore install claude-code --name lore-payments --repo /path/to/payments-service\nlore install claude-code --name lore-platform --repo /path/to/platform\n```\n\nPrefer to edit the config by hand? Run the server directly:\n\n```bash\nlore mcp --repo /abs/path/to/your/project\n```\n\nAnd add to `~/.claude/mcp_settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"lore\": {\n      \"command\": \"lore\",\n      \"args\": [\"mcp\", \"--repo\", \"/abs/path/to/your/project\"]\n    }\n  }\n}\n```\n\nOnce installed, Claude Code can call:\n\n- `recall_decision(query)` — relevant past decisions for a proposed change\n- `find_postmortems(query)` — past incidents touching the same area\n- `related_history(query)` — broader context across all decision types\n\nUse with **Cursor** and **Codex** is identical — both speak MCP.\n\n---\n\n## What lore tracks\n\n| `decision_type` | When it surfaces                                            |\n|----------------|-------------------------------------------------------------|\n| `decision`     | An explicit choice between options                          |\n| `revert`       | Something was tried and rolled back                         |\n| `convention`   | A team rule (e.g. \"no in-memory caching on payments\")       |\n| `incident`     | A postmortem-worthy event                                   |\n| `tradeoff`     | A deliberate compromise future engineers should understand  |\n\nRetrieval is opinionated: **reverts and incidents outrank the decisions they invalidate** when relevance ties. That's the whole point.\n\n---\n\n## Retrieval is hybrid and opinionated\n\n- **Vector** search via `bge-small-en-v1.5` (384-dim, runs locally)\n- **BM25** keyword search via SQLite FTS5\n- Fused with **Reciprocal Rank Fusion** (k=60)\n- Then boosted by:\n  - **Source priority:** `postmortem ≈ incident > adr > pr > git_commit > markdown`\n  - **Decision type:** `revert ≈ incident > convention > tradeoff > decision`\n  - **Severity:** high-severity incidents float up\n  - **Recency:** gentle 18-month half-life decay\n  - **Extractor confidence**\n\nTuning lives in [`lore/search.py`](lore/search.py) — every weight is a single constant you can change.\n\n---\n\n## CLI reference\n\n```bash\nlore demo [\"<question>\"]            # try lore on a preloaded memory, no setup\nlore init [path]                    # create .lore/memory.db\nlore ingest [path] [opts]           # walk git + optional --adrs / --postmortems dirs\nlore ask \"<question>\" [-k 5]        # query the memory\nlore status                         # counts by type and source\nlore mcp [--repo path]              # run the MCP server (stdio)\nlore install claude-code [--repo p] # register lore with Claude Code (writes mcp_settings.json)\nlore version\n```\n\n---\n\n## Configuration (environment variables)\n\n| Variable | Purpose |\n|---|---|\n| `ANTHROPIC_API_KEY` / `ANTHROPIC_API_KEYS` | Use Claude for extraction (best quality) |\n| `GROQ_API_KEY` / `GROQ_API_KEYS` | Use Groq Llama 3.3 (best free option) |\n| `OPENROUTER_API_KEY` / `OPENROUTER_API_KEYS` | Use OpenRouter (gateway to many free models) |\n| `GEMINI_API_KEY` / `GEMINI_API_KEYS` | Use Google Gemini (free tier) |\n| `DEEPSEEK_API_KEY` / `DEEPSEEK_API_KEYS` | Use DeepSeek chat (free credits) |\n| `NVIDIA_NIM_API_KEY` / `NVIDIA_NIM_API_KEYS` | Use NVIDIA NIM (free tier) |\n| `OLLAMA_HOST` | Override default `http://localhost:11434` |\n| `LORE_OLLAMA_MODEL` | Override default `qwen2.5:7b` |\n| `LORE_OPENROUTER_MODEL` | Override default `meta-llama/llama-3.3-70b-instruct:free` |\n| `LORE_NVIDIA_MODEL` | Override default `meta/llama-3.3-70b-instruct` |\n| `LORE_DEEPSEEK_MODEL` | Override default `deepseek-chat` |\n| `LORE_LLM_PROVIDER` | Force `anthropic` \\| `groq` \\| `openrouter` \\| `gemini` \\| `deepseek` \\| `nvidia` \\| `ollama` |\n\n---\n\n## Roadmap\n\n**v0.1 (current)** — git + markdown ingestion, hybrid retrieval, MCP server, four LLM providers, heuristic fallback.\n\n**v0.2 — Launch polish**\n- ~~`lore install claude-code` — one-command MCP config writer~~ **[shipped]**\n- ~~Surface fallback events so silent quality regressions are visible~~ **[shipped]**\n- ~~`lore demo` — preloaded memory so you can feel the magic with zero ingestion~~ **[shipped]**\n- ~~`.env` auto-loading so keys don't need re-exporting~~ **[shipped]**\n- LLM-extraction quality eval set (golden 50)\n- `lore install cursor` / `lore install codex`\n\n**v0.3 — Distribution**\n- Linear / Jira / GitHub Discussions connectors\n- Slack export ingestion (no auth required at first)\n- VS Code extension wrapping the MCP integration\n\n**v0.4 — Team mode**\n- Hosted sync of decision graphs across a team\n- Shared organizational memory with per-repo scoping\n\nIf you're a team that wants `v0.4` early, open an issue.\n\n---\n\n## Status\n\nPre-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.\n\nIf `lore ask` returns mediocre results on your codebase, the most common causes (in order):\n\n1. Heuristic-only mode — set any of the API keys above and re-ingest with `--force`.\n2. Your team writes one-line commit messages with no rationale. lore can only recall what was once written down.\n3. The memory is too small — try ingesting ADRs and postmortems too.\n\n---\n\n## Contributing\n\nPRs welcome. The most valuable contributions right now:\n\n- Connectors for new sources (Notion, Linear, Confluence, etc.)\n- Provider plug-ins for additional LLMs (OpenAI, Mistral, OpenRouter)\n- Eval datasets — real decision-recall pairs from your own codebase\n- IDE / MCP-client integrations\n\nTo set up:\n\n```bash\ngit clone https://github.com/Hanishsaini/Lore.git\ncd Lore\npython -m venv .venv && source .venv/bin/activate     # or .venv\\Scripts\\activate on Windows\npip install -e \".[dev]\"\npytest                                                 # 38 tests, ~1s, no model download\n```\n\nTests are hermetic — store/search tests use synthetic embedding vectors, so the\nsuite never pulls the embedding model. Ranking invariants (relevance leads,\nboosts only break ties) and the `.env`/JSON parsers are all covered.\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n---\n\n> 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.\n"}