Memmy: Shared AI Agent Memory for Your VPS
Memmy gives your AI agents one local memory store. Build version 1.0.4 on Ubuntu, run the service on port 18960, and share notes safely.
Memmy na wetin e dey store
Memmy na local memory hub for AI agents wey dey run for your own VPS (virtual private server). E dey keep one SQLite database of wetin your agents don learn, and every agent for the box dey read and write to that same store. MemTensor dey maintain the project memmy-agent, e get MIT license, and version 1.0.4 na the current version as of July 2026.
Na part of am dey important for server. Memmy releases one memory service wey dey listen on http://127.0.0.1:18960, one memmy-memory command line interface (CLI) wey dey talk to that service, and one desktop workbench. Dem package the workbench for macOS and Windows only. So, for Linux VPS, you go run the service and the CLI. That one dey enough to give Claude Code, Codex and Cursor one shared memory.
Memmy dey arrange wetin e store into four layers. L1 Trace na the raw turn: the request, the response and the tool calls. L2 Policy na procedure wey Memmy derive from traces wey don prove useful. L3 World Model na stable knowledge about project or environment. Skill na callable procedure wey dem form from policy. The service dey assign layer when e ingest one turn, so you no need create dem by hand.
Wetin a shared memory hub dey change compared to memory for each tool
Every agent today dey release with im own memory. Claude Code dey keep instruction files for the repository. Cursor dey keep rules for im workspace database. Codex dey keep session logs under ~/.codex. Each store belong to one tool, so fact wey you teach on Monday for one tool no dey known on Tuesday for another one. You dey pay for that two times: once for tokens wey you spend to explain the same project again, and once for wrong work when agent act based on assumption wey you don correct somewhere else.
A hub dey move the store comot from the tool. Memmy still dey read the stores wey already dey exist, so you no go start from empty database. Im scanner sabi six sources: Claude Code for ~/.claude/projects/**/*.jsonl, Codex at ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl, OpenCode at ~/.local/share/opencode/opencode.db, Cursor's state.vscdb files, OpenClaw's SQLite databases under ~/.openclaw, and Hermes under ~/.hermes. You fit add source by hand with name and local path.
The import counters no go match, and na expected behavior be that. The scanner dey group messages by source and conversation, then e dey write one L1 memory for each complete turn. A turn count as complete when e get non-empty user content and e end with non-empty assistant message, so interrupted session no dey contribute anything. Messages dey deduplicate with conversation checkpoints and stable turn IDs. The scanned count, imported message count and new memory count all dey different for the same run.
Na this part dey work together with how Claude Code dey manage context inside one session. Context management dey decide wetin fit inside one window. A memory hub dey decide wetin survive after that window close.
Wetin you need for the VPS
- Node.js 22 or newer. Memmy docs require am, and Ubuntu 24.04 ships Node 18.
gitand build toolchain, becausebetter-sqlite3na native module wey fit compile during install.- About 2 GB RAM. The root install dey pull large workspace and frontend build chain.
- Few GB free disk space for
node_modulesand the database.
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 suppose print v22 or higher. v18 for here mean say the NodeSource step no work, and the install go later fail for the project's engine check.
Install Memmy from source on Ubuntu 24.04
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 dey compile the @memmy/memory workspace enter Memory/dist. Nothing else for this tree need build for headless server. Check say the native module don load:
node -e "require('better-sqlite3'); console.log('better-sqlite3 loads')"If that line throw error instead of printing, the native module no match your Node version. Run npm rebuild better-sqlite3, wey na exactly wetin the project own start script dey do before e launch anything.
The README document bash scripts/dev-start.sh as one-command start. No run am for headless VPS. E start the Electron desktop shell and Vite dev server for port 19000 alongside the memory service. Electron need display, so for server wey no get graphical session, the script go stall or exit.
Start the memory service and check say e dey answer
npm run memory:serve:devNa the documented way be this to run the memory service from source. E bind to 127.0.0.1:18960, e keep the database for ~/.memmy/memory-service/memory.sqlite, and e read config from ~/.memmy/config.yaml. The README write the same values clearly when you want make dem explicit:
npm run memory:serve:dev -- \
--host 127.0.0.1 --port 18960 \
--db ~/.memmy/memory-service/memory.sqlite \
--config ~/.memmy/config.yamlFrom another shell, ask the service whether e dey alive:
curl -sS http://127.0.0.1:18960/api/v1/healthHealth na the only endpoint wey never ask for token, na why e be the correct probe. If curl comot with code 7 and a Failed to connect to 127.0.0.1 port 18960 message, nothing dey listen. Read the terminal wey dey run the service, because startup crash go print there, and the usual cause na native SQLite module wey fail to load. ss -lntp | grep 18960 confirms the socket once the service don start.
The rest of the HTTP API (application programming interface) dey under /api/v1.
POST /api/v1/memory/adddey write memory andPOST /api/v1/memory/searchdey query.GET /api/v1/memory/:idandDELETE /api/v1/memory/:iddey read and remove one entry.POST /api/v1/sessions/openandPOST /api/v1/sessions/:sessionId/closedey mark the beginning and end of an agent session.POST /api/v1/turns/startandPOST /api/v1/turns/:turnId/completedey record one turn.GET /api/v1/panel/overview,/api/v1/panel/analysisand/api/v1/panel/itemsdey send data to the dashboard.
Memmy reserve one block of ports, and for headless mode you go use only the first one: 18960 for memory, 18970 for gateway health, 18980 for the web UI and admin HTTP, 18990 for the OpenAI-compatible API wey memmy serve start, then 19000 and 19010 for the desktop frontend dev server. If something for your box already dey use any of dem, na that list you suppose check.
Where the memmy-memory command actually comes from
Na here first install dey usually go wrong, so read am from the package instead of guessing. The command name no get anything to do with the repository name. E come from the bin field of the workspace wey define am:
node -p "JSON.stringify(require('./Memory/package.json').bin)"That one print {"memmy-memory":"./dist/src/cli/index.js"}. So the built entry point na Memory/dist/src/cli/index.js, and e dey exist only after npm run memory:build, because na the build dey create dist and mark the file executable. Run am directly:
node Memory/dist/src/cli/index.js healthIf you want the short name for your PATH, link that same file:
sudo ln -s "$PWD/Memory/dist/src/cli/index.js" /usr/local/bin/memmy-memory
memmy-memory healthThe CLI dey default to http://127.0.0.1:18960 and e accept --url, --token, --config, --source and --user-id. The subcommands na init, health, search, add, get and delete, plus session and turn calls wey agents dey use instead of people. memmy-memory search "deploy steps" and memmy-memory add "staging migrates on deploy" na the two wey agent dey run pass.
Claude Code go connect to Memmy how?
Claude Code no get memory plugin interface, so Memmy no hook into am. The integration simple pass that. Claude Code dey run memmy-memory as ordinary shell command, and instruction file dey tell am when to run am. Memmy documented installer dey write that file for you: memmy-memory init --agent dey put memory instruction file inside the target agent rules directory.
Write the instruction by hand one time, so you go know exactly wetin you tell the agent. Claude Code dey read CLAUDE.md from the project root when every session start, so section like this na the whole integration:
## 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.Make sure say you understand wetin this one dey give you. Na instruction-level integration, so e go work when the model decide to run the command, and e no go work otherwise. Nothing dey force the call. If session end without add, nothing save, and the only signal na empty result the next time you search. Na the same trade-off as Claude Code own memory files, but one difference dey: the store dey shared, so the note still reach Codex and Cursor for the same machine.
The other direction no need any setup. Memmy scanner already dey read ~/.claude/projects/**/*.jsonl, na there Claude Code dey write its session transcripts. Run Memmy for the same server wey you dey run Claude Code inside tmux session, and yesterday work go become memory without you configuring anything.
Memmy dey work as MCP server for Claude Code?
No. If you know how e dey work, you go save one afternoon. MCP (model context protocol) get clients and servers. Memmy na client. E dey connect to MCP servers and make their tools available to im own agent runtime. E no publish any MCP endpoint wey claude mcp add fit connect to. The only MCP bridge for the repository dey with the Composio integration inside the desktop local API. That API bind one random port on 127.0.0.1 behind im own x-memmy-mcp-token header.
You configure the client side for ~/.memmy/config.yaml, the file wey MEMMY_CONFIG point to, under tools.mcpServers:
tools:
mcpServers:
example:
type: stdio
command: npx
args:
- "-y"
- "your-mcp-server"
toolTimeout: 30
enabledTools:
- "*"type dey accept stdio, sse and streamableHttp. A stdio server dey run as Memmy child process. This mean say im command must dey for the same box and run as the same user. If you already dey keep MCP servers wey dey run for VPS, na those ones you suppose list here.
How to keep the memory store private
Everything wey Memmy own dey under ~/.memmy: config.yaml, the workspace, memory-service/memory.sqlite and runtime files. Scanning and ingestion dey happen locally, and memories dey write to that local SQLite file, so the default setup really dey local.
Two paths dey reach the network. MEMMY_CLOUD_SERVICE dey default to https://memmy-api.memtensor.cn and e dey support account mode with its trial tokens, so API key mode no dey call am. The memory improvement program na separate toggle for privacy settings, and e dey off until you switch am on.
Third path dey easy to miss. If you configure a hosted embedding provider, the text of every memory dey send to that provider so e fit turn am into a vector. Local storage no fit prevent this. An embedding endpoint wey you host yourself na the only way to close am.
Keep port 18960 for the loopback address. E no need firewall rule, because service wey bind to 127.0.0.1 no dey reachable from outside the machine at all. Reach am from your laptop through SSH instead:
ssh -N -L 18960:127.0.0.1:18960 you@your-vpsIf you ever bind am wider, set a token first. Setting storage.token for the config, or the MEMMY_MEMORY_TOKEN or MEMORY_SERVICE_TOKEN environment variable, makes every endpoint except health require a bearer token. Config values support ${ENV_NAME} references, so the token and your model API keys no go dey inside the file itself. Na the same habit as keeping secrets out of AI agents everywhere else, and a default deny ufw policy na your backstop if a future version changes its default bind address.
Before you trust am, back up ~/.memmy
memory.sqlite na the whole store. The vectors dey inside that same file through the sqlite-vec extension, so one file na the backup. If you copy am with cp while the service dey write, the database fit tear. Use SQLite own backup command:
mkdir -p ~/memmy-backup
sqlite3 ~/.memmy/memory-service/memory.sqlite ".backup '$HOME/memmy-backup/memory.sqlite'"This one go create a consistent copy while the service still dey run. Push the copy comot from the box on a schedule. Na wetin restic to off-site storage dey do be that. If you lose config.yaml, na provider settings you fit type again. If you lose memory.sqlite, you lose every memory, and no other thing for the machine get another copy.
Run memory service under systemd
npm run memory:serve:dev wey you run for shell go die together with the shell. Unit file dey keep the service running across reboots.
[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.targetNo put the token inside the unit. Put am for /etc/memmy/memory.env, make root own am, and set mode 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/healthstatus=203/EXEC for the status output mean say systemd no fit run ExecStart at all. So check which npm: for NodeSource install, e dey /usr/bin/npm, but for nvm e dey somewhere under the user home directory. systemd no go find am. If the unit start and exit immediately, the problem happen inside npm instead. journalctl -u memmy-memory -n 50 go print the reason. The process na the same as any other systemd service for VPS.
Wetin Memmy never dey do yet
- No Linux desktop build dey. The packaging scripts cover macOS and Windows, so the workbench, onboarding wizard and memory dashboard no dey available for the server itself.
memory:serve:devdey run the TypeScript entry point throughtsx, wey be development path. The repository still getmemory:servefor compiled output. Runnpm runwithout arguments to see which scripts your checkout really get.- Retrieval dey build its search window from the latest 2,000 vector rows, then e dey apply Top-K selection inside that window. For a very large store, old memory fit dey outside the window.
- Embedding dey happen after capture, and if e fail, e dey enter retry queue instead of blocking the agent's turn. Memory wey you add just now fit never dey findable through vector search.
- One SQLite file mean one node. No clustering dey, so second server na separate memory.
Version 1.0.4 and roughly 329 stars as of July 2026 show say na young project. Flags, paths and script names fit change between releases. Read the bin field and the output of npm run for your own checkout instead of trusting command wey you copy from anywhere, including here.
FAQ
Why health check dey return connection refused?
Nothing dey listen for port 18960. A curl exit code 7 with Failed to connect to 127.0.0.1 port 18960 mean say memory service no dey run or e die when e start, so read the terminal or the journal where e start. The two common causes na better-sqlite3 native module wey no match your Node version, and Node version wey dey below 22. Fix the module with npm rebuild better-sqlite3. Confirm the socket with ss -lntp | grep 18960 after the service don start.
Where memmy-memory command dey come from after building from source?
E dey come from bin field of @memmy/memory workspace package, no be from the repository name. Run node -p "JSON.stringify(require('./Memory/package.json').bin)" inside the checkout and e go print {"memmy-memory":"./dist/src/cli/index.js"}. That file no dey exist until after npm run memory:build, because the build dey create dist and mark the file executable. Run am as node Memory/dist/src/cli/index.js health, or create symlink for am inside /usr/local/bin so you fit use the short name.
I fit add Memmy to Claude Code with claude mcp add?
No. Memmy na MCP client, e no be MCP server. E dey connect out to servers wey dey listed under tools.mcpServers for ~/.memmy/config.yaml, and e dey offer their tools to im own runtime. Claude Code reaches Memmy the other way, by running memmy-memory CLI as shell command, with instruction file wey memmy-memory init --agent dey write inside the agent's rules directory.
Memmy dey send my memories to cloud service when e dey run?
Scanning and ingestion dey run locally, and memories dey write to ~/.memmy/memory-service/memory.sqlite for your own disk. MEMMY_CLOUD_SERVICE dey point to https://memmy-api.memtensor.cn for account mode and trial tokens, and memory improvement program remain off until you enable am. The path wey you need monitor na the embedding provider: hosted embedding model dey receive the text of every memory wey e turn to vector. So use endpoint wey you dey run yourself if that matter.