SSD Nodes Learn 🎉 VPS dari $4.99/bln
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-07

Cara Pasang Memmy Sebagai Hab Memori Ejen AI di VPS

Gunakan Memmy untuk menyatukan memori ejen AI anda pada satu storan SQLite tempatan. Ikuti panduan membina dari sumber pada Ubuntu dan jalankan servis pada port 18960.

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

Apakah Memmy dan perkara yang disimpannya

Memmy ialah hab memori setempat untuk ejen AI yang dijalankan pada VPS (virtual private server) anda sendiri. Ia menyimpan satu pangkalan data SQLite tentang perkara yang telah dipelajari oleh ejen anda, dan setiap ejen pada pelayan tersebut membaca serta menulis ke storan yang sama. Projek ini adalah memmy-agent daripada MemTensor, dilesenkan di bawah MIT, pada versi 1.0.4 setakat Julai 2026.

Hanya sebahagian daripadanya penting pada pelayan. Memmy membekalkan servis memori yang mendengar pada http://127.0.0.1:18960, antara muka baris perintah (CLI) memmy-memory yang berhubung dengan servis tersebut, dan sebuah workbench desktop. Workbench tersebut dibungkus untuk macOS dan Windows sahaja, jadi pada VPS Linux anda hanya menjalankan servis dan CLI. Itu sudah memadai untuk memberikan Claude Code, Codex dan Cursor memori yang dikongsi.

Memmy menyusun perkara yang disimpannya kepada empat lapisan. L1 Trace ialah giliran mentah: permintaan, respons dan panggilan alat. L2 Policy ialah prosedur yang diterbitkan daripada trace yang terbukti berguna. L3 World Model ialah pengetahuan stabil tentang sesuatu projek atau persekitaran. Skill ialah prosedur boleh panggil yang dikristalkan daripada sesuatu polisi. Servis tersebut menetapkan lapisan apabila ia menyerap sesuatu giliran, jadi anda tidak perlu menciptanya secara manual.

Perubahan yang dibawa oleh hab memori berkongsi berbanding memori setiap alat

Setiap ejen pada masa kini membawa memorinya sendiri. Claude Code menyimpan fail arahan di dalam repositori. Cursor menyimpan peraturan di dalam pangkalan data ruang kerja. Codex menyimpan log sesi di bawah ~/.codex. Setiap storan adalah milik satu alat, jadi fakta yang anda ajarkan pada hari Isnin dalam satu alat tidak diketahui pada hari Selasa dalam alat yang lain. Anda membayar untuk perkara itu dua kali: sekali dalam token yang dibelanjakan untuk menerangkan semula projek yang sama, dan sekali lagi dalam kerja yang salah apabila ejen bertindak berdasarkan andaian yang telah anda betulkan di tempat lain.

Satu hab memindahkan storan keluar daripada alat tersebut. Memmy juga membaca storan sedia ada, jadi anda tidak bermula daripada pangkalan data yang kosong. Pengimbasnya mengenali enam sumber: Claude Code di ~/.claude/projects/**/*.jsonl, Codex di ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl, OpenCode di ~/.local/share/opencode/opencode.db, fail state.vscdb milik Cursor, pangkalan data SQLite OpenClaw di bawah ~/.openclaw, dan Hermes di bawah ~/.hermes. Anda boleh menambah sumber secara manual dengan nama dan laluan setempat.

Pembilang import tidak akan selari, dan itu adalah perkara biasa. Pengimbas mengumpulkan mesej mengikut sumber dan perbualan, kemudian menulis satu memori L1 bagi setiap giliran yang lengkap. Satu giliran dikira lengkap apabila ia mempunyai kandungan pengguna yang tidak kosong dan berakhir dengan mesej pembantu yang tidak kosong, jadi sesi yang terganggu tidak menyumbang apa-apa. Mesej dinyahduplikasi dengan titik semak perbualan dan ID giliran yang stabil. Kiraan yang diimbas, kiraan mesej yang diimport, dan kiraan memori baharu semuanya berbeza dalam satu pelaksanaan yang sama.

Ini adalah bahagian yang dipadankan dengan cara Claude Code mengurus konteks dalam satu sesi. Pengurusan konteks menentukan perkara yang muat dalam satu tetingkap. Hab memori menentukan perkara yang kekal selepas tetingkap itu ditutup.

Keperluan pada VPS

  • Node.js 22 atau lebih baharu. Dokumentasi Memmy memerlukannya, manakala Ubuntu 24.04 menyertakan Node 18.
  • git dan rantaian alat binaan (build toolchain), kerana better-sqlite3 ialah modul natif yang mungkin perlu dikompilasi semasa pemasangan.
  • Sekitar 2 GB RAM. Pemasangan root menarik ruang kerja yang besar dan rantaian binaan bahagian hadapan (frontend).
  • Beberapa GB ruang cakera kosong untuk node_modules dan pangkalan data.
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 sepatutnya memaparkan v22 atau lebih tinggi. v18 di sini bermakna langkah NodeSource tidak berjaya, dan pemasangan akan gagal kemudian semasa pemeriksaan enjin projek.

Memasang Memmy daripada sumber pada 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 menyusun @memmy/memory workspace menjadi Memory/dist. Tiada komponen lain dalam pepohon tersebut yang perlu dibina untuk pelayan tanpa kepala (headless server). Pastikan modul natif telah dimuatkan:

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

Jika baris tersebut mengeluarkan ralat dan bukannya mencetak output, bermakna modul natif tidak sepadan dengan versi Node anda. Jalankan npm rebuild better-sqlite3, iaitu langkah yang sama dilakukan oleh skrip permulaan projek sebelum ia melancarkan apa-apa.

README mendokumentasikan bash scripts/dev-start.sh sebagai arahan untuk bermula dengan satu perintah. Jangan jalankan arahan ini pada VPS tanpa kepala. Ia memulakan shell desktop Electron dan pelayan pembangunan Vite pada port 19000 di samping servis memori. Memandangkan Electron memerlukan paparan, skrip tersebut akan terhenti atau keluar secara paksa pada pelayan yang tidak mempunyai sesi grafik.

Mulakan servis memori dan pastikan ia memberi respons

npm run memory:serve:dev

Itu merupakan cara yang didokumentasikan untuk menjalankan servis memori daripada sumber. Ia mengikat 127.0.0.1:18960, menyimpan pangkalan data di ~/.memmy/memory-service/memory.sqlite, dan membaca konfigurasi daripada ~/.memmy/config.yaml. Fail README menyatakan nilai yang sama apabila anda mahukannya secara eksplisit:

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

Daripada shell kedua, tanya servis tersebut sama ada ia masih aktif:

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

Health ialah satu-satunya endpoint yang tidak pernah meminta token, itulah sebabnya ia merupakan probe yang tepat. Jika curl keluar dengan kod 7 dan mesej Failed to connect to 127.0.0.1 port 18960, tiada apa yang sedang mendengar. Baca terminal yang menjalankan servis tersebut, kerana kegagalan semasa permulaan akan dicetak di situ, dan punca lazimnya ialah modul asli SQLite gagal dimuatkan. ss -lntp | grep 18960 mengesahkan soket sebaik sahaja servis tersebut aktif.

Selebihnya HTTP API (application programming interface) terletak di bawah /api/v1.

  • POST /api/v1/memory/add menulis memori dan POST /api/v1/memory/search membuat pertanyaan.
  • GET /api/v1/memory/:id dan DELETE /api/v1/memory/:id membaca serta membuang satu entri.
  • POST /api/v1/sessions/open dan POST /api/v1/sessions/:sessionId/close mengapit satu sesi ejen.
  • POST /api/v1/turns/start dan POST /api/v1/turns/:turnId/complete merekod satu giliran.
  • GET /api/v1/panel/overview, /api/v1/panel/analysis dan /api/v1/panel/items membekalkan data kepada papan pemuka.

Memmy menempah satu blok port, dan secara headless anda hanya menggunakan yang pertama: 18960 untuk memori, 18970 untuk kesihatan gateway, 18980 untuk UI web dan HTTP admin, 18990 untuk API yang serasi dengan OpenAI yang dimulakan oleh memmy serve, kemudian 19000 dan 19010 untuk pelayan pembangunan frontend desktop. Jika sesuatu pada mesin anda sudah menggunakan salah satu port tersebut, senarai itulah tempat untuk diperiksa.

Dari mana datangnya perintah memmy-memory

Di sinilah pemasangan kali pertama biasanya gagal, jadi bacalah daripada pakej dan bukannya meneka. Nama perintah tiada kaitan dengan nama repositori. Ia datang daripada medan bin dalam ruang kerja yang mentakrifkannya:

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

Perintah itu mencetak {"memmy-memory":"./dist/src/cli/index.js"}. Jadi, titik masuk yang dibina ialah Memory/dist/src/cli/index.js, dan ia hanya wujud selepas npm run memory:build, kerana proses binaanlah yang mencipta dist dan menandakan fail tersebut sebagai boleh laku (executable). Jalankan ia secara terus:

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

Jika anda mahukan nama pendek pada PATH anda, pautkan fail yang sama:

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

CLI ini menggunakan http://127.0.0.1:18960 sebagai lalai dan menerima --url, --token, --config, --source serta --user-id. Subperintahnya ialah init, health, search, add, get dan delete, ditambah dengan panggilan session dan turn yang digunakan oleh ejen dan bukannya manusia. memmy-memory search "deploy steps" dan memmy-memory add "staging migrates on deploy" adalah dua perintah yang paling kerap dijalankan oleh ejen.

Bagaimanakah anda menyambungkan Claude Code kepada Memmy?

Claude Code tidak mempunyai antara muka pemalam memori, jadi Memmy tidak berhubung dengannya secara terus. Integrasinya lebih ringkas daripada itu. Claude Code menjalankan memmy-memory sebagai arahan shell biasa, dan fail arahan memberitahunya bila untuk melakukannya. Pemasang yang didokumentasikan oleh Memmy menulis fail tersebut untuk anda: memmy-memory init --agent meletakkan fail arahan memori ke dalam direktori peraturan ejen sasaran.

Tulis arahan tersebut secara manual sekali, supaya anda tahu dengan tepat apa yang diberitahu kepada ejen itu. Claude Code membaca CLAUDE.md daripada punca projek pada permulaan setiap sesi, jadi bahagian seperti ini adalah keseluruhan integrasi tersebut:

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

Fahami dengan jelas apa yang anda peroleh daripada langkah ini. Ia merupakan integrasi pada tahap arahan, jadi ia berfungsi apabila model memutuskan untuk menjalankan arahan tersebut, dan tidak sebaliknya. Tiada apa yang memaksa panggilan itu dibuat. Jika sesuatu sesi berakhir tanpa add, tiada apa yang disimpan, dan satu-satunya isyarat ialah hasil kosong pada kali seterusnya anda membuat carian. Ini adalah pertukaran (trade-off) yang sama seperti fail memori Claude Code sendiri, dengan satu perbezaan: storan tersebut dikongsi, jadi nota itu juga sampai kepada Codex dan Cursor pada mesin yang sama.

Arah yang satu lagi tidak memerlukan sebarang persediaan. Pengimbas Memmy sudah membaca ~/.claude/projects/**/*.jsonl, iaitu tempat Claude Code menulis transkrip sesinya. Jalankan Memmy pada pelayan yang sama di mana anda menjalankan Claude Code di dalam sesi tmux dan kerja semalam akan menjadi memori tanpa anda perlu mengkonfigurasi apa-apa.

Adakah Memmy berfungsi sebagai pelayan MCP untuk Claude Code?

Tidak, dan mengetahui hala tuju ini dapat menjimatkan masa anda. MCP (model context protocol) mempunyai klien dan pelayan. Memmy ialah klien. Ia menyambung keluar ke pelayan MCP dan menawarkan alat tersebut kepada runtime ejennya sendiri. Ia tidak menerbitkan endpoint MCP yang boleh dihalakan oleh claude mcp add. Satu-satunya jambatan MCP dalam repositori tersebut adalah milik integrasi Composio di dalam API tempatan desktop, dan API tersebut mengikat port rawak pada 127.0.0.1 di sebalik header x-memmy-mcp-token miliknya sendiri.

Bahagian klien dikonfigurasikan dalam ~/.memmy/config.yaml, fail yang ditunjuk oleh MEMMY_CONFIG, di bawah tools.mcpServers:

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

type menerima stdio, sse dan streamableHttp. Pelayan stdio berjalan sebagai proses anak bagi Memmy, yang bermaksud arahannya mesti wujud pada mesin yang sama dan berjalan sebagai pengguna yang sama. Jika anda sudah mengekalkan pelayan MCP yang berjalan pada VPS, itulah pelayan yang perlu disenaraikan di sini.

Memastikan storan memori kekal peribadi

Segala milik Memmy disimpan di bawah ~/.memmy: config.yaml, ruang kerja, memory-service/memory.sqlite dan fail masa jalan (runtime). Imbasan dan penyerapan (ingestion) berlaku secara setempat, dan memori ditulis ke dalam fail SQLite setempat tersebut, jadi pendirian lalai adalah benar-benar setempat.

Dua laluan memang mencapai rangkaian. MEMMY_CLOUD_SERVICE secara lalai menuju ke https://memmy-api.memtensor.cn dan menyokong mod akaun dengan token percubaan, jadi mod kunci API tidak pernah memanggilnya. Program penambahbaikan memori ialah togol berasingan dalam tetapan privasi, yang dimatikan sehingga anda menghidupkannya.

Laluan ketiga lebih mudah terlepas pandang. Jika anda mengkonfigurasi pembekal embedding yang dihoskan, teks bagi setiap memori akan dihantar kepada pembekal tersebut supaya ia boleh ditukar menjadi vektor. Storan setempat tidak membantu dalam hal ini. Titik akhir (endpoint) embedding yang anda hoskan sendiri adalah satu-satunya cara untuk menutup laluan tersebut.

Pastikan port 18960 pada alamat loopback. Ia tidak memerlukan peraturan firewall, kerana servis yang terikat pada 127.0.0.1 tidak boleh dicapai dari luar kotak sama sekali. Capai ia dari komputer riba anda melalui SSH sebaliknya:

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

Jika anda pernah mengikatnya dengan lebih luas, tetapkan token terlebih dahulu. Menetapkan storage.token dalam konfigurasi, atau pemboleh ubah persekitaran MEMMY_MEMORY_TOKEN atau MEMORY_SERVICE_TOKEN, menyebabkan setiap titik akhir kecuali health memerlukan token bearer. Nilai konfigurasi menyokong rujukan ${ENV_NAME}, jadi token dan kunci API model anda kekal di luar fail tersebut. Itu adalah tabiat yang sama seperti menyimpan rahsia di luar ejen AI di tempat lain, dan polisi ufw deny lalai adalah benteng pertahanan anda jika versi masa hadapan menukar alamat ikat lalainya.

Sandarkan ~/.memmy sebelum anda mempercayainya

memory.sqlite ialah keseluruhan storan. Vektor disimpan dalam fail yang sama melalui sambungan sqlite-vec, jadi satu fail tersebut adalah sandarannya. Menyalin fail ini dengan cp semasa perkhidmatan sedang menulis data boleh menyebabkan pangkalan data menjadi rosak (torn database). Gunakan arahan sandaran SQLite sendiri:

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

Arahan ini menghasilkan salinan yang konsisten sementara perkhidmatan terus berjalan. Pindahkan salinan tersebut keluar dari pelayan mengikut jadual, iaitu tujuan bagi restic ke storan luar tapak. Kehilangan config.yaml hanya menyebabkan anda kehilangan tetapan pembekal yang boleh ditaip semula. Kehilangan memory.sqlite menyebabkan anda kehilangan setiap memori, dan tiada fail lain pada mesin tersebut yang menyimpan salinan kedua.

Jalankan servis memori di bawah systemd

npm run memory:serve:dev dalam shell akan mati apabila shell ditutup. Fail unit memastikan servis kekal berjalan selepas but semula.

[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

Simpan token di luar fail unit. Letakkannya dalam /etc/memmy/memory.env, dimiliki oleh root, dengan mod 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 dalam output status bermaksud systemd tidak dapat menjalankan ExecStart sama sekali, jadi periksa which npm: ia berada di /usr/bin/npm pada pemasangan NodeSource dan di bawah direktori home pengguna jika menggunakan nvm, yang tidak akan ditemui oleh systemd. Unit yang bermula dan terus keluar dengan serta-merta bermaksud kegagalan berlaku di dalam npm, dan journalctl -u memmy-memory -n 50 akan mencetak puncanya. Mekanismenya adalah sama seperti mana-mana servis systemd lain pada VPS.

Perkara yang belum dilakukan oleh Memmy

  • Tiada binaan desktop Linux. Skrip pembungkusan hanya merangkumi macOS dan Windows, jadi workbench, wizard onboarding, dan papan pemuka memori tidak tersedia pada pelayan itu sendiri.
  • memory:serve:dev menjalankan titik masuk TypeScript melalui tsx, iaitu laluan pembangunan. Repositori ini juga menghantar memory:serve untuk output yang telah dikompilasi. Jalankan npm run tanpa argumen untuk melihat skrip yang sebenarnya ada pada checkout anda.
  • Retrieval membina tetingkap carian daripada 2,000 baris vektor terkini, kemudian menggunakan pemilihan Top-K di dalam tetingkap tersebut. Pada storan yang sangat besar, memori lama mungkin berada di luar tetingkap ini.
  • Embedding berlaku selepas tangkapan, dan kegagalan akan dihantar ke baris gilir cuba semula (retry queue) dan bukannya menyekat giliran ejen. Memori yang baru ditambah sebentar tadi mungkin belum boleh ditemui melalui carian vektor.
  • Satu fail SQLite bermakna satu nod. Tiada pengelompokan (clustering), jadi pelayan kedua adalah memori kedua yang berasingan.

Versi 1.0.4 dan kira-kira 329 bintang setakat Julai 2026 menggambarkan projek yang masih baharu. Flag, laluan, dan nama skrip berubah antara keluaran. Baca medan bin dan output npm run dalam checkout anda sendiri dan jangan hanya mempercayai arahan yang disalin dari mana-mana tempat, termasuk di sini.

FAQ

Mengapakah pemeriksaan kesihatan mengembalikan ralat connection refused?

Tiada apa-apa yang mendengar pada port 18960. Kod keluar curl 7 dengan Failed to connect to 127.0.0.1 port 18960 bermaksud servis memori tidak berjalan atau ia terhenti semasa permulaan, jadi baca terminal atau jurnal tempat ia bermula. Dua punca biasa ialah modul natif better-sqlite3 yang tidak sepadan dengan versi Node anda, yang dibetulkan dengan npm rebuild better-sqlite3, dan versi Node di bawah 22. Sahkan soket dengan ss -lntp | grep 18960 sebaik sahaja servis tersebut aktif.

Dari manakah datangnya arahan memmy-memory selepas membina daripada sumber?

Daripada medan bin dalam pakej ruang kerja @memmy/memory, bukan daripada nama repositori. Jalankan node -p "JSON.stringify(require('./Memory/package.json').bin)" di dalam direktori daftar keluar (checkout) dan ia akan mencetak {"memmy-memory":"./dist/src/cli/index.js"}. Fail itu hanya wujud selepas npm run memory:build, kerana binaan tersebut mencipta dist dan menandakan fail itu sebagai boleh laksana (executable). Jalankannya sebagai node Memory/dist/src/cli/index.js health, atau buat symlink ke dalam /usr/local/bin untuk nama ringkas.

Bolehkah saya menambah Memmy ke Claude Code dengan claude mcp add?

Tidak. Memmy ialah klien MCP, bukan pelayan MCP. Ia menyambung keluar ke pelayan yang disenaraikan di bawah tools.mcpServers dalam ~/.memmy/config.yaml dan menawarkan alatan mereka kepada runtime-nya sendiri. Claude Code mencapai Memmy melalui cara sebaliknya, dengan menjalankan CLI memmy-memory sebagai arahan shell, dipandu oleh fail arahan yang ditulis oleh memmy-memory init --agent ke dalam direktori peraturan ejen.

Adakah menjalankan Memmy menghantar memori saya ke perkhidmatan awan?

Pengimbasan dan penyerapan (ingestion) dijalankan secara setempat, dan memori ditulis ke ~/.memmy/memory-service/memory.sqlite pada cakera anda sendiri. MEMMY_CLOUD_SERVICE menghala ke https://memmy-api.memtensor.cn untuk mod akaun dan token percubaan, dan program penambahbaikan memori kekal dimatikan sehingga anda mengaktifkannya. Laluan yang perlu diawasi ialah penyedia embedding: model embedding yang dihoskan menerima teks setiap memori yang ditukarkannya menjadi vektor, jadi gunakan endpoint yang anda jalankan sendiri jika perkara itu penting.