SSD Nodes Learn 8GB RAM — $66/năm
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-01

Memmy: memory hub local cho AI agent trên VPS

Memmy tạo shared memory bằng SQLite cho AI agent trên VPS. Bài hướng dẫn build từ source trên Ubuntu, chạy service ở port 18960 và giữ mọi note local.

Memmy là gì và lưu trữ gì

Memmy là một memory hub cục bộ cho các AI agent, chạy trên VPS (virtual private server) của bạn. Memmy lưu một cơ sở dữ liệu SQLite về những gì các agent đã học, và mọi agent trên máy chủ đều đọc và ghi vào cùng kho dữ liệu đó. Dự án này được memmy-agent từ MemTensor, được cấp phép theo MIT, ở phiên bản 1.0.4 tính đến tháng 7 năm 2026.

Trên server, chỉ một phần của Memmy là cần thiết. Memmy cung cấp một memory service lắng nghe trên http://127.0.0.1:18960, một memmy-memory command line interface (CLI) giao tiếp với service đó, và một desktop workbench. Workbench chỉ được đóng gói cho macOS và Windows, nên trên Linux VPS bạn chạy service và CLI. Như vậy là đủ để cung cấp shared memory cho Claude Code, Codex và Cursor.

Memmy phân loại dữ liệu được lưu trữ thành bốn layer. L1 Trace là lượt tương tác thô: request, response và các lần gọi tool. L2 Policy là một quy trình được suy ra từ các trace đã chứng minh là hữu ích. L3 World Model là kiến thức ổn định về một project hoặc một môi trường. Skill là một quy trình có thể gọi, được kết tinh từ một policy. Service tự gán layer khi ingest một lượt tương tác, nên bạn không cần tạo các layer này thủ công.

Hub memory dùng chung thay đổi gì so với memory riêng của từng tool

Mỗi agent hiện nay đều có memory riêng. Claude Code lưu các file chỉ dẫn trong repository. Cursor lưu rules trong cơ sở dữ liệu workspace. Codex lưu session log tại ~/.codex. Mỗi kho lưu trữ chỉ thuộc về một tool, nên thông tin bạn đã hướng dẫn cho một tool vào thứ Hai sẽ không được biết đến ở tool khác vào thứ Ba. Bạn phải trả giá hai lần: một lần bằng token để giải thích lại cùng một project, và một lần bằng công việc sai khi agent dựa trên giả định mà bạn đã sửa ở nơi khác.

Hub đưa kho lưu trữ ra khỏi tool. Memmy cũng đọc các kho lưu trữ hiện có, nên bạn không phải bắt đầu với một database trống. Scanner của nó biết 6 nguồn: Claude Code tại ~/.claude/projects/**/*.jsonl, Codex tại ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl, OpenCode tại ~/.local/share/opencode/opencode.db, các file state.vscdb của Cursor, các database SQLite của OpenClaw dưới ~/.openclaw và Hermes dưới ~/.hermes. Bạn có thể thêm nguồn thủ công bằng tên và path cục bộ.

Các bộ đếm import sẽ không khớp nhau, và đó là điều bình thường. Scanner nhóm các message theo source và conversation, sau đó ghi một memory L1 cho mỗi lượt hoàn chỉnh. Một lượt được xem là hoàn chỉnh khi có nội dung user không rỗng và kết thúc bằng message assistant không rỗng, nên một session bị gián đoạn sẽ không đóng góp dữ liệu. Các message được loại trùng bằng checkpoint của conversation và turn ID ổn định. Số lượng đã scan, số message đã import và số memory mới đều khác nhau trong cùng một lần chạy.

Đây là phần kết hợp với cách Claude Code quản lý context trong một session. Quản lý context quyết định nội dung nào vừa trong một window. Hub memory quyết định nội dung nào còn lại sau khi window đó đóng.

Những thứ bạn cần trên VPS

  • Node.js 22 trở lên. Tài liệu Memmy yêu cầu phiên bản này, còn Ubuntu 24.04 cung cấp Node 18.
  • git và bộ công cụ build, vì better-sqlite3 là native module có thể được biên dịch trong quá trình cài đặt.
  • Khoảng 2 GB RAM. Cài đặt root tải về một workspace lớn và chuỗi công cụ build frontend.
  • Vài GB dung lượng đĩa trống cho node_modules và cơ sở dữ liệu.
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 phải in ra v22 hoặc cao hơn. v18 ở đây có nghĩa là bước NodeSource chưa áp dụng, và quá trình cài đặt sau đó sẽ thất bại khi kiểm tra engine của dự án.

Cài đặt Memmy từ mã nguồn trên Ubuntu 24.04

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 biên dịch workspace @memmy/memory thành Memory/dist. Không cần build phần nào khác trong cây mã nguồn trên server headless. Kiểm tra xem native module đã được nạp chưa:

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

Nếu dòng đó báo lỗi thay vì in kết quả, native module không tương thích với phiên bản Node của bạn. Chạy npm rebuild better-sqlite3. Đây chính xác là lệnh mà start script của dự án chạy trước khi khởi động bất kỳ thành phần nào.

README mô tả bash scripts/dev-start.sh là lệnh khởi động duy nhất. Không chạy lệnh này trên VPS headless. Lệnh này khởi động Electron desktop shell và Vite dev server trên port 19000 cùng với memory service. Electron cần display, nên trên server không có graphical session, script sẽ bị treo hoặc thoát.

Khởi động memory service và kiểm tra phản hồi

npm run memory:serve:dev

Đây là cách được tài liệu hướng dẫn để chạy memory service từ source. Service bind vào 127.0.0.1:18960, lưu database tại ~/.memmy/memory-service/memory.sqlite và đọc cấu hình từ ~/.memmy/config.yaml. README cũng ghi rõ các giá trị này khi bạn muốn chỉ định tường minh:

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

Từ shell thứ hai, yêu cầu service kiểm tra trạng thái hoạt động:

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

Health là endpoint duy nhất không yêu cầu token, nên đây là probe phù hợp. Nếu curl thoát với mã 7 và thông báo Failed to connect to 127.0.0.1 port 18960, không có process nào đang listen. Kiểm tra terminal đang chạy service, vì lỗi crash khi khởi động sẽ được in ở đó. Nguyên nhân thường gặp là native SQLite module không load được. ss -lntp | grep 18960 xác nhận socket sau khi service khởi động.

Phần còn lại của HTTP API (application programming interface) nằm dưới /api/v1.

  • POST /api/v1/memory/add ghi một memory và POST /api/v1/memory/search truy vấn.
  • GET /api/v1/memory/:idDELETE /api/v1/memory/:id đọc và xóa một entry.
  • POST /api/v1/sessions/openPOST /api/v1/sessions/:sessionId/close bao quanh một agent session.
  • POST /api/v1/turns/startPOST /api/v1/turns/:turnId/complete ghi lại một lượt trao đổi.
  • GET /api/v1/panel/overview, /api/v1/panel/analysis/api/v1/panel/items cung cấp dữ liệu cho dashboard.

Memmy dành riêng một dải port. Trong chế độ headless, bạn chỉ dùng các port đầu tiên: 18960 cho memory, 18970 cho gateway health, 18980 cho web UI và admin HTTP, 18990 cho API tương thích OpenAI do memmy serve khởi động, sau đó là 19000 và 19010 cho dev server của desktop frontend. Nếu một process trên máy bạn đang chiếm một trong các port đó, hãy kiểm tra danh sách này trước.

Lệnh memmy-memory thực sự xuất phát từ đâu

Đây là chỗ lần cài đặt đầu tiên thường gặp lỗi, vì vậy hãy đọc từ package thay vì đoán. Tên lệnh không liên quan đến tên repository. Nó xuất phát từ trường bin của workspace định nghĩa lệnh đó:

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

Lệnh này in ra {"memmy-memory":"./dist/src/cli/index.js"}. Vì vậy entry point đã build là Memory/dist/src/cli/index.js. File này chỉ tồn tại sau khi chạy npm run memory:build, vì quá trình build tạo dist và đánh dấu file là executable. Chạy trực tiếp:

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

Nếu muốn dùng tên ngắn trên PATH, hãy tạo link đến chính file đó:

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

CLI mặc định dùng http://127.0.0.1:18960 và chấp nhận --url, --token, --config, --source--user-id. Các subcommand của nó là init, health, search, add, getdelete, cùng với các lệnh gọi session và turn mà agent sử dụng thay vì người dùng. memmy-memory search "deploy steps"memmy-memory add "staging migrates on deploy" là hai lệnh agent chạy thường xuyên nhất.

Làm thế nào để kết nối Claude Code với Memmy?

Claude Code không có interface plugin cho memory, nên Memmy không hook vào đó. Tích hợp đơn giản hơn thế. Claude Code chạy memmy-memory như một shell command thông thường, và một file instruction cho nó biết khi nào cần chạy. Installer được tài liệu hóa của Memmy sẽ ghi file đó giúp bạn: memmy-memory init --agent đặt một file instruction về memory vào rules directory của agent đích.

Hãy tự viết instruction một lần, vì khi đó bạn biết chính xác agent đã được yêu cầu làm gì. Claude Code đọc CLAUDE.md từ project root khi bắt đầu mỗi session, nên một section như sau là toàn bộ phần tích hợp:

## 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.

Cần hiểu rõ lợi ích thực tế của cách này. Đây là tích hợp ở cấp instruction, nên chỉ hoạt động khi model quyết định chạy command; nếu không thì không hoạt động. Không có gì bắt buộc nó phải gọi command. Nếu session kết thúc mà không có add, không có gì được lưu và tín hiệu duy nhất là kết quả rỗng vào lần search tiếp theo. Đây cũng là đánh đổi giống các file memory riêng của Claude Code, nhưng có một điểm khác: store được chia sẻ, nên note cũng có thể được Codex và Cursor trên cùng máy truy cập.

Chiều ngược lại không cần setup nào. Scanner của Memmy đã đọc ~/.claude/projects/**/*.jsonl, là nơi Claude Code ghi các session transcript. Chạy Memmy trên cùng server với nơi bạn chạy Claude Code bên trong một session tmux; công việc của ngày hôm qua sẽ trở thành memory mà bạn không cần cấu hình gì thêm.

Memmy có hoạt động như một MCP server cho Claude Code không?

Không. Hiểu rõ hướng kết nối sẽ giúp bạn tránh mất cả buổi chiều. MCP (model context protocol) có client và server. Memmy là một client. Nó kết nối đến các MCP server và cung cấp các tool của chúng cho runtime agent riêng. Memmy không công khai MCP endpoint để claude mcp add kết nối đến. Cầu nối MCP duy nhất trong repository thuộc về tích hợp Composio bên trong local API của desktop. API này bind vào một port ngẫu nhiên trên 127.0.0.1 và dùng header x-memmy-mcp-token riêng.

Phía client được cấu hình trong ~/.memmy/config.yaml, là file được MEMMY_CONFIG trỏ đến, bên dưới tools.mcpServers:

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

type chấp nhận stdio, ssestreamableHttp. Một MCP server stdio chạy dưới dạng child process của Memmy. Vì vậy, command của server phải tồn tại trên cùng máy và chạy với cùng user. Nếu bạn đã duy trì MCP server chạy trên VPS, hãy liệt kê chúng tại đây.

Giữ kho bộ nhớ ở chế độ riêng tư

Mọi dữ liệu Memmy sở hữu đều nằm dưới ~/.memmy: config.yaml, workspace, memory-service/memory.sqlite và các tệp runtime. Việc quét và nạp dữ liệu diễn ra cục bộ. Các memory được ghi vào tệp SQLite cục bộ đó, nên mặc định hệ thống thực sự hoạt động cục bộ.

Có 2 đường đi ra network. MEMMY_CLOUD_SERVICE mặc định trỏ đến https://memmy-api.memtensor.cn và hỗ trợ account mode bằng trial token của nó, nên API key mode không bao giờ gọi đến đó. Chương trình cải thiện memory là một toggle riêng trong privacy settings và được tắt cho đến khi bạn bật.

Có một đường thứ ba dễ bị bỏ sót. Nếu bạn cấu hình hosted embedding provider, nội dung của mọi memory sẽ được gửi đến provider đó để chuyển thành vector. Lưu trữ cục bộ không ngăn được việc này. Cách duy nhất để đóng đường này là tự host embedding endpoint.

Giữ port 18960 trên địa chỉ loopback. Port này không cần firewall rule, vì service bind vào 127.0.0.1 hoàn toàn không thể truy cập từ bên ngoài máy. Thay vào đó, hãy truy cập từ laptop qua SSH:

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

Nếu bạn bind service trên phạm vi rộng hơn, hãy đặt token trước. Đặt storage.token trong config, hoặc đặt biến môi trường MEMMY_MEMORY_TOKEN hay MEMORY_SERVICE_TOKEN, sẽ khiến mọi endpoint, ngoại trừ health endpoint, yêu cầu bearer token. Các giá trị trong config hỗ trợ tham chiếu ${ENV_NAME}, nên token và model API key không phải nằm trực tiếp trong file. Đây cũng là nguyên tắc giữ secret ngoài AI agent được áp dụng ở mọi nơi khác, còn ufw policy mặc định deny là lớp bảo vệ dự phòng nếu phiên bản tương lai thay đổi địa chỉ bind mặc định.

Sao lưu ~/.memmy trước khi tin dùng

memory.sqlite là toàn bộ kho dữ liệu. Các vector nằm trong cùng tệp đó thông qua extension sqlite-vec, nên chỉ cần sao lưu một tệp. Dùng cp để sao chép khi service đang ghi có thể tạo ra database không nhất quán. Hãy dùng lệnh backup riêng của SQLite:

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

Lệnh này tạo một bản sao nhất quán trong khi service vẫn chạy. Định kỳ đẩy bản sao đó ra khỏi máy; restic tới bộ nhớ lưu trữ ngoài site dùng cho việc này. Mất config.yaml chỉ khiến bạn mất các cài đặt provider, có thể nhập lại. Mất memory.sqlite khiến bạn mất toàn bộ memory, và không có bản sao thứ hai nào trên máy.

Chạy memory service dưới systemd

npm run memory:serve:dev trong shell sẽ dừng khi shell dừng. Unit file giữ cho service tiếp tục chạy sau khi reboot.

[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

Không để token trong unit. Đặt token vào /etc/memmy/memory.env, gán quyền sở hữu cho root và đặt mode 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 trong output trạng thái có nghĩa là systemd không thể chạy ExecStart ngay từ đầu. Vì vậy, hãy kiểm tra which npm: trên bản cài NodeSource, đây là /usr/bin/npm; còn với nvm, nó nằm ở đâu đó trong home của người dùng, và systemd sẽ không tìm thấy. Unit khởi động rồi thoát ngay đã gặp lỗi bên trong npm. journalctl -u memmy-memory -n 50 sẽ in ra nguyên nhân. Cách vận hành giống như bất kỳ systemd service nào khác trên VPS.

Memmy hiện chưa làm được gì

  • Hiện chưa có bản build desktop cho Linux. Các script đóng gói chỉ hỗ trợ macOS và Windows, nên workbench, trình hướng dẫn onboarding và dashboard memory không có trên chính server.
  • memory:serve:dev chạy entry point TypeScript thông qua tsx, đây là đường chạy dành cho development. Repository cũng cung cấp memory:serve cho output đã compile. Chạy npm run không có argument để xem checkout của bạn thực sự có những script nào.
  • Retrieval tạo search window từ 2,000 vector row mới nhất, sau đó áp dụng lựa chọn Top-K trong window đó. Với store rất lớn, một memory cũ có thể nằm ngoài window này.
  • Embedding diễn ra sau khi capture. Nếu thất bại, tác vụ được đưa vào retry queue thay vì chặn lượt chạy của agent. Một memory vừa được thêm có thể chưa thể tìm thấy bằng vector search.
  • Một file SQLite chỉ tương ứng với một node. Không có clustering, nên server thứ hai sẽ có memory riêng, tách biệt.

Version 1.0.4 và khoảng 329 star tính đến tháng 7 năm 2026 cho thấy đây là một project còn mới. Flag, path và tên script có thể thay đổi giữa các release. Hãy đọc field bin và output của npm run trong checkout của bạn, thay vì tin vào một command được sao chép từ bất kỳ đâu, kể cả nội dung ở đây.

FAQ

Vì sao health check trả về lỗi từ chối kết nối?

Không có tiến trình nào đang lắng nghe trên port 18960. Mã thoát 7 của curl cùng với Failed to connect to 127.0.0.1 port 18960 nghĩa là memory service chưa chạy hoặc đã dừng khi khởi động. Hãy đọc output trong terminal hoặc journal nơi service được khởi động. Hai nguyên nhân thường gặp là module native better-sqlite3 không tương thích với phiên bản Node của bạn, có thể sửa bằng npm rebuild better-sqlite3, và phiên bản Node thấp hơn 22. Khi service đã chạy, hãy xác nhận socket bằng ss -lntp | grep 18960.

Lệnh memmy-memory xuất hiện từ đâu sau khi build từ source?

Lệnh này lấy từ trường bin của package workspace @memmy/memory, không phải từ tên repository. Chạy node -p "JSON.stringify(require('./Memory/package.json').bin)" bên trong thư mục checkout để in ra {"memmy-memory":"./dist/src/cli/index.js"}. File đó chỉ tồn tại sau npm run memory:build, vì quá trình build tạo dist và đánh dấu file là executable. Chạy file bằng node Memory/dist/src/cli/index.js health, hoặc tạo symlink đến /usr/local/bin để dùng tên ngắn.

Tôi có thể thêm Memmy vào Claude Code bằng claude mcp add không?

Không. Memmy là MCP client, không phải MCP server. Nó kết nối đến các server được liệt kê trong tools.mcpServers~/.memmy/config.yaml và cung cấp các tool của chúng cho runtime của chính nó. Claude Code kết nối với Memmy theo hướng ngược lại, bằng cách chạy CLI memmy-memory dưới dạng shell command. Việc này được hướng dẫn bởi instruction file mà memmy-memory init --agent ghi vào rules directory của agent.

Chạy Memmy có gửi memory của tôi đến cloud service không?

Việc quét và ingestion chạy cục bộ. Memory được ghi vào ~/.memmy/memory-service/memory.sqlite trên chính disk của bạn. MEMMY_CLOUD_SERVICE trỏ đến https://memmy-api.memtensor.cn để dùng account mode và trial token. Chương trình cải thiện memory vẫn tắt cho đến khi bạn bật nó. Thành phần cần theo dõi là embedding provider: hosted embedding model sẽ nhận text của mọi memory mà nó chuyển thành vector. Nếu điều này quan trọng, hãy dùng endpoint do bạn tự vận hành.