Memmy:在 VPS 上建立 AI 代理共用記憶體
Memmy 將 AI 代理的記憶集中在本機 SQLite 資料庫。本文說明如何在 Ubuntu 從原始碼建置,啟動 port 18960 的服務,並讓 Claude Code、Codex 與 Cursor 共用。
Memmy 的用途與儲存內容
Memmy 是在您自己的 VPS (virtual private server) 上執行的 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 是從原則具體化而成的可呼叫程序。服務在擷取回合時會指派層級,因此您不必手動建立這些層級。
共用記憶中樞與各工具個別記憶的差異
目前每個代理程式都有自己的記憶體。Claude Code 會將指示檔案儲存在存放庫中。Cursor 會將規則儲存在其工作區資料庫中。Codex 會將工作階段記錄儲存在 ~/.codex 下。每個儲存區都隸屬於單一工具,因此您週一在某個工具中教導的資訊,週二在另一個工具中仍然無法取得。這會產生兩種成本:一是重複說明同一個專案所耗用的權杖,二是代理程式根據您已在其他位置修正的假設執行錯誤工作。
中樞會將儲存區移出工具。Memmy 也會讀取現有的儲存區,因此您不必從空白資料庫開始。其掃描器支援 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 資料庫,以及位於 ~/.hermes 的 Hermes。您可以手動新增來源,指定名稱和本機路徑。
匯入計數不會一致,這是預期行為。掃描器會依來源和對話將訊息分組,然後為每個完整回合寫入一筆 L1 記憶。當回合包含非空白的使用者內容,且以非空白的代理程式訊息結束時,才算完整。因此,中斷的工作階段不會產生任何內容。訊息會透過對話檢查點和穩定的回合 ID 去除重複。同一次執行中,掃描數、匯入訊息數和新增記憶數都會不同。
這是與Claude Code 如何在單一工作階段內管理內容相互配合的部分。內容管理決定單一視窗能容納哪些內容。記憶中樞則決定視窗關閉後哪些內容仍會保留。
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,以及在 port 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 的端點,因此適合作為探測端點。如果 curl 以代碼 7 結束,並顯示 Failed to connect to 127.0.0.1 port 18960 訊息,表示沒有任何程序正在監聽。查看執行服務的終端機,因為服務啟動時發生當機會在該處輸出,最常見的原因是原生 SQLite 模組載入失敗。服務啟動後,ss -lntp | grep 18960 會確認 socket。
其餘 HTTP API(應用程式介面)位於 /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會標示代理程式工作階段的開始與結束。POST /api/v1/turns/start和POST /api/v1/turns/:turnId/complete會記錄一個回合。GET /api/v1/panel/overview、/api/v1/panel/analysis和/api/v1/panel/items會將資料提供給儀表板。
Memmy 會保留一組連續的連接埠;在無頭模式下只會使用其中第一個:18960 用於記憶體服務、18970 用於 gateway health、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 healthCLI 預設為 http://127.0.0.1:18960,並接受 --url、--token、--config、--source 和 --user-id。其子命令包括 init、health、search、add、get 和 delete,此外還有由代理程式使用、而非由人員使用的工作階段與回合呼叫。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 也能取得該筆記錄。
反向整合完全不需要設定。Memmy 的掃描器已經會讀取 ~/.claude/projects/**/*.jsonl,Claude Code 會將其工作階段逐字稿寫入此處。在執行 tmux 工作階段中的 Claude Code 的同一部伺服器上執行 Memmy,昨天的工作就會自動成為記憶,不需要進行任何設定。
Memmy 是否可作為 Claude Code 的 MCP 伺服器?
不可以。了解這個方向可節省一下午的時間。MCP(model context protocol)包含用戶端和伺服器。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 接受 stdio、sse 和 streamableHttp。stdio 伺服器會作為 Memmy 的子程序執行,因此其命令必須存在於同一台主機上,並以相同的使用者身分執行。如果您已在 VPS 上執行 MCP 伺服器,請將這些伺服器列於此處。
保持記憶儲存區為私有
Memmy 擁有的所有內容都位於 ~/.memmy 下:config.yaml、工作區、memory-service/memory.sqlite 和執行階段檔案。掃描與擷取作業都在本機執行,記憶也會寫入本機 SQLite 檔案,因此預設狀態確實是本機運作。
有兩條路徑會連線至網路。MEMMY_CLOUD_SERVICE 預設為 https://memmy-api.memtensor.cn,並以試用權杖支援帳戶模式,因此 API 金鑰模式不會呼叫它。記憶改善計畫是隱私設定中的獨立切換選項,除非你手動開啟,否則會維持關閉。
第三條路徑較容易被忽略。如果你設定代管的嵌入提供者,每則記憶的文字都會傳送至該提供者,以轉換為向量。本機儲存無法避免這種傳送。只有自行代管嵌入端點,才能完全阻止資料離開本機。
請讓連接埠 18960 綁定至迴路位址。這不需要防火牆規則,因為綁定至 127.0.0.1 的服務完全無法從本機以外連線。請改用 SSH 從筆記型電腦連線:
ssh -N -L 18960:127.0.0.1:18960 you@your-vps如果你需要將服務綁定至更廣泛的位址,請先設定權杖。在設定中設定 storage.token,或設定 MEMMY_MEMORY_TOKEN 或 MEMORY_SERVICE_TOKEN 環境變數後,除了 health 端點外,所有端點都會要求 bearer token。設定值支援 ${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 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請勿將權杖放在 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 選取。在非常大的儲存區中,較舊的記憶可能位於搜尋範圍之外。
- 擷取完成後才會建立嵌入向量。若建立失敗,系統會將工作放入重試佇列,而不會阻塞代理程式回合。剛加入的記憶可能尚未能透過向量搜尋找到。
- 一個 SQLite 檔案只能對應一個節點。目前沒有叢集功能,因此第二部伺服器會使用另一份獨立的記憶。
截至 2026 年 7 月,版本 1.0.4 約有 329 顆星,顯示這仍是早期專案。不同版本之間可能會變更旗標、路徑與指令碼名稱。請查看自己 checkout 中的 bin 欄位,以及 npm run 的輸出,不要直接信任從任何地方複製的指令,包括本文中的指令。
FAQ
為什麼健康檢查會回傳連線遭拒?
連接埠 18960 上沒有任何服務正在監聽。curl 結束代碼 7 與 Failed to connect to 127.0.0.1 port 18960 表示記憶體服務未執行,或在啟動時終止,因此請查看服務啟動時所在的終端機輸出或 journal。最常見的兩個原因是與 Node 版本不相容的 better-sqlite3 原生模組,可使用 npm rebuild better-sqlite3 修正;另一個原因是 Node 版本低於 22。服務啟動後,使用 ss -lntp | grep 18960 確認 socket。
從原始碼建置後,memmy-memory 命令來自哪裡?
它來自 @memmy/memory 工作區套件的 bin 欄位,而不是儲存庫名稱。在 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 執行,或將它建立符號連結至 /usr/local/bin,以使用簡短名稱。
我可以使用 claude mcp add 將 Memmy 加入 Claude Code 嗎?
不可以。Memmy 是 MCP 用戶端,不是 MCP 伺服器。它會連線至 ~/.memmy/config.yaml 中 tools.mcpServers 下列出的伺服器,並將這些伺服器的工具提供給自身的執行環境。Claude Code 則透過另一種方式存取 Memmy:將 memmy-memory CLI 當作 shell 命令執行,並依據 memmy-memory init --agent 寫入代理程式規則目錄的指示檔操作。
執行 Memmy 會將我的記憶傳送至雲端服務嗎?
掃描與擷取程序都在本機執行,記憶會寫入您自己磁碟上的 ~/.memmy/memory-service/memory.sqlite。MEMMY_CLOUD_SERVICE 會在帳戶模式與試用權杖中指向 https://memmy-api.memtensor.cn,而記憶改善計畫在您啟用前都維持關閉。需要監控的項目是嵌入提供者:託管的嵌入模型會接收每筆記憶的文字,並將其轉換為向量;如果這點很重要,請使用您自行執行的端點。