Skip to main content

LBrain — a dragon coiled around a circuit-etched L

LBrain

PyPI version PyPI downloads Status: Beta BSD-3-Clause Python 3.10-3.13

Beta. Early software from a small team, with no independent security audit yet. Keep backups, as you would with any beta.

Local memory for AI that knows which record to trust.

Your agent can already search your notes. The harder problem starts when your notes disagree.

LBrain retrieves the relevant records, shows where they came from, tells the agent which ones are current, and flags when a record doesn't actually answer the question.

No API key. No account. Your memory stays on your machine.

Watch: the two-minute XPRIZE submission — Metavolve Labs
The two-minute story — our XPRIZE submission.

See it work

Say your project contains two notes.

notes/deploy-flag.md, from March:

Deploys use --safe-mode. Never ship without it.

Then, five months later, notes/deploy-flag-update.md:

--safe-mode is retired. Deploys now use --verify-first.

Supersedes [[deploy-flag]].

Now ask:

$ lbrain query "what flag do deploys use?"

[1] deploy-flag-update · dated 2026-08-02 · binds
    │ --safe-mode is retired. Deploys now use --verify-first.
[2] postgres-choice · dated 2026-05-20 · near-miss
[3] team-lunch · near-miss
[4] deploy-flag · dated 2026-03-14 · SUPERSEDED · binds
    │ Deploys use --safe-mode. Never ship without it.

Real output from the bundled sample corpus, trimmed for width. Reproduce it yourself: the corpus ships in examples/demo-corpus, and the terminal-recording script is examples/demo.tape.

Both deploy notes match the question. Only one is current. LBrain puts the current decision first, keeps the old one visible but marks it SUPERSEDED, and identifies unrelated matches as near-miss. So your agent answers --verify-first, with the record that supports it.

And when nothing answers

Ask the same corpus something it doesn't know:

$ lbrain query "what is our production Redis eviction policy?"

[1] redis-evaluation · dated 2026-06-11 · near-miss
    │ Evaluated Redis vs Memcached for the session cache. Redis won on data
    │ structures and persistence options. Eviction policy discussion deferred
    │ until we see production load.
[2] caching-notes · near-miss
...

Every match comes back flagged near-miss: text about Redis exists, a decision about eviction policy does not, and nothing pretends otherwise. Finding the nearest text and finding an answer are not the same operation.

That's deliberate. We'd rather give the model a little more reason to say "I don't know" than another reason to be confidently wrong.

What can I give it?

Start with Markdown.

Point LBrain at a directory and it indexes the .md files underneath it, subdirectories included. Your notes don't need a schema:

---
date: 2026-08-21
type: decision
---
We picked Postgres over SQLite for the API tier because ...

The frontmatter is optional — plain Markdown works. Dates and record types just give LBrain more to work with.

When one decision replaces another, say so on its own line:

Supersedes [[deploy-flag]].

LBrain keeps both records. The newer decision takes precedence without erasing the history that came before it.

PDFs and Word documents? Not directly, yet. Convert the ones that matter to Markdown and keep the originals as your source of truth. The easy way: you already have an agent — tell it "convert the PDFs in ~/docs that are relevant to our work into markdown notes." Agents are good at this, it takes a minute, and you get to review what your memory is about to be made of. That review is the point: extraction quality varies enough that we'd rather have you glance at a conversion than quietly put mangled text into something your AI will later treat as memory.

Try it

You need Python 3.10–3.13 whose SQLite can load extensions, and ~67 MB of disk for the on-device embedding model. No API key, no account, no cloud service. Check the SQLite requirement first:

python3 -c "import sqlite3; print(hasattr(sqlite3.connect(':memory:'), 'enable_load_extension'))"

If that prints False — Apple's /usr/bin/python3 and the python.org macOS installers are built that way — use Homebrew's (brew install python@3.12). Linux distro packages normally have it enabled.

pip install "lbrain[local]"

lbrain init --source ~/notes
lbrain import
lbrain embed --stale

lbrain query "what did we decide about the deploy flag?"

Rather kick the tires before pointing it at your own notes? Both examples above run against the bundled corpus:

lbrain init --source examples/demo-corpus
lbrain import && lbrain embed --stale
lbrain query "what flag do deploys use?"

Indexing and search run on-device — your documents and queries are never transmitted. The one network call the local path ever makes is the one-time ~67 MB embedding model download (that is the model coming down, not your notes going up); after that, embedding is fully offline.

[!IMPORTANT] Importing an old archive? A cold import of old notes will serve old decisions as current — a bulk copy resets every file date to today, so newest-wins has nothing to order by. Read this first: either vet it, restore the dates, or knowingly run a calibration period.

Connect it to an agent

Start with AGENTS.md — it is written to the agent itself: how to stand LBrain up cleanly for its human, and the contract for consuming what it serves.

# Claude Code
claude mcp add lbrain -- lbrain mcp

# Any client that speaks streamable HTTP
lbrain mcp --transport streamable-http --host 127.0.0.1 --port 7370

Five tools over MCP: semantic recall, exact-phrase search, a save-worthiness check, an action check against your recorded corrections, and corpus statistics. Everything also works from the shell — lbrain query, search, import, doctor.

Terminal presentation

Choose a semantic terminal theme without changing any served content or brain configuration:

LBRAIN_THEME=high-contrast lbrain query "what did we decide?"
LBRAIN_THEME=mono lbrain search "exact phrase"

Themes are classic (default), high-contrast, and mono. They alter ANSI styling only: record order, fences, trust labels, provenance, and exit behavior remain unchanged. An unknown theme reports a warning and visibly falls back to classic.

⚠️ The HTTP server has no built-in auth and exposes the whole corpus. Bind to 127.0.0.1, or put authenticated TLS ingress in front. Never publish it on a public interface.

Why use LBrain?

Because retrieval isn't enough when your history disagrees with itself. A long-running project accumulates stale decisions, corrections, near-duplicates, and things that were true six months ago. Ordinary retrieval finds all of them. LBrain is built to help the agent distinguish among them.

Because evidence should travel with the answer. Retrieved records carry their source, date, status, and whether they actually answer the question — the model has something to cite instead of just something plausible to repeat.

Because your memory should belong to you. Local-first: SQLite, sqlite-vec, FTS5. No account, no cloud database, no hosted memory service.

Change your model. Change your agent. Change your tools. Keep the history.

What LBrain doesn't do

LBrain isn't a hallucination cure and it doesn't make a model smarter. It governs the records retrieved from your corpus; it can't control facts a model invents from its own weights, or guarantee what the model does with good evidence. And its admissibility check is deliberately conservative, so it will sometimes flag a record you'd have accepted. That's a trade we're willing to make: we'd rather surface uncertainty than manufacture confidence.

How it works

  • Hybrid retrieval — vector + BM25 keyword, fused by reciprocal rank fusion.
  • Deterministic admissibility check — classifies each record against the question as admissible, near-miss, or irrelevant, without a second model call.
  • Supersession — a replaced note stops being served but is never deleted. Persistence and activation are separate concerns.
  • Honest dating — each record states whether its date came from the content, the filename, or the filesystem. No invented timestamps. Precedence, strongest first: a **Last Updated**: header (verified) → an as of <date> in the body → frontmatter date: or a date in the filename (dated) → mtime (file-dated, the weakest — it moves on any edit).

    Copying a corpus reages it. cp, a git clone, and most sync tools reset mtime to now. Put a date: in the frontmatter and the claim date rides inside the file — it survives the move.

  • Untrusted-data fencing — retrieved text is fenced and labelled as data, never instructions, so a note can't hijack the agent reading it.

Research behind it

LBrain grew out of a simple question: what happens when the correct answer is present, but the surrounding records make it easy to use the wrong one?

We profiled eight model architectures from seven organizations on the same near-domain retrieval task. Failure rates swung 1.3% / 35.7% / 16.7% depending only on how the records were structured — a 34.4-point absolute difference — while architecture explained roughly none of the variance, with identical failure ordering in 8 of 8 models. Changing models didn't remove the effect. Telling the model not to guess didn't either. So the fix belongs before generation, on the input side, and it has to be deterministic.

The work is published as DOI-backed preprints and datasets, and the experiments are available for others to challenge: lbrain.ai/papers. We also killed three of our own claims while building this; the retractions are published with the findings.

Related work — read these too

Four 2026 papers staked adjacent ground while we were building, and they deserve the citation:

  • Deceptive Grounding — Caruzzo, Yoo & Kim (arXiv:2607.09349): named and measured the failure mode — RAG responses that pass standard quality checks while attributing evidence to the wrong entity, in 8–87% of cases across 13 models.
  • MemStrata (arXiv:2606.26511): deterministic supersession rules over a bi-temporal ledger, against stale-fact errors on evolving knowledge.
  • Engram (arXiv:2606.09900): a bi-temporal memory graph tracking provenance and contradictions — a lean retrieved context beats the full history.
  • Don't Ask the LLM to Track Freshness (arXiv:2606.01435): conflict resolution belongs in deterministic code, not model judgment.

What our 8-model matrix adds is the controlled variable: the serving format, not the model, is the controlling variable — the axis these works leave open, and the axis LBrain operates on.

Embeddings

Provider Setup Where your text goes
local (default) none nowhere — on-device ONNX, 384-dim (one-time model download)
gemini your own key Google, under your key
openai your own key OpenAI, under your key

lbrain init uses local unless you pass a key on the command line. A key sitting in your environment is never treated as consent to send your corpus to a third party. Every network call LBrain can make is listed in the Privacy Policy, §3. See docs/KEYS.md.

Known issues — read this before filing

Most reports land in one of these. Checking first is faster than waiting for us.

Symptom Cause / fix
TOMLDecodeError on any command right after init, on Windows You are on 0.1.0, which is yanked. It wrote an unparseable config.toml on Windows paths. pip install -U lbrain (≥ 0.1.1), then delete ~/.lbrain/config.toml and re-run init.
UnicodeEncodeError during init, on Windows Same fix — 0.1.0 wrote template files in the locale encoding. Fixed in 0.1.1.
Build errors installing [local] (fastembed / onnxruntime / sqlite-vec) Native wheels. Upgrade pip first (pip install -U pip), which resolves nearly all of these. On Windows a wheel may be missing for a very new Python — 3.10–3.13 are supported; 3.14+ may have no wheel yet.
First embed pauses, then works One-time ~67 MB model download. It is the model coming down, not your notes going up. Offline after that.
"It says my provider is Gemini but I never set that" Run lbrain doctor. It marks every setting [config] or [DEFAULT]. In 0.1.0 an API key in your environment silently selected a hosted provider; 0.1.1 refuses to treat an ambient key as consent.
Results changed after switching provider Changing provider changes the vector space. Re-embed (lbrain embed --all); doctor exits non-zero on drift until you do.
A note is missing from results but the file exists Usually imported-but-not-embedded. lbrain stats shows the gap; lbrain embed --stale closes it.
I edited only the YAML frontmatter and nothing changed Known in 0.1.1 and earlier: change detection hashed the body only, so type: / description: edits were skipped and the old value persisted. Fixed in the next release — import will report meta-refreshed: N. Workaround today: touch the body (a trailing newline is enough) to force a re-index.
Two brains on one machine interfering Use LBRAIN_HOME=/path/to/brain2 per invocation.

Not listed? Then it is worth an issue — please use the template, it asks for lbrain doctor --json.

Something wrong?

lbrain doctor

Prints the effective config with per-setting provenance — [config] vs [DEFAULT] — and whether your stored vectors match your current embedding settings. Include its output in any issue.

docs/DEVELOPER-NOTES.md covers the symptoms that look like bugs and aren't — switching embedding providers on an existing brain, two brains on one machine, imported-but-not-embedded records, and why a note can vanish from results without being deleted.

Agent identity

A brain that persists can also know whose it is. Identity is a first-class layer in LBrain — and deliberately optional: an anonymous install stays fully functional forever. Identity accretes onto a brain; it never gates one.

lbrain register --name jarvis --address <your-key-address>   # bind a gcx:// name to this brain
lbrain whoami                                                # who is this brain, what is it trusted for?
  • register is free. It persists the identity to ~/.lbrain/identity.json (0600); from then on whoami and the MCP lair_whoami report this brain as that identity — which matters the moment more than one agent, tool, or machine touches your memory.
  • whoami answers the question an agent should ask before relying on retrieved records: what am I reading, how does it serve, and who does it claim to be.
  • Since 0.1.10 the write path honors identity: a process claiming a seat (LBRAIN_SEAT) cannot write into a brain whose identity doesn't match, and a config resolving to a foreign database is refused with both paths named. "Wrote into the wrong brain" stopped being a documentation warning and became an engine refusal.

The name can outlive your accounts, too: lbrain.ai is the project home, and a permanent gcx:// name — yours, portable across tools, models, and machines — can be claimed at lbrain.ai/claim.html.

More

Truth hierarchy: your source files are authoritative; the index is a derivative cache. If they disagree, trust the file and re-run lbrain import && lbrain embed --stale.

If LBrain earns a place in your setup, a ⭐ on this repo is the signal that helps the next person find it.

License

BSD-3-Clause — see LICENSE. Copyright (c) 2026 Metavolve Labs, Inc.

Patents pending. The licence covers the code; it does not grant patent rights.

Metadata

Release files for lbrain 0.1.10.post1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lbrain 0.1.10.post1
File Size Uploaded
lbrain-0.1.10.post1.tar.gz 388.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lbrain 0.1.10.post1
File Interpreter ABI Platform
lbrain-0.1.10.post1-py3-none-any.whl Python 3 none any Details

Total release size: 665.4 kB

Release files / lbrain-0.1.10.post1.tar.gz

Download URL lbrain-0.1.10.post1.tar.gz
Size 388.7 kB
Tags Source
SHA-256 checksum
How to use checksums
5ba2eaa8fd1690284c52d4be9a1d6e67474e082ba25e0eabc05a1be12a581f24
BLAKE2b-256 checksum
How to use checksums
4db212a445ca2068afefbfaa11994b5419b874607baf26166adfac708f4dff66
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release files / lbrain-0.1.10.post1-py3-none-any.whl

Download URL lbrain-0.1.10.post1-py3-none-any.whl
Size 276.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
649c439a1a3541415e0b086a5c4649fc03fa7a922a6dd10ec9889fa6b0f90df4
BLAKE2b-256 checksum
How to use checksums
26bf70f8f75055cfd8efb4a34f9812ba1ded606880c92bc601fce8edd82796ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 2, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.10.post1 This release

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page