SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-26

Memmy:在 VPS 上为 AI 智能体搭建本地共享记忆中心

Memmy 是一个基于 SQLite 的本地记忆中心,支持 Claude Code、Cursor 和 Codex 等工具共享上下文。通过在 VPS 部署并监听 18960 端口,您可以将碎片化的智能体记忆统一管理,减少重复指令消耗并避免因信息孤岛导致的错误决策。

Verified Every command ran end-to-end on a fresh Ubuntu 24.04 server, July 31, 2026.

Memmy 的定义及其存储内容

Memmy 是一个运行在您自有 VPS(虚拟专用服务器)上的 AI 智能体本地记忆中心。它维护一个 SQLite 数据库来存储智能体所学到的内容,服务器上的所有智能体均可读写该存储。该项目由 MemTensor memmy-agent 开发,采用 MIT 许可证,截至 2026 年 7 月版本为 1.0.4。

在服务器上仅需使用其部分组件。Memmy 提供了一个监听 http://127.0.0.1:18960 的记忆服务、一个与该服务交互的 memmy-memory 命令行界面 (CLI) 以及一个桌面工作台。由于工作台仅提供 macOS 和 Windows 版本,因此在 Linux VPS 上您只需运行该服务和 CLI。这足以让 Claude Code、Codex 和 Cursor 共享记忆。

Memmy 会将存储内容分为四个层次。L1 Trace 是原始交互轮次,包括请求、响应和工具调用。L2 Policy 是从已证明有用的交互轨迹中归纳出的过程。L3 World Model 是关于某个项目或环境的稳定知识。Skill 是从策略中固化出的可调用过程。服务在摄取交互轮次时分配层次,因此您无需手动创建这些层次。如果这些区分比较抽象,可以将记忆看作 构建智能体的分阶段学习路径中的后续阶段之一。您先亲自编写一个简单的智能体循环,并观察它在每次运行之间忘记所有内容后,就会更容易理解这些层次。

共享内存中心与各工具独立内存的区别

目前的每个 Agent 都自带内存。Claude Code 将指令文件保存在代码仓库中。Cursor 将规则保存在工作区数据库中。Codex 将会话日志保存在 ~/.codex 下。每个存储库仅属于一个工具,因此您周一在一个工具中教授的事实,周二在另一个工具中将无法获取。您为此付出了双重代价:一是重复解释同一项目所消耗的 Token,二是当 Agent 基于您在别处已修正的错误假设进行操作时,会导致工作出错。

内存中心将存储从工具中剥离出来。Memmy 也可以读取现有的存储库,因此您无需从空数据库开始。其扫描器支持六种来源:~/.claude/projects/**/*.jsonl 下的 Claude Code、~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl 下的 Codex、~/.local/share/opencode/opencode.db 下的 OpenCode、Cursor 的 state.vscdb 文件、~/.openclaw 下的 OpenClaw SQLite 数据库以及 ~/.hermes 下的 Hermes。您可以手动添加来源,只需提供名称和本地路径即可。

导入计数不会完全一致,这是正常现象。扫描器按来源和会话对消息进行分组,然后为每个完整的交互轮次写入一个 L1 内存。当交互轮次包含非空的用户内容并以非空的助手消息结束时,即视为完整,因此中断的会话不会产生任何记录。消息通过会话检查点和稳定的轮次 ID 进行去重。在同一次运行中,扫描数量、导入消息数量和新内存数量均不相同。

这部分内容与 Claude Code 如何在单次会话内管理上下文 相辅相成。上下文管理决定了单个窗口内能容纳的内容,而内存中心则决定了窗口关闭后哪些信息能够保留。

VPS 所需环境

  • Node.js 22 或更高版本。Memmy 文档要求此版本,而 Ubuntu 24.04 默认提供 Node 18。
  • git 及构建工具链,因为 better-sqlite3 是原生模块,安装过程中可能需要编译。
  • 约 2 GB 内存。根目录安装会拉取大型工作区及前端构建链。
  • 几 GB 可用磁盘空间,用于存放 node_modules 和数据库。
sudo apt update
sudo apt install -y git build-essential python3 curl ca-certificates sqlite3
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node --version

node --version 应输出 v22 或更高版本。如果此处显示 v18,说明 NodeSource 配置未生效,后续安装会在项目的引擎检查阶段失败。

在 Ubuntu 24.04 上从源码安装 Memmy

git clone https://github.com/MemTensor/memmy-agent.git
cd memmy-agent
cp .env.example .env
npm install
npm run memory:build

npm run memory:build@memmy/memory 工作区编译为 Memory/dist。对于无头服务器,源码树中的其他内容无需构建。请检查原生模块是否已加载:

node -e "require('better-sqlite3'); console.log('better-sqlite3 loads')"

如果该行代码报错而非输出内容,说明原生模块与您的 Node 版本不匹配。请运行 npm rebuild better-sqlite3,这正是该项目启动脚本在执行任何操作前所做的步骤。

README 将 bash scripts/dev-start.sh 记录为一键启动命令。请勿在无头 VPS 上运行此命令。它会在内存服务旁边启动 Electron 桌面外壳和端口为 19000 的 Vite 开发服务器,而 Electron 需要显示环境,因此在没有图形会话的服务器上,该脚本会挂起或退出。

启动内存服务并检查其响应

npm run memory:serve:dev

这是从源码运行内存服务的标准方式。它绑定到 127.0.0.1:18960,将数据库保存在 ~/.memmy/memory-service/memory.sqlite,并从 ~/.memmy/config.yaml 读取配置。若需显式指定这些值,README 中也列出了相同参数:

npm run memory:serve:dev -- \
  --host 127.0.0.1 --port 18960 \
  --db ~/.memmy/memory-service/memory.sqlite \
  --config ~/.memmy/config.yaml

在第二个 shell 中,询问服务是否存活:

curl -sS http://127.0.0.1:18960/api/v1/health

Health 是唯一不需要令牌的端点,因此它是最合适的探测方式。如果 curl 以代码 7 退出并显示 Failed to connect to 127.0.0.1 port 18960 错误,说明没有进程在监听。请查看运行服务的终端,因为启动时的崩溃信息会打印在那里,常见原因是原生 SQLite 模块加载失败。服务启动后,ss -lntp | grep 18960 可确认套接字状态。

其余 HTTP API(应用程序编程接口)位于 /api/v1 下。

  • POST /api/v1/memory/add 用于写入内存,POST /api/v1/memory/search 用于查询。
  • GET /api/v1/memory/:idDELETE /api/v1/memory/:id 用于读取和删除单条记录。
  • POST /api/v1/sessions/openPOST /api/v1/sessions/:sessionId/close 用于管理代理会话。
  • POST /api/v1/turns/startPOST /api/v1/turns/:turnId/complete 用于记录单轮对话。
  • GET /api/v1/panel/overview/api/v1/panel/analysis/api/v1/panel/items 用于提供仪表板数据。

Memmy 预留了一组端口,在无头模式下仅使用第一个:18960 用于内存服务,18970 用于网关健康检查,18980 用于 Web UI 和管理 HTTP,18990 用于 memmy serve 启动的 OpenAI 兼容 API,19000 和 19010 用于桌面前端的开发服务器。如果你的机器上已有其他进程占用了这些端口,请检查此列表。

memmy-memory 命令的来源

这是首次安装最容易出错的地方,请直接查阅软件包内容,不要盲目猜测。命令名称与仓库名称无关,它源自定义该工作区的 bin 字段:

node -p "JSON.stringify(require('./Memory/package.json').bin)"

该命令会输出 {"memmy-memory":"./dist/src/cli/index.js"}。因此,构建后的入口点为 Memory/dist/src/cli/index.js,且仅在执行 npm run memory:build 后才会生成,因为构建过程负责创建 dist 并将文件标记为可执行。直接运行它:

node Memory/dist/src/cli/index.js health

若希望在 PATH 中使用简短名称,请链接该文件:

sudo ln -s "$PWD/Memory/dist/src/cli/index.js" /usr/local/bin/memmy-memory
memmy-memory health

CLI 默认使用 http://127.0.0.1:18960,并接受 --url--token--config--source--user-id 参数。其子命令包括 inithealthsearchaddgetdelete,此外还有供代理(agent)而非用户调用的 session 和 turn。memmy-memory search "deploy steps"memmy-memory add "staging migrates on deploy" 是代理最常运行的两个命令。

如何将 Claude Code 连接到 Memmy?

Claude Code 没有内存插件接口,因此 Memmy 无法直接挂载到它上面。这种集成方式更为简单。Claude Code 将 memmy-memory 作为普通的 shell 命令运行,并通过指令文件告知其执行时机。Memmy 的文档化安装程序会为您写入该文件:memmy-memory init --agent 会将内存指令文件放入目标代理的规则目录中。

请手动编写一次指令,这样您就能确切了解代理接收到的内容。Claude Code 在每次会话开始时都会从项目根目录读取 CLAUDE.md,因此像下面这样的部分就是集成的全部内容:

## Memory

Before starting a task, run `memmy-memory search "<topic>"` and read what comes back.
When a task is done, run `memmy-memory add "<what you learned>"` for anything that will matter next session.

明确这种方式带来的收益。这是指令级别的集成,因此它仅在模型决定运行该命令时生效,否则不会触发。没有任何机制强制调用。如果会话结束时没有执行 add,则不会保存任何内容,唯一的信号是下次搜索时返回空结果。这与 Claude Code 自带的内存文件 权衡一致,但有一点不同:存储是共享的,因此该笔记也会同步到同一台机器上的 Codex 和 Cursor。提供真实插件接口的工具框架可以弥补这一差距,而无需通过“请求”方式,这就是为什么持久化内存与预算上限和权限规则一起,被列为 值得安装的 DeepSeek 工具框架插件 的原因。

反向操作则完全无需设置。Memmy 的扫描器已经可以读取 ~/.claude/projects/**/*.jsonl,这是 Claude Code 写入会话记录的位置。只需在运行 tmux 会话中的 Claude Code 的同一台服务器上运行 Memmy,昨天的成果就会自动成为内存,无需任何额外配置。

Memmy 能否作为 Claude Code 的 MCP 服务器使用?

不能。明确这一点可以避免浪费时间。MCP(模型上下文协议)包含客户端和服务器。Memmy 是一个客户端。它连接到 MCP 服务器,并将其工具提供给自身的代理运行时。它不会发布可供 claude mcp add 指向的 MCP 端点。存储库中唯一的 MCP 桥接属于桌面本地 API 内的 Composio 集成,该 API 在 127.0.0.1 上绑定了一个随机端口,并使用其自身的 x-memmy-mcp-token 标头。

客户端配置位于 ~/.memmy/config.yaml 中,即 MEMMY_CONFIG 指向的文件,位于 tools.mcpServers 下:

tools:
  mcpServers:
    example:
      type: stdio
      command: npx
      args:
        - "-y"
        - "your-mcp-server"
      toolTimeout: 30
      enabledTools:
        - "*"

type 接受 stdiossestreamableHttpstdio 服务器作为 Memmy 的子进程运行,这意味着其命令必须存在于同一台机器上,并以相同的用户身份运行。如果您已经在 VPS 上运行 MCP 服务器,则应在此处列出这些服务器。

保持内存存储的私密性

Memmy 拥有的所有内容都位于 ~/.memmy 下:config.yaml、工作区、memory-service/memory.sqlite 以及运行时文件。扫描和摄取过程均在本地进行,内存被写入该本地 SQLite 文件,因此默认状态即为真正的本地化。

只有两条路径会连接网络。MEMMY_CLOUD_SERVICE 默认为 https://memmy-api.memtensor.cn,并使用其试用令牌支持账户模式,因此 API 密钥模式从不调用该路径。内存改进计划是隐私设置中的一个独立开关,在您手动开启前处于关闭状态。

第三条路径更容易被忽略。如果您配置了托管的嵌入(embedding)提供商,每条内存的文本都会被发送到该提供商以转换为向量。本地存储在此处无法提供保护。自行托管嵌入端点是关闭此路径的唯一方法。

请将端口 18960 保持在回环地址上。它不需要防火墙规则,因为绑定到 127.0.0.1 的服务在主机外部完全无法访问。请通过 SSH 从您的笔记本电脑访问它:

ssh -N -L 18960:127.0.0.1:18960 you@your-vps

如果您确实需要将其绑定到更广的范围,请务必先设置令牌。在配置中设置 storage.token,或使用 MEMMY_MEMORY_TOKENMEMORY_SERVICE_TOKEN 环境变量,将使除健康检查外的所有端点都需要 Bearer 令牌。配置值支持 ${ENV_NAME} 引用,因此令牌和您的模型 API 密钥不会直接出现在文件中。这与在其他任何地方将密钥排除在 AI 代理之外的习惯相同,而默认拒绝的 ufw 策略则是防止未来版本更改默认绑定地址的最后防线。

在信任 ~/.memmy 之前请先备份

memory.sqlite 是整个存储库。向量数据通过 sqlite-vec 扩展名保存在同一个文件中,因此只需备份这一个文件即可。如果在服务写入时使用 cp 进行复制,可能会导致数据库损坏。请使用 SQLite 自带的备份命令:

mkdir -p ~/memmy-backup
sqlite3 ~/.memmy/memory-service/memory.sqlite ".backup '$HOME/memmy-backup/memory.sqlite'"

该命令可在服务运行期间生成一致的副本。请按计划将备份文件传输到服务器外部,具体可参考 使用 restic 备份至异地存储。丢失 config.yaml 只会损失服务提供商的设置,这些设置可以重新输入。但丢失 memory.sqlite 则意味着丢失所有记忆数据,且机器上没有任何其他地方存有副本。

在 systemd 下运行内存服务

在 shell 中直接运行 npm run memory:serve:dev 会随 shell 的关闭而终止。使用 unit 文件可确保服务在重启后持续运行。

[Unit]
Description=Memmy memory service
After=network-online.target

[Service]
Type=simple
User=memmy
WorkingDirectory=/opt/memmy/memmy-agent
EnvironmentFile=/etc/memmy/memory.env
ExecStart=/usr/bin/npm run memory:serve:dev
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

请勿将令牌(token)写入 unit 文件。应将其存放在 /etc/memmy/memory.env 中,所有者设为 root,权限设为 600:

MEMMY_CONFIG=/home/memmy/.memmy/config.yaml
MEMMY_MEMORY_TOKEN=replace-this-with-a-long-random-string
sudo systemctl daemon-reload
sudo systemctl enable --now memmy-memory
systemctl status memmy-memory --no-pager
curl -sS http://127.0.0.1:18960/api/v1/health

状态输出中的 status=203/EXEC 表示 systemd 无法运行 ExecStart,此时请检查 which npm:在 NodeSource 安装中,它位于 /usr/bin/npm,而使用 nvm 时则位于用户主目录下,systemd 无法找到该路径。如果服务启动后立即退出,说明错误发生在 npm 内部,此时 journalctl -u memmy-memory -n 50 会输出具体原因。其处理机制与 VPS 上的其他任何 systemd 服务 相同。

Memmy 尚未实现的功能

  • 目前没有 Linux 桌面构建版本。打包脚本仅涵盖 macOS 和 Windows,因此工作台、入门向导和内存仪表板无法在服务器本地使用。
  • memory:serve:dev 通过 tsx(一个开发路径)运行 TypeScript 入口点。代码仓库也提供了用于编译输出的 memory:serve。运行不带参数的 npm run,即可查看当前检出版本中实际包含的脚本。
  • 检索功能基于最新的 2,000 条向量行构建搜索窗口,随后在该窗口内应用 Top-K 选择。在存储规模非常大时,较旧的记忆可能会落在窗口之外。
  • 嵌入过程在捕获之后进行,如果失败会进入重试队列,而不会阻塞代理的当前任务。因此,刚刚添加的记忆可能暂时无法通过向量搜索找到。
  • 一个 SQLite 文件对应一个节点。目前不支持集群,因此第二台服务器将拥有独立的内存空间。

截至 2026 年 7 月,1.0.4 版本和约 329 个星标表明这是一个尚处于早期的项目。标志、路径和脚本名称会在不同版本间变动。请查阅您本地检出版本中的 bin 字段以及 npm run 的输出,不要盲目信任从任何地方(包括此处)复制的命令。

FAQ

为什么健康检查返回 connection refused?

端口 18960 上没有服务在监听。curl 退出码 7 配合 Failed to connect to 127.0.0.1 port 18960 表示内存服务未运行或在启动时崩溃,请查看终端或服务启动时的日志。通常有两个原因:一是 better-sqlite3 原生模块与你的 Node 版本不匹配,可通过 npm rebuild better-sqlite3 修复;二是 Node 版本低于 22。服务启动后,使用 ss -lntp | grep 18960 确认套接字状态。

从源码构建后,memmy-memory 命令从何而来?

它来自 @memmy/memory 工作区包的 bin 字段,而非仓库名称。在检出目录内运行 node -p "JSON.stringify(require('./Memory/package.json').bin)",它会输出 {"memmy-memory":"./dist/src/cli/index.js"}。该文件仅在 npm run memory:build 后存在,因为构建过程会创建 dist 并将其标记为可执行。请使用 node Memory/dist/src/cli/index.js health 运行它,或将其软链接到 /usr/local/bin 以使用简短名称。

我可以使用 claude mcp add 将 Memmy 添加到 Claude Code 吗?

不能。Memmy 是 MCP 客户端,而非 MCP 服务器。它主动连接到 ~/.memmy/config.yamltools.mcpServers 下列出的服务器,并将其工具提供给自身的运行时。Claude Code 与 Memmy 的交互方式相反,它是通过将 memmy-memory CLI 作为 shell 命令运行来实现的,并由 memmy-memory init --agent 写入代理规则目录的指令文件进行引导。

运行 Memmy 会将我的记忆发送到云服务吗?

扫描和摄取过程均在本地运行,记忆会被写入你磁盘上的 ~/.memmy/memory-service/memory.sqliteMEMMY_CLOUD_SERVICE 指向 https://memmy-api.memtensor.cn 以用于账户模式和试用令牌,且记忆改进计划在启用前始终处于关闭状态。需要关注的路径是嵌入提供程序:托管的嵌入模型会接收其转换为向量的每一条记忆文本,因此如果这涉及隐私,请使用你自己运行的端点。