Memmy:VPS 上供 AI agent 共用的本機記憶中樞
Memmy 讓 AI agent 共用一個本機記憶庫。本文示範在 Ubuntu 從原始碼建置,於 port 18960 執行服務,並讓所有筆記留在自己的 VPS 上。
Memmy 是什麼,以及它儲存的內容
Memmy 是供 AI agent 使用的本機記憶中樞,執行於您自己的 VPS(virtual private server)上。它會在單一 SQLite 資料庫中儲存 agent 學到的內容,該主機上的所有 agent 都會讀取及寫入同一個資料儲存區。截至 2026 年 7 月,這個專案由 MemTensor memmy-agent,採用 MIT 授權,版本為 1.0.4。
在伺服器上,只有其中一部分功能重要。Memmy 提供在 http://127.0.0.1:18960 上監聽的記憶服務、與該服務通訊的 memmy-memory 命令列介面(CLI),以及桌面工作台。工作台只提供 macOS 和 Windows 套件,因此在 Linux VPS 上執行服務與 CLI 即可。這足以讓 Claude Code、Codex 和 Cursor 共用記憶。
Memmy 會將儲存內容分為 4 個層級。L1 Trace 是原始回合,包括請求、回應和工具呼叫。L2 Policy 是從證實有用的 trace 歸納出的程序。L3 World Model 是關於專案或環境的穩定知識。Skill 是由 policy 固化而成、可供呼叫的程序。服務在擷取回合時會指派層級,因此不需要手動建立這些層級。
共享記憶體中樞與各工具獨立記憶體的差異
目前每個 agent 都自帶記憶體。Claude Code 將指示檔案放在 repository 中。Cursor 將規則儲存在其 workspace database 中。Codex 將工作階段日誌儲存在 ~/.codex 下。每個儲存區都只屬於單一工具,因此你週一在某個工具中教過的資訊,週二在另一個工具中仍然不存在。你會因此付出兩次成本:一次是浪費 tokens 重複說明相同專案,另一次是 agent 根據你已在其他地方修正過的假設執行錯誤工作。
中樞會將儲存區移出工具本身。Memmy 也會讀取現有的儲存區,因此不必從空白 database 開始。其掃描器支援 6 個來源:位於 ~/.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 databases,以及位於 ~/.hermes 下的 Hermes。你也可以手動提供名稱與本機路徑來新增來源。
匯入計數不會一致,這是預期行為。掃描器會依來源與對話分組訊息,然後為每個完整回合寫入 1 筆 L1 記憶。回合必須同時具備非空白的 user 內容,並以非空白的 assistant 訊息結束,才會被視為完整。因此,中斷的工作階段不會產生任何資料。系統會使用對話 checkpoint 與穩定的回合 ID 去除重複訊息。同一次執行中,掃描數量、匯入訊息數量與新增記憶數量都會不同。
這部分與Claude Code 如何在單一工作階段內管理 context相互搭配。Context 管理決定單一視窗能容納哪些內容。記憶體中樞則決定視窗關閉後哪些內容仍會保留。
VPS 所需環境
- Node.js 22 或更新版本。Memmy 文件要求此版本,而 Ubuntu 24.04 內建 Node 18。
git與建置工具鏈,因為better-sqlite3是原生模組,安裝期間可能需要編譯。- 約 2 GB RAM。root 安裝會下載大型工作區與前端建置工具鏈。
- 幾 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 --versionnode --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:buildnpm 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 桌面 shell 和連接埠 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/healthHealth 是唯一不要求 token 的 endpoint,因此適合作為探測端點。若 curl 以代碼 7 結束並顯示 Failed to connect to 127.0.0.1 port 18960 訊息,表示目前沒有程序監聽該連接埠。請查看執行服務的終端機,因為啟動時發生當機會在該處顯示,而最常見的原因是原生 SQLite 模組載入失敗。服務啟動後,ss -lntp | grep 18960 會確認 socket 是否存在。
其餘 HTTP API(application programming interface)位於 /api/v1 底下。
POST /api/v1/memory/add寫入記憶,POST /api/v1/memory/search執行查詢。GET /api/v1/memory/:id和DELETE /api/v1/memory/:id讀取並移除單一項目。POST /api/v1/sessions/open和POST /api/v1/sessions/:sessionId/close標示 agent 工作階段的開始與結束。POST /api/v1/turns/start和POST /api/v1/turns/:turnId/complete記錄單一回合。GET /api/v1/panel/overview、/api/v1/panel/analysis和/api/v1/panel/items提供 dashboard 所需資料。
Memmy 會保留一組連接埠;在無頭模式下只會使用其中前幾個:18960 用於記憶服務,18970 用於 gateway health,18980 用於 web UI 與 admin HTTP,18990 用於由 memmy serve 啟動的 OpenAI-compatible API,19000 和 19010 則用於 desktop frontend 的 dev server。若系統上的其他程序已佔用其中任何一個連接埠,請從這份清單開始檢查。
memmy-memory 指令實際上的來源
這是初次安裝通常會出錯的地方,因此請直接從套件中確認,不要猜測。指令名稱與儲存庫名稱無關。它來自定義該指令之 workspace 的 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 healthCLI 預設為 http://127.0.0.1:18960,並接受 --url、--token、--config、--source 和 --user-id。其子命令包括 init、health、search、add、get 和 delete,此外還有供 agent 使用、而非供人員使用的 session 與 turn 呼叫。memmy-memory search "deploy steps" 和 memmy-memory add "staging migrates on deploy" 是 agent 最常執行的兩個命令。
如何將 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 也能取得該筆備註。
反向流程完全不需要設定。Memmy 的掃描器已經會讀取 ~/.claude/projects/**/*.jsonl;Claude Code 會將工作階段逐字記錄寫入該處。在執行 於 tmux 工作階段中執行 Claude Code 的同一台伺服器上執行 Memmy,昨天的工作就會自動成為記憶,無須進行任何設定。
Memmy 能作為 Claude Code 的 MCP 伺服器嗎?
不能。先了解這個方向,可以省下大量時間。MCP(model context protocol)包含用戶端與伺服器。Memmy 是用戶端,會向外連線至 MCP 伺服器,並將其工具提供給自身的 agent runtime。它不會發布可供 claude mcp add 指向的 MCP endpoint。儲存庫中唯一的 MCP bridge 屬於桌面本機 API 內的 Composio integration,而該 API 會在 127.0.0.1 上繫結隨機埠,並使用自身的 x-memmy-mcp-token header。
用戶端設定位於 ~/.memmy/config.yaml 所指向的 MEMMY_CONFIG 檔案中,路徑為 tools.mcpServers:
tools:
mcpServers:
example:
type: stdio
command: npx
args:
- "-y"
- "your-mcp-server"
toolTimeout: 30
enabledTools:
- "*"type 接受 stdio、sse 與 streamableHttp。stdio 伺服器會作為 Memmy 的子程序執行,因此其 command 必須存在於同一台主機上,並以相同使用者身分執行。如果你已在 VPS 上執行 MCP 伺服器,請將這些伺服器列在此處。
讓記憶儲存區保持私有
Memmy 擁有的所有內容都位於 ~/.memmy 下:config.yaml、工作區、memory-service/memory.sqlite 及執行階段檔案。掃描與匯入都在本機執行,記憶會寫入本機 SQLite 檔案,因此預設狀態確實是本機運作。
有兩條路徑會連到網路。MEMMY_CLOUD_SERVICE 預設為 https://memmy-api.memtensor.cn,並使用其試用 token 支援帳戶模式,因此 API key 模式不會呼叫它。記憶改善計畫是隱私設定中的獨立切換選項,除非你手動開啟,否則預設關閉。
第三條路徑較容易忽略。如果你設定代管的 embedding provider,每則記憶的文字都會傳送給該 provider,以便轉換成向量。本機儲存無法避免這件事。只有自行代管 embedding endpoint,才能封閉這條路徑。
讓 port 18960 綁定在 loopback 位址。這不需要防火牆規則,因為綁定至 127.0.0.1 的服務完全無法從主機外部連線。請改用 SSH 從筆電連入:
ssh -N -L 18960:127.0.0.1:18960 you@your-vps如果你要讓它綁定至更廣泛的位址,請先設定 token。在設定檔中設定 storage.token,或設定 MEMMY_MEMORY_TOKEN 或 MEMORY_SERVICE_TOKEN 環境變數,即可讓除了 health endpoint 之外的所有 endpoint 都要求 bearer token。設定值支援 ${ENV_NAME} 參照,因此 token 與模型 API key 不必直接寫入檔案。這與其他地方的 讓 AI agents 的 secret 保持在檔案外 做法相同;如果未來版本變更預設綁定位址,預設拒絕的 ufw 政策 可作為最後一道防線。
備份 ~/.memmy,再信任它
memory.sqlite 是完整的資料儲存庫。向量透過 sqlite-vec extension 儲存在同一個檔案中,因此單一檔案就是備份。服務寫入期間使用 cp 複製檔案,可能會產生不完整的資料庫。請使用 SQLite 內建的備份命令:
mkdir -p ~/memmy-backup
sqlite3 ~/.memmy/memory-service/memory.sqlite ".backup '$HOME/memmy-backup/memory.sqlite'"這會在服務持續執行的情況下建立一致的複本。請依排程將複本傳送到主機外部的儲存位置,使用 restic 傳送至異地儲存就是用於此目的。遺失 config.yaml 時,您只需重新輸入 provider 設定。遺失 memory.sqlite 時,所有記憶都會遺失,而這台機器上的其他位置沒有第二份複本。
使用 systemd 執行 memory 服務
在 shell 中執行 npm run memory:serve:dev 時,shell 結束後該程序也會結束。unit file 可讓服務在重新開機後持續執行。
[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-stringsudo 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 找不到該位置。若 unit 啟動後立即結束,表示 npm 內部發生錯誤;journalctl -u memmy-memory -n 50 會輸出原因。其運作方式與 VPS 上的其他 systemd 服務 相同。
Memmy 目前尚未支援的功能
- 目前沒有 Linux 桌面版本。打包腳本涵蓋 macOS 和 Windows,因此 workbench、引導精靈與記憶體儀表板無法直接在伺服器上使用。
memory:serve:dev會透過tsx執行 TypeScript 進入點,這是開發用流程。儲存庫也提供編譯輸出的memory:serve。不帶引數執行npm run,即可查看目前 checkout 實際包含哪些腳本。- 擷取流程會從最新的 2,000 筆向量資料列建立搜尋範圍,再在該範圍內套用 Top-K 選取。在非常大的儲存庫中,較舊的記憶可能位於搜尋範圍之外。
- 擷取完成後才會建立 embedding。若建立失敗,項目會進入重試佇列,不會阻塞 agent 的回合。剛加入的記憶可能尚未能透過向量搜尋找到。
- 一個 SQLite 檔案只能對應一個節點。目前沒有叢集功能,因此第二台伺服器會是另一個獨立的記憶體。
截至 2026 年 7 月,版本 1.0.4 約有 329 顆星,顯示這仍是年輕的專案。不同版本之間可能會變更旗標、路徑與腳本名稱。請查看自己 checkout 中的 bin 欄位,以及 npm run 的輸出,不要盲目相信從任何地方複製的指令,包括本文。
FAQ
為什麼 health check 會回傳 connection refused?
port 18960 上沒有任何程式在監聽。curl exit code 7 搭配 Failed to connect to 127.0.0.1 port 18960 表示 memory service 尚未執行,或在啟動時中止,因此請查看啟動服務的 terminal 或 journal。最常見的兩個原因是:better-sqlite3 native module 與 Node 版本不相容,可用 npm rebuild better-sqlite3 修正;以及 Node 版本低於 22。服務啟動後,使用 ss -lntp | grep 18960 確認 socket。
從 source 建置後,memmy-memory command 從何而來?
它來自 @memmy/memory workspace package 的 bin field,而不是 repository 名稱。在 checkout 目錄內執行 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 執行,或將它 symlink 到 /usr/local/bin,以使用短名稱。
我可以使用 claude mcp add 將 Memmy 加入 Claude Code 嗎?
不行。Memmy 是 MCP client,不是 MCP server。它會連出至 ~/.memmy/config.yaml 中 tools.mcpServers 所列的 server,並將這些 server 提供的 tools 提供給自己的 runtime。Claude Code 則是透過另一種方式存取 Memmy:將 memmy-memory CLI 當作 shell command 執行,並依據 memmy-memory init --agent 寫入 agent rules directory 的 instruction file 操作。
執行 Memmy 會將我的 memories 傳送到 cloud service 嗎?
掃描與 ingestion 都在本機執行,memories 會寫入你自己磁碟上的 ~/.memmy/memory-service/memory.sqlite。MEMMY_CLOUD_SERVICE 會在 account mode 與 trial tokens 下指向 https://memmy-api.memtensor.cn,而 memory improvement program 在你啟用前會保持關閉。需要注意的路徑是 embedding provider:hosted embedding model 會接收每個 memory 的文字,並將其轉換為 vector;如果這點很重要,請使用由你自行執行的 endpoint。