mcpField
M
mcp-memory-rs

mcp-memory-rs

本地服务
dev.mmmbuto.com记忆与知识26 周前更新

关于 mcp-memory-rs

mcp-memory-rs 是面向 Agent 的本地优先 MCP 记忆服务,将长期状态保存在带版本记录的 JSON 文件中,并用可重建的 SQLite 索引搜索。默认离线运行,也可选择在设备间同步。

主要功能

  1. 01带版本记录的 JSON 分类与备份
  2. 02BM25 全文及混合搜索
  3. 03按设备限制分类写入权限
  4. 04可选的 Merkle 设备群同步
  5. 05历史记录、追加日志与快照

适用场景

  1. 01跨会话保存 Agent 身份与项目笔记
  2. 02无需嵌入服务即可搜索本地记忆
  3. 03限制设备仅写入自身分类
  4. 04按需在多台设备间同步记忆

MCP 相关

通过 stdio 向 MCP 客户端提供记忆读取、写入、搜索、历史、诊断和同步工具。相同能力也可通过需身份验证的 HTTP API 使用。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

mcp-memory-rs

CI Tests License: Apache-2.0 Rust Local First

使用纯 Rust 构建的本地优先 MCP 记忆服务。为 AI Agent 提供持久化、版本化、可查询的记忆——由用户掌控,而非平台。

状态以纯 JSON 分类文件的形式保存在本地磁盘,并由 SQLite(FTS5)提供支持。每次写入都会进行版本管理并备份。多台设备可通过可选的 HTTP 端点,使用 Merkle 清单和乐观并发机制进行同步。默认模式下无需云账号、嵌入服务或网络依赖。

为什么选择它

与供应商绑定的 Agent 记忆会随着供应商会话结束而消失。本服务将 Agent 的长期状态——身份、项目、基础设施笔记、各设备的工作流——保存在你可以自行读取、搜索、比较差异和备份的文件中。任何 MCP 客户端(Claude Code、Codex,或任何使用 MCP stdio 的客户端)都能访问相同的记忆;更换模型不会丢失状态。

由此形成的设计选择:

  • 本地优先:stdio 服务可完全离线地使用本地存储。同步是单独且明确执行的步骤——绝不会成为隐藏依赖。
  • 纯文本存储:每个分类对应一个 JSON 文件,另有一个 SQLite 索引。数据库可以从这些文件重建;文件才是真实数据。
  • 默认启用版本管理:每次写入都会保留历史记录;删除前会先创建备份。memory_history 和 memory_compact 用于管理历史记录。
  • 并发安全写入:expected_hash 可将并发 Agent 之间的覆盖竞争转化为明确的冲突。
  • 核心不包含 ML:全文搜索使用 SQLite FTS5 和 BM25;memory_search_semantic 可选地添加 TF-IDF 混合搜索。无需下载模型。

**配套服务:**如需检索 语料库(分块文档、BM25 检索、注入原文),请参阅配套服务 mcp-vl-msa-rs。本服务保存经过整理的 Agent 状态;配套服务保存可查询的语料库。

flowchart LR
    A["AI agent<br/>(any MCP client)"]
    A -->|"curated state<br/>read / write / sync"| M["mcp-memory-rs<br/><i>the notebook</i>"]
    A -->|"corpus recall<br/>index / search / fetch"| V["mcp-vl-msa-rs<br/><i>the library</i>"]
    M --- D1[("JSON categories<br/>SQLite FTS5")]
    V --- D2[("tantivy BM25<br/>collections")]

安装

预编译二进制文件(推荐)——从最新版本下载适用于你平台的压缩包,解压后将 MCP 客户端指向该二进制文件:

tar xzf mcp-memory-rs-x86_64-unknown-linux-gnu.tar.gz
install -m755 mcp-memory-rs-*/mcp-memory-rs ~/.local/bin/

预编译目标平台(Linux + Android):x86_64-unknown-linux-gnu、 x86_64-unknown-linux-musl、aarch64-unknown-linux-gnu、 aarch64-unknown-linux-musl(边缘设备 / ARM / Termux)、aarch64-linux-android。

macOS:不提供预编译二进制文件(需要 Apple 代码签名)。 请改为从源码安装——运行 cargo install 即可通过一条命令在 Mac 上编译,无需签名:

cargo install --git https://github.com/DioNanos/mcp-memory-rs --locked

--locked 使用已提交的 Cargo.lock(确保构建可复现)。

快速开始

cargo build --release

# stdio MCP server, offline mode (default)
./target/release/mcp-memory-rs

Claude Code(~/.claude.json)或任何 MCP 客户端:

{
  "mcpServers": {
    "memory": {
      "command": "/path/to/mcp-memory-rs",
      "env": {
        "MCP_MEMORY_CONFIG": "/home/me/.config/mcp-memory-rs/config.toml",
        "MCP_MEMORY_REQUIRE_CONFIG": "1",
        "MCP_MEMORY_MODE": "offline",
        "MCP_DEVICE": "my-laptop"
      }
    }
  }
}

Codex(~/.codex/config.toml):

[mcp_servers.memory]
command = "/path/to/mcp-memory-rs"
env = { MCP_MEMORY_CONFIG = "/home/me/.config/mcp-memory-rs/config.toml", MCP_MEMORY_REQUIRE_CONFIG = "1", MCP_MEMORY_MODE = "offline", MCP_DEVICE = "my-laptop" }
# auto-approve read-only tools (memory_read/list/search/…); writes still gated
default_tools_approval_mode = "approve"

配置采用 TOML 格式——将 config/example.toml 复制到 ~/.config/mcp-memory-rs/config.toml 并进行调整。服务会自动发现该 XDG 风格路径。环境变量会覆盖文件中的值(MCP_DEVICE、MCP_MEMORY_MODE、MCP_MEMORY_DIR、……);托管部署应设置 MCP_MEMORY_REQUIRE_CONFIG=1,以便在配置缺失时安全地拒绝启动。

记忆模型

记忆按类别组织:命名的 JSON 文档(base、 projects、my-laptop、workflow_my-laptop,……)。读取会返回文档 及其元数据(内容哈希、大小、最后写入者、时间戳)。写入会替换整个类别,或在 merge=true 时按顶层键进行修补。

访问控制

多设备集群使用简单明确的 ACL(配置中的 [acl]):

规则效果
admin_devices列出的设备可以写入所有内容。
device_categories设备 name 可以写入类别 name 和 workflow_name——仅限其自身命名空间。
agent scope设备 foo-agent 可以写入 foo_* 类别。
everyone所有设备都可以读取所有内容。

非管理员写入者无法访问未知类别——默认拒绝。

集群同步

每个节点都以本地优先的方式运行;一个或多个节点可以将 HTTP API 作为同步远程服务公开。sync_manifest 会为所有类别构建以 Merkle 根为基础的指纹;sync_diff 会比较清单;memory_sync 会推送有更改的类别,或拉取远程更改。节点间的冲突由配置的 conflict_strategy 解决(默认采用最后写入者胜出);expected_hash 前置条件可保护直接写入(MCP 和 HTTP),但不保护同步信封。

HTTP API 是一个管理员/同步平面:持有 bearer token 即可完全访问每个类别。每类别 ACL 仅适用于 MCP stdio 接口,因为设备身份在本地已知;HTTP 调用者只能通过共享令牌识别,因此不会在此强制执行每设备 ACL。

HTTP 服务必须使用 MCP_MEMORY_TOKEN,没有该令牌时拒绝启动。请将其绑定到 loopback(默认设置),并在节点间建立隧道;切勿将其暴露到公共互联网。

MCP_MEMORY_TOKEN=<secret> ./target/release/mcp-memory-rs --http

工具接口

工具描述
memory_read读取类别(可选字段筛选)。
memory_write替换或合并修补类别;带版本控制;使用 expected_hash 前置条件。
memory_append向有界、仅追加的日志类别追加带时间戳的条目;根据 max_entries/max_age_days 自动清理。用于事件流/会话日志,避免记忆类别变得臃肿。
memory_delete删除类别(先创建备份)。
memory_list列出所有类别及其哈希/大小/上次更新元数据。
memory_searchFTS5 全文搜索、BM25 排名、类别/日期/操作者筛选、摘要片段。
memory_search_semantic混合 TF-IDF + FTS5 搜索。
memory_history查看类别的版本历史。
memory_delta获取自已知哈希以来的更改(低开销轮询)。
memory_context读取多个类别以进行预热,面向令牌预算优化。
memory_compact清理旧版本和备份。
memory_status本地优先状态:待处理队列、清单哈希、上次同步时间。
memory_doctor诊断信息:路径、数据库、类别、同步配置。
sync_manifest为所有类别生成以 Merkle 根为基础的清单。
sync_diff比较本地与远程清单:推送/拉取/冲突集合。
sync_push / sync_pull导出/导入同步信封。
memory_sync针对已配置的远程服务执行一次同步(push_dirty / pull_remote)。

非 MCP 调用方也可通过 HTTP(/api/v1/*)使用相同的接口;/health 无需身份验证,其余接口均需要 bearer token。

AI 客户端兼容性

该服务的设计旨在让能力较弱的客户端模型也能轻松理解:

  • 在 initialize 时,它会返回一段 instructions 字符串,用于说明记忆模型和入口工具。一些轻量级客户端会忽略此字段;如果客户端从不显示该字段,请改为查看工具描述——其中包含相同的指引(例如,memory_read 接受的是 category,而不是 key)。
  • 只读工具带有 readOnlyHint 注释,因此 Codex 之类的客户端可以自动批准这些工具。在 Codex 中,unsupported call / user cancelled 结果通常表示触发了工具审批关卡,而非服务故障——请设置 default_tools_approval_mode = "approve"(见上面的 Codex 示例)。
  • 该服务使用标准 MCP 握手。客户端必须像任何 MCP 客户端一样完成 initialize 并发送 notifications/initialized。

存储布局

未配置且未启用严格模式时,独立运行的 base_dir 仍为 ~/.memory,以保持兼容性。自动发现的示例配置使用 ~/.local/state/mcp-memory-rs(XDG 风格)。配置解析顺序为:显式指定的 MCP_MEMORY_CONFIG、$XDG_CONFIG_HOME、$HOME/.config、旧版当前工作目录下的 memory-config.toml,然后是独立运行的默认值。无论哪种情况,布局如下:

<base_dir>/
├── categories/   # one .json file per category — the source of truth
├── backups/      # automatic pre-delete/pre-overwrite backups
├── memory.db     # SQLite: FTS5 index, versions, sync state (rebuildable)
└── memory.db-wal # write-ahead log (WAL mode; do not copy or delete by hand)
并发(多个进程,共用一个存储)

每个写入进程——每个客户端对应一个 stdio 服务,以及可选的 --http 实例——都会在同一个文件上打开各自的 SQLite 连接。自 0.3.2 起,每次修改都在 BEGIN IMMEDIATE 事务中执行:SQLite 充当互斥锁,在多个进程之间串行化写入,因此追加操作(读取 → 修改 → 写入)绝不会丢失其他进程写入的条目。锁获取会在一个总时限内通过带抖动的退避机制重试;时限到期后,调用会返回明确的 Store busy … retry later 错误,而不是一直挂起或损坏任何内容。

[storage]
journal_mode = "wal"           # "wal" (default) or "delete"
synchronous = "full"           # "full" (default, durable) or "normal"
sqlite_busy_timeout_ms = 200   # per-statement SQLite busy handler
lock_deadline_ms = 10000       # total wait for the write lock per mutation

类别 JSON 文件采用崩溃安全的方式写入:新内容会先暂存到文件旁边(文件名在事务中唯一),SQLite 行提交后,再将暂存文件重命名到位。若进程在此期间退出,暂存文件的去留将在下一次写入锁期间根据其哈希值决定(与已提交的哈希值匹配 → 提升为正式文件;否则 → 丢弃)。读取者绝不会重命名或删除任何内容:它们只会提供与已提交哈希值对应的文件。memory_write merge=true、日志/记忆类型检查,以及可选的 expected_hash 比较并交换,都会在同一把锁内执行。

快照与恢复

仅备份 memory.db 并不完整(还涉及 WAL 和 JSON 文件)。请使用 CLI:

mcp-memory-rs --snapshot /path/to/snap-2026-09-15 --with-backups  # db + json + backups + manifest
mcp-memory-rs --restore  /path/to/snap-2026-09-15 --stopped
mcp-memory-rs --verify-store                                      # read-only: db vs json, pending files

--verify-store 不会打开 Store(不执行 PRAGMA、模式操作或协调):即使存储仍由另一个二进制程序占用,也可以安全使用。由早于 0.3.2 的版本写入的存储,可能存在类别文件比数据库行更新的情况(SQL 写入失败):--adopt-json --plan out.json 会以只读方式列出这些文件,而 --adopt-json --apply out.json 则会在锁内、满足前置条件后接纳这些文件。恢复的最终切换涉及若干次重命名——可安全复制,但作为整体并非原子操作:RESTORE_IN_PROGRESS 标记会使存储保持关闭,直到手动恢复被中断的切换。

创建快照时,会在整个过程中阻止写入者(读取者仍可继续),并运行 VACUUM INTO、复制类别文件,因此快照的两部分描述的是同一时刻;报告快照前还会先进行验证。覆盖范围会在 manifest.json 中明确说明:不带 --with-backups 时,仅包含当前内容和版本元数据——memory_history 负载(read_version)存放在 backups/ 中,需要使用 --with-backups 才会纳入。恢复前会先验证快照(完整性,以及每个类别都有一个哈希值与记录相符的文件),然后才会修改任何内容;接着替换在线存储,并将之前的存储保存在 <base_dir>/restore-parked-<timestamp>/ 下;必须先停止该存储上的所有 mcp-memory-rs 进程——--stopped 标志就是对此的声明。

构建与测试

cargo build --release   # single static-friendly binary
cargo test              # unit + integration tests
cargo clippy --all-targets -- -D warnings

构建时无需访问网络,除捆绑的 SQLite 外无其他 C 依赖。

许可证

Apache-2.0。详见 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。