Self-hosted family memory for the assistant you already use, over MCP
Project description
Homelore
Self-hosted family memory for the assistant you already use.
Families accumulate a huge amount of small, precious knowledge — shoe sizes, birthdays, who said what at the lake house, what a child wants to learn next — and it lives nowhere. When you need it ("what size shoes does Mia wear now?"), you either can't find it or find a stale version. General-purpose assistants can't help because they know nothing about your family, and no one wants to hand their family's private life to a hosted memory startup.
Homelore fixes this without adding a single new app to your life. It runs as an MCP server on your own machine: you tell your assistant things in passing ("remember that Mia moved up to size 32") and ask it things later, and Homelore supplies the memory. Everything lives in one SQLite file you own.
Quickstart
You need uv
(curl -LsSf https://astral.sh/uv/install.sh | sh) and one API key
(Anthropic, used only to understand new
memories — see Privacy). Homelore runs anywhere uvx runs; no
install step needed.
Claude Code:
claude mcp add homelore --scope user -- uvx homelore serve
Claude Desktop (or any MCP client that takes a JSON config) — add to
claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"homelore": {
"command": "uvx",
"args": ["homelore", "serve"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
}
}
}
ANTHROPIC_API_KEY must reach the server: pass it in the client config as
above, or export it in the environment the client starts from. Then just talk
to your assistant:
You: Remember that Mia moved up to shoe size 32. Assistant: Saved it.
That's the whole workflow. The first start downloads a small local embedding model (one-time); after that, retrieval works offline.
Your memories live in a single SQLite file (homelore.db in the directory
the server is started from — for an MCP client launched inside a project,
that's the project folder; set HOMELORE_DB_PATH or pass --db-path to move
it). Backup is copying one file.
The five tools
Your assistant picks the right tool from your phrasing — you never name them.
remember — save anything worth keeping, told in passing. Each memory is
stored with a timestamp and your name, and a past event can carry the date it
happened rather than the date you typed it:
You: Remember that last summer we scattered wildflower seeds along the back fence — that was around June 10th. Assistant: Saved, dated June 10, 2025.
recall — specific questions, answered from your memories with
provenance, so you can judge how fresh the answer is. Changing facts return
their latest value:
You: What size shoes does Mia wear? Assistant: Size 32 — you recorded "Mia moved up to shoe size 32" on July 13, 2026. (That supersedes the size 31 note from January.)
profile — everything known about one person, place, or thing, reachable
by any name the family uses ("Ana", "my wife", "grandma" — same person):
You: Who is Noor? Assistant: Noor is one of Freya's best friends. She has a serious nut allergy (Espen noted it in October 2025), her mom shared a nut-free brownie recipe, and she's already invited to the dinosaur dig birthday…
upcoming_dates — birthdays, anniversaries, and other special dates in a
window. This answer is computed from a deterministic index, never search: it
is exact and complete, with ages and anniversary years worked out for you:
You: Any family dates in the next few weeks? Assistant: Two: your wedding anniversary — 14 years — on December 30th, and Freya turns 8 on January 2nd.
reflect — broad questions no single memory can answer, synthesized
across your whole history and grounded in the actual memories:
You: What themes keep coming up with the kids this year? Assistant: Water, mostly — Otto's swim club took off, from first lap to a regionals medal. And Freya's fox era has officially given way to dinosaurs, full time…
How it's built
Memories are the source of truth. Every memory is an append-only entry —
text, timestamp, author — that the system never rewrites; newer facts
supersede older ones at retrieval time, not by editing history. Everything
else — the entity/relation graph, the dates index, the community summaries —
is a derived, disposable index: it can be dropped and rebuilt from the
memories at any time, so an extraction bug can never corrupt family history,
and every improvement to extraction retroactively benefits your existing data
(homelore reindex --full). This is the load-bearing design decision; the
full reasoning is in ADR 0001.
Right-sized storage. A family's memory is precious, not big. Everything — memory log, vector index, graph, dates, summaries — lives in one SQLite file, and graph traversal happens in memory. No database server, no vector-store service, nothing to operate.
Deterministic where correctness is non-negotiable, retrieval where recall matters. Date questions are answered by exact query over a structured index — a missed birthday because a search "happened to miss" is not acceptable. Open-ended questions go through hybrid retrieval: vector search over memories, expanded through the graph neighborhood, ranked with recency awareness so a superseded fact loses to its successor.
Graceful degradation. If the extraction model is unreachable, your memory is still saved and marked for retry — an outage never loses family history. Without an API key, everything already stored keeps answering; only writing new memories and rebuilding summaries need the key, and they say so clearly.
Privacy
- Self-hosted: all family data is a single SQLite file on your machine. Nothing is synced anywhere.
- Local embeddings: vector search runs on a local ONNX model. Your questions are never sent to a cloud service, and retrieval works offline.
- One provider, one direction: exactly one API key (Anthropic), used to extract structure from new memories and to write summaries. That is the complete list of what leaves your machine.
Try it with the Demo Family
The repository ships with the Demo Family — Maren, Espen, their kids Otto and Freya, Farmor Ingrid, and Waffle the dog — 55 fictional memories spanning two and a half years, so you can try the full experience without using real family data.
export ANTHROPIC_API_KEY=sk-ant-...
uvx homelore demo # builds ./homelore-demo.db from the fixtures
Point your MCP client at it (e.g. claude mcp add homelore-demo -- uvx homelore serve --db-path /path/to/homelore-demo.db) and ask:
- "What is Noor allergic to?" — precise recall with provenance.
- "Who is Ingrid?" — a profile assembled across aliases ("Farmor").
- "Whose birthdays are coming up?" — exact dates, ages computed (Ingrid is a leap-day baby; Homelore gets that right).
- "How did Otto's swimming year go?" — synthesis across a dozen memories.
The demo builds into its own file, deliberately never your real database.
The CLI
The same operations, without a chat in front of them:
homelore serve # run the MCP server over stdio
homelore import memories.jsonl # bulk-seed from existing notes (one JSON object per line)
homelore reindex # retry failed extractions, heal the indexes
homelore reindex --full # re-extract everything (after extraction improvements)
homelore demo # build the Demo Family instance
The import format is one JSON object per line: text, author, and optional
created_at / event_date. Imported memories go through the same write path
as ones told to the assistant. reindex only ever rebuilds derived indexes —
it never touches the memories themselves, and it's safe to interrupt and
re-run.
Roadmap
- Family server mode — Streamable HTTP transport with authentication, so the whole family shares one memory from every device.
- Forgetting and editing — deliberate removal and correction semantics for a store that is otherwise append-only.
- Local extraction — the extractor is already behind a small interface; a fully local backend (e.g. Ollama) would make Homelore need zero API keys.
Development
git clone https://github.com/AdrianZaplata/homelore && cd homelore
uv sync
uv run pytest # keyless and deterministic — no API key, no model downloads
uv run ruff check . && uv run pyright
uv run python -m homelore.evals # retrieval-quality scorecard (needs an API key)
The test suite runs against fake extraction/embedding adapters and a real SQLite database. Retrieval quality is measured, not guessed: the eval harness builds the Demo Family with real adapters and scores a 50-question golden set per tool.
License
MIT.
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 homelore-0.2.0.tar.gz.
File metadata
- Download URL: homelore-0.2.0.tar.gz
- Upload date:
- Size: 38.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2aa8d42c8f55ad713c4c8d64637369f1e54314f815de374287dc4acfc2d49f3a
|
|
| MD5 |
403d11f1f689b20517d54ad7337aa756
|
|
| BLAKE2b-256 |
5b698572dbdd348cda16e71889b9e19604763fa79e038bebfd79372fa1c88be2
|
Provenance
The following attestation bundles were made for homelore-0.2.0.tar.gz:
Publisher:
release.yml on AdrianZaplata/homelore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
homelore-0.2.0.tar.gz -
Subject digest:
2aa8d42c8f55ad713c4c8d64637369f1e54314f815de374287dc4acfc2d49f3a - Sigstore transparency entry: 2181709679
- Sigstore integration time:
-
Permalink:
AdrianZaplata/homelore@23962be98f6dcf7f351630dd42fafeee69e8298f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/AdrianZaplata
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@23962be98f6dcf7f351630dd42fafeee69e8298f -
Trigger Event:
push
-
Statement type:
File details
Details for the file homelore-0.2.0-py3-none-any.whl.
File metadata
- Download URL: homelore-0.2.0-py3-none-any.whl
- Upload date:
- Size: 49.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df402ae1c34a353ec11c5e032b90dea99454cde48610771248a90cf52d84c4a9
|
|
| MD5 |
70fd7f0d6d66188528691dc3be440151
|
|
| BLAKE2b-256 |
170149ac5012b84a9797ef8216df01009d0fe72fe164d4e2b2f21cbdc6d2c871
|
Provenance
The following attestation bundles were made for homelore-0.2.0-py3-none-any.whl:
Publisher:
release.yml on AdrianZaplata/homelore
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
homelore-0.2.0-py3-none-any.whl -
Subject digest:
df402ae1c34a353ec11c5e032b90dea99454cde48610771248a90cf52d84c4a9 - Sigstore transparency entry: 2181710009
- Sigstore integration time:
-
Permalink:
AdrianZaplata/homelore@23962be98f6dcf7f351630dd42fafeee69e8298f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/AdrianZaplata
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@23962be98f6dcf7f351630dd42fafeee69e8298f -
Trigger Event:
push
-
Statement type: