A memory store that runs on your own machine. magpie writes to it like any other destination, it holds what you save in one SQLite file, searches it, and lets Claude read it over MCP. No account, no key, no network.
Node 22.5 or newer, which is the only requirement: the database is Node’s own
node:sqlite, so there is nothing to compile and no platform-specific binary.
# the package, and the service that keeps it running npm install -g @anona-labs/magpie-local magpie-local install # let Claude read it claude mcp add --scope user magpie -- magpie-local mcp
install starts it now and at every login. Then open the magpie popup,
choose This machine, and paste the token it printed. magpie-local token
prints it again.
--scope user matters. claude mcp add defaults to
--scope local, which registers the server for the one directory you happened to
be standing in. Everywhere else it looks like magpie simply does not work.
Nothing permanent: npx @anona-labs/magpie-local start runs it in the
background until you reboot, and ... serve runs it in the terminal where you can
watch it.
| Command | What it does |
|---|---|
magpie-local | what is in the store, and whether it is running |
magpie-local install | run it now, and with the computer from now on |
magpie-local uninstall | stop doing that |
magpie-local start / stop / restart | in the background, until the next reboot |
magpie-local serve | in the foreground, logging here |
magpie-local ui | open it in a browser: search, read, forget |
magpie-local search "…" | search the store from the terminal |
magpie-local token | print the token, for pasting into magpie |
magpie-local mcp | speak MCP on stdio; Claude starts this itself |
The bare command is the one that answers everything: whether the service is up and for how long, the file and its size, how much of it is embedded, which spaces and what kinds of thing they came from, a fortnight of capture as a sparkline, and the newest thing you saved. It is read from your own file and printed on your own terminal. magpie has no telemetry: none of it is sent anywhere, by that command or by anything else.
install writes your platform’s own service file — a systemd user
unit, a LaunchAgent, or a Startup entry — and prints the path and every command it ran, so
nothing happens to your machine that you cannot read first.
The terminal answers the same questions, and reading is not what a terminal is for: the store holds whole articles, and the thing you most want to do with a search result is read it.
magpie-local ui
It starts the store if it is not already up and opens
http://127.0.0.1:7777. The page shows what is stored and how much of it is
embedded, searches everything with the same two retrievers, reads a whole page back with its
summary above it, and forgets one you no longer want.
The token reaches the page in the # of that address, which a browser never
sends to a server and never writes to a log. The page keeps it, so every visit after the
first is just 127.0.0.1:7777. The page itself is served without a token because
it holds no data: every number on it arrives from a call the token guards, and a hostile web
page can read neither this origin’s storage nor our answers.
Everything the page needs is in the document — no font, no script and no stylesheet is fetched from anywhere — so a local store does not stop being readable when the house wifi does.
| Tool | For |
|---|---|
search_memories | keyword and semantic search across everything you saved |
get_page | the whole text of one page, by id or URL |
recent_memories | what you saved lately |
All three are read-only. A tool that can write is a tool a prompt injection in a web page can aim at your notes, and the writing surface already exists in the extension behind a key you press.
There is deliberately no ask tool and no model inside the server. In an MCP setup
the generation half of retrieval-augmented generation is the client: Claude is the thing doing
the reasoning, so this server’s whole job is to find the right text and hand it over. An LLM
inside a retrieval server whose only caller is an LLM buys nothing and costs a second runtime,
a second download, and a GPU.
Two retrievers over the same file, fused with Reciprocal Rank Fusion:
bge-small-en-v1.5, 384 dimensions, embedded on your CPU in
this process.The model is about 130MB and downloads once, in the background. Nothing waits for it: captures are accepted and keyword search answers from the first second, and semantic results start appearing on their own when the download finishes. Every result says which retriever found it.
Vectors are scanned exactly rather than through an approximate index. At the scale one person reaches — roughly 70,000 passages a year — that is about 107MB and tens of milliseconds, and exact means no index to rebuild and no recall cliff.
One row per page: the URL, the title, when you saved it, the summary magpie wrote, and the full source text. The extension sends a summary to cloud providers because they bill for what they extract; on your own disk there is no bill, so the source is kept and indexed while the summary stays as the headline.
Re-saving a page replaces it rather than storing it twice.
~/.magpie/ memories.db pages, passages, the text index and the vectors, one file token the credential, mode 600 magpie-local.log what the background service has been saying
It is an ordinary SQLite file and it is yours: sqlite3 ~/.magpie/memories.db opens
it.
Any page you visit can make a request to 127.0.0.1, and a store holding the full
text of everything you have read is a bigger prize than one holding summaries. Three things
guard it:
/health.The database is not encrypted. Its directory is mode 700 and the token file 600, which is the same protection your browser profile has beside it. If that is not enough for what you are reading, it should not be captured.
| Variable | Default |
|---|---|
MAGPIE_HOME | ~/.magpie |
MAGPIE_PORT | 7777 |
MAGPIE_EMBED_MODEL | Xenova/bge-small-en-v1.5 |
Changing the model invalidates every vector. Nothing breaks and nothing has to be run: each vector records the model that wrote it, search ignores the ones that do not match, and they are re-embedded in the background.
Check which Node it is running:
systemctl --user status magpie-local # Linux
journalctl --user -u magpie-local -n 20
ERR_UNKNOWN_BUILTIN_MODULE with an old version number means the service found a
different Node than your shell does, and that one has no node:sqlite. Versions
before 0.1.1 wrote a unit that ran the magpie-local shim, whose
#!/usr/bin/env node resolves against the service manager’s PATH rather than
yours. Upgrade and reinstall the unit:
npm install -g @anona-labs/magpie-local@latest magpie-local install
It is a message, not a lost capture: the extension keeps the capture and retries on its own
once the store is back. magpie-local says whether it is up, and
~/.magpie/magpie-local.log says what happened if it is not.
The embedding model is still downloading, or could not. magpie-local shows the
embedded count against the total; if it stays at zero, the log will say why. Keyword results
are a complete answer in the meantime.
Set MAGPIE_PORT, reinstall the service so the unit carries it, and note that the
extension looks for 7777 today.
This is one machine. No sync, no sharing, no phone. It searches what you saved; it does not consolidate facts, track what supersedes what, or reason across your memories. That is Anona Memory, and it is a different product that happens to also store text. You can change your mind later without losing anything: the local store keeps the original of everything it holds.
MIT, and the source is on GitHub.