
mcp-memory-rs
io.github.DioNanosPublished by GitHub account DioNanosv0.2.1Updated Oct 25, 2026
Local-first agent memory: versioned JSON categories, BM25 search, per-device ACL, fleet sync.
The publisher's own server: Memory.fit
Overview
Local-first MCP memory server that gives an assistant persistent, versioned JSON memory categories with full-text search and optional device sync.
- What you can do
- Read, write, merge-patch and delete memory categories, with version history and automatic backups before changes; append timestamped entries to bounded log categories for event streams and session journals; list categories and search them with BM25 full-text or hybrid TF-IDF ranking, filtered by category, date or actor; fetch multi-category context within a token budget and poll changes since a known hash; inspect status and run diagnostics on paths, database and sync configuration; build merkle manifests, diff them and push or pull sync envelopes against a configured remote.
- When to use it
- Useful when an assistant should keep long-lived state such as identity, project notes or per-device workflows across sessions and across different MCP clients, stored in files the user owns. It suits users who want offline, vendor-independent agent memory without a cloud account or embedding service, and who may later sync several devices.
- Requirements
- Runs as a local stdio process; a prebuilt binary is offered for Linux and Android targets, while macOS requires building from source with cargo. Configuration is a TOML file, auto-discovered or set via MCP_MEMORY_CONFIG, with environment overrides such as MCP_DEVICE and MCP_MEMORY_MODE; managed setups can set MCP_MEMORY_REQUIRE_CONFIG=1. The optional HTTP sync mode requires MCP_MEMORY_TOKEN. Default mode needs no network.
Installation
In SourceWeft
- Open mcp-memory-rs in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
mcp-memory-rs
[CI] [Tests] [License: Apache-2.0] [Rust] [Local First]
Local-first MCP memory server in pure Rust. Persistent, versioned, queryable memory for AI agents — owned by the user, not by a platform.
State lives on your disk as plain JSON categories backed by SQLite (FTS5). Every write is versioned and backed up. A fleet of devices syncs through an optional HTTP endpoint with merkle manifests and optimistic concurrency. No cloud account, no embedding service, no network dependency in the default mode.
Why
Agent memory tied to a vendor dies with the vendor session. This server keeps the agent's long-lived state — identity, projects, infrastructure notes, per-device workflows — in files you can read, grep, diff, and back up yourself. Any MCP client (Claude Code, Codex, or anything speaking MCP stdio) gets the same memory; swapping the model does not lose the state.
Design choices that follow from that:
- Local-first: the stdio server works fully offline against local storage. Sync is a separate, explicit step — never a hidden dependency.
- Plain storage: one JSON file per category plus a SQLite index. The database can be rebuilt from the files; the files are the truth.
- Versioning by default: every write keeps history; deletes create a
backup first.
memory_historyandmemory_compactmanage the tail. - Concurrency-safe writes:
expected_hashturns clobbering races between concurrent agents into explicit conflicts. - Zero ML in the core: full-text search is SQLite FTS5 with BM25;
memory_search_semanticadds an optional TF-IDF hybrid. No model downloads.
The pair: for corpus recall (chunked documents, BM25 retrieval, original-text injection) see the companion server mcp-vl-msa-rs. This server holds the curated agent state; that one holds the queryable corpus.
Install
Prebuilt binary (recommended) — download the archive for your platform from the latest release, extract, and point your MCP client at the binary:
Prebuilt targets (Linux + Android): x86_64-unknown-linux-gnu,
x86_64-unknown-linux-musl, aarch64-unknown-linux-gnu,
aarch64-unknown-linux-musl (edge / ARM / Termux), aarch64-linux-android.
macOS: no prebuilt binary is shipped (it would need Apple code-signing).
Install from source instead — cargo install compiles it on your Mac in one
command, no signing needed:
--locked uses the committed Cargo.lock (reproducible build).
Quick start
Claude Code (~/.claude.json) or any MCP client:
Codex (~/.codex/config.toml):
Configuration is TOML — copy config/example.toml to
~/.config/mcp-memory-rs/config.toml and adjust it. The server auto-discovers
that XDG-style path. Environment variables override file values (MCP_DEVICE,
MCP_MEMORY_MODE, MCP_MEMORY_DIR, …); managed deployments should set
MCP_MEMORY_REQUIRE_CONFIG=1 so a missing config fails closed.
Memory model
Memory is organized in categories: named JSON documents (base,
projects, my-laptop, workflow_my-laptop, …). Reads return the document
plus metadata (content hash, size, last writer, timestamp). Writes replace the
category or, with merge=true, patch it per top-level key.
Access control
Multi-device fleets get a small, explicit ACL ([acl] in the config):
Unknown categories are denied for non-admin writers — fail closed.
Fleet sync
Each node runs local-first; one node (or any number) exposes the HTTP API as a
sync remote. sync_manifest builds a merkle-rooted fingerprint of all
categories; sync_diff compares manifests; memory_sync pushes dirty
categories or pulls remote changes. Conflicts between nodes are resolved by
the configured conflict_strategy (last-write-wins by default);
expected_hash preconditions protect direct writes (MCP and HTTP), not the
sync envelope.
The HTTP API is an admin/sync plane: the bearer token grants full access to every category. Per-category ACL applies on the MCP stdio surface, where the device identity is known locally; HTTP callers are identified only by the shared token, so no per-device ACL is enforced there.
The HTTP server requires MCP_MEMORY_TOKEN and refuses to start without
it. Bind it to loopback (the default) and tunnel between nodes; do not expose
it to the public internet.
Tool surface
The same surface is available over HTTP (/api/v1/*) for non-MCP consumers;
/health is unauthenticated, everything else requires the bearer token.
AI client compatibility
The server is built to be self-explanatory to a weak client model:
- At
initializeit returns an instructions string describing the memory model and the entry-point tools. Some lightweight clients ignore this field; if your client never surfaces it, read the tool descriptions instead — they carry the same guidance (e.g.memory_readtakescategory, notkey). - Read-only tools are annotated
readOnlyHint, so a client such as Codex can auto-approve them. On Codex, anunsupported call/user cancelledresult usually means the tool-approval gate fired, not a server fault — setdefault_tools_approval_mode = "approve"(see the Codex snippet above). - The server speaks the standard MCP handshake. A client must complete
initializeand sendnotifications/initializedlike any MCP client.
Storage layout
With no config and strict mode disabled, standalone base_dir remains
~/.memory for compatibility. The auto-discovered example config uses
~/.local/state/mcp-memory-rs (XDG-style). Config resolution is: explicit
MCP_MEMORY_CONFIG, $XDG_CONFIG_HOME, $HOME/.config, legacy cwd-local
memory-config.toml, then standalone defaults. Either way the layout is:
Concurrency (many processes, one store)
Every writer — one stdio server per client plus the optional --http
instance — opens its own SQLite connection on the same file. Since 0.3.2 each
mutation runs inside a BEGIN IMMEDIATE transaction: SQLite is the mutex that
serializes writers across processes, so an append (read → modify → write) can
never lose another process's entry. Lock acquisition is retried with jittered
backoff inside one total budget; when it expires the call fails with a clear
Store busy … retry later error instead of hanging or corrupting anything.
Category JSON files are written crash-safely: the new content is staged next
to the file (a name unique to the transaction), the SQLite rows are
committed, then the staged file is renamed into place. A process that dies in
between leaves a staged file whose fate is decided by its hash under the next
write lock (matching the committed hash → promoted; otherwise → discarded).
Readers never rename or delete anything: they serve whichever file carries
the committed hash. memory_write merge=true, the log/memory kind check and
the optional expected_hash compare-and-swap all run inside the same lock.
Snapshot and restore
memory.db alone is not a backup (WAL, JSON files). Use the CLI:
--verify-store never opens a Store (no PRAGMA, schema or reconcile): it is
safe on a store another binary still owns. A store written by a version older
than 0.3.2 can hold categories whose file is newer than the database row (a
write whose SQL failed): --adopt-json --plan out.json describes them
read-only and --adopt-json --apply out.json adopts the files, with
preconditions, under the lock. Restore's final swap is a few
renames — copy-safe, not atomic as a group: a RESTORE_IN_PROGRESS marker
keeps the store closed until an interrupted swap is recovered by hand.
A snapshot blocks writers for its duration (readers continue), runs
VACUUM INTO and copies the category files, so both halves describe the same
instant; it is verified before it is reported. Coverage is explicit in
manifest.json: without --with-backups only the current content and the
version metadata are covered — memory_history payloads (read_version)
live in backups/ and need --with-backups. Restore verifies the snapshot
(integrity, one file per category with the recorded hash) before touching
anything, then replaces the live store and parks the previous one under
<base_dir>/restore-parked-<timestamp>/; it requires every mcp-memory-rs
process on that store to be stopped first — the --stopped flag is your
word for it.
Building and testing
No build-time network access, no C dependencies beyond bundled SQLite.
License
Apache-2.0. See LICENSE.
Source: README.md at commit 02a0755
Tools
0Version history
1- v0.2.1LatestSep 16, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts
Other Memory integrations

Memory.fit
fit.memoryOfficial publisher
Hosted Memory.fit server that lets an AI read your training, sleep, recovery and nutrition data and write back weekly plans, targets and meal plans.
pg.ddx.io: the PostgreSQL community's memory
io.ddx.pgOfficial publisher
pg.ddx.io: the PostgreSQL community's memory's hosted MCP server, published by pg.ddx.io; no sign-in required; Streamable HTTP; 29 tools.
var.gg Naming Memory
gg.varOfficial publisher
Remote MCP server that suggests and searches code identifier names from domain concepts in Korean, Japanese, Chinese, Vietnamese and English, and exposes ERD…

Counterparts
ai.counterparts
Local-first long-term memory for Claude Code and Claude Desktop: the assistant writes notes about you and your projects and recalls them in later sessions.

LAHZE - Persian AI Memory Platform
Published by GitHub account pedramgholizadeh
LAHZE - Persian AI Memory Platform's hosted MCP server; no sign-in required; Streamable HTTP; 13 tools.