Skip to content
Conduit

mcp server

Lore

Persistent decision memory for AI coding agents (Claude Code, Cursor, Codex) over MCP. Local-first, open-source.

Hanishsaini/Lorecommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "hanishsaini-lore": {
      "command": "uvx",
      "args": [
        "codelore"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 23, 2026

lore

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

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 is lore.

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:

ProviderCostQualitySetup
Anthropic ClaudePaidHighestexport ANTHROPIC_API_KEY=…
GroqFree tierHighexport GROQ_API_KEY=… (signup, no credit card)
OpenRouterFree modelsHighexport OPENROUTER_API_KEY=… (signup)
Google GeminiFree tierHighexport GEMINI_API_KEY=… (signup)
DeepSeekFree creditsHighexport DEEPSEEK_API_KEY=… (signup)
NVIDIA NIMFree tierHighexport NVIDIA_NIM_API_KEY=… (signup)
Ollama (local)FreeMediumollama serve + ollama pull qwen2.5:7b
Heuristic fallback—Lownothing — 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 change
  • find_postmortems(query) — past incidents touching the same area
  • related_history(query) — broader context across all decision types

Use with Cursor and Codex is identical — both speak MCP.


What lore tracks

decision_typeWhen it surfaces
decisionAn explicit choice between options
revertSomething was tried and rolled back
conventionA team rule (e.g. "no in-memory caching on payments")
incidentA postmortem-worthy event
tradeoffA 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

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)

VariablePurpose
ANTHROPIC_API_KEY / ANTHROPIC_API_KEYSUse Claude for extraction (best quality)
GROQ_API_KEY / GROQ_API_KEYSUse Groq Llama 3.3 (best free option)
OPENROUTER_API_KEY / OPENROUTER_API_KEYSUse OpenRouter (gateway to many free models)
GEMINI_API_KEY / GEMINI_API_KEYSUse Google Gemini (free tier)
DEEPSEEK_API_KEY / DEEPSEEK_API_KEYSUse DeepSeek chat (free credits)
NVIDIA_NIM_API_KEY / NVIDIA_NIM_API_KEYSUse NVIDIA NIM (free tier)
OLLAMA_HOSTOverride default http://localhost:11434
LORE_OLLAMA_MODELOverride default qwen2.5:7b
LORE_OPENROUTER_MODELOverride default meta-llama/llama-3.3-70b-instruct:free
LORE_NVIDIA_MODELOverride default meta/llama-3.3-70b-instruct
LORE_DEEPSEEK_MODELOverride default deepseek-chat
LORE_LLM_PROVIDERForce 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

  • lore install claude-code — one-command MCP config writer [shipped]
  • Surface fallback events so silent quality regressions are visible [shipped]
  • lore demo — preloaded memory so you can feel the magic with zero ingestion [shipped]
  • .env auto-loading so keys don't need re-exporting [shipped]
  • 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):

  1. Heuristic-only mode — set any of the API keys above and re-ingest with --force.
  2. Your team writes one-line commit messages with no rationale. lore can only recall what was once written down.
  3. 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.

↑↓ navigate openesc close