SSD Nodes Learn 🎉 VPS dès $4.99/mois
Guides Matt ConnorPar Matt Connor · Mis à jour le 2026-08-07

Installer Memmy sur un VPS Ubuntu pour vos agents IA

Memmy partage une mémoire SQLite locale entre vos agents IA. Compilez-le sur Ubuntu, lancez le service sur le port 18960 et évitez tout stockage distant.

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

Ce qu’est Memmy et ce qu’il stocke

Memmy est un hub de mémoire local pour les agents d’IA qui s’exécute sur votre propre VPS (serveur privé virtuel). Il conserve une base de données SQLite contenant ce que vos agents ont appris. Tous les agents présents sur le serveur lisent et écrivent dans ce même stockage. Le projet est memmy-agent de MemTensor, sous licence MIT, en version 1.0.4 en juillet 2026.

Seule une partie de Memmy est utile sur un serveur. Memmy fournit un service de mémoire qui écoute sur http://127.0.0.1:18960, une interface de ligne de commande (CLI) memmy-memory qui communique avec ce service, ainsi qu’un environnement de travail de bureau. Cet environnement est fourni uniquement pour macOS et Windows. Sur un VPS Linux, vous exécutez donc le service et la CLI. Cela suffit pour fournir une mémoire partagée à Claude Code, Codex et Cursor.

Memmy répartit ce qu’il stocke en quatre couches. L1 Trace contient le tour brut : la requête, la réponse et les appels d’outils. L2 Policy est une procédure déduite de traces qui se sont révélées utiles. L3 World Model contient les connaissances stables sur un projet ou un environnement. Skill est une procédure appelable, cristallisée à partir d’une policy. Le service attribue une couche lors de l’ingestion d’un tour. Vous n’avez donc pas à les créer manuellement.

Ce que change un hub de mémoire partagée par rapport à une mémoire propre à chaque outil

Aujourd’hui, chaque agent intègre sa propre mémoire. Claude Code conserve ses fichiers d’instructions dans le dépôt. Cursor conserve ses règles dans la base de données de son espace de travail. Codex conserve les journaux de session sous ~/.codex. Chaque stockage appartient à un seul outil. Un fait que vous avez enseigné lundi dans un outil reste donc inconnu mardi dans un autre. Vous le payez deux fois : d’abord en tokens pour réexpliquer le même projet, puis à cause des erreurs lorsqu’un agent applique une hypothèse que vous avez déjà corrigée ailleurs.

Un hub sort le stockage de l’outil. Memmy lit également les stockages existants. Vous ne partez donc pas d’une base de données vide. Son scanner connaît six sources : Claude Code à ~/.claude/projects/**/*.jsonl, Codex à ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl, OpenCode à ~/.local/share/opencode/opencode.db, les fichiers state.vscdb de Cursor, les bases de données SQLite d’OpenClaw sous ~/.openclaw et Hermes sous ~/.hermes. Vous pouvez ajouter manuellement une source en indiquant un nom et un chemin local.

Les compteurs d’importation ne correspondront pas, et c’est normal. Le scanner regroupe les messages par source et par conversation, puis écrit une mémoire L1 par tour complet. Un tour est complet lorsqu’il contient un contenu utilisateur non vide et se termine par un message assistant non vide. Une session interrompue ne contribue donc aucune mémoire. Les messages sont dédupliqués à l’aide de checkpoints de conversation et d’identifiants de tour stables. Le nombre d’éléments analysés, le nombre de messages importés et le nombre de nouvelles mémoires diffèrent lors d’une même exécution.

C’est la partie qui complète la gestion du contexte par Claude Code au cours d’une session. La gestion du contexte détermine ce qui tient dans une seule fenêtre. Un hub de mémoire détermine ce qui est conservé après la fermeture de cette fenêtre.

Ce qu’il vous faut sur le VPS

  • Node.js 22 ou version ultérieure. La documentation de Memmy l’exige, et Ubuntu 24.04 fournit Node 18.
  • git et une toolchain de compilation, car better-sqlite3 est un module natif qui peut être compilé pendant l’installation.
  • Environ 2 GB de RAM. L’installation à la racine récupère un workspace volumineux et une toolchain frontend.
  • Quelques GB d’espace disque libre pour node_modules et la base de données.
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 doit afficher v22 ou une version ultérieure. Un résultat v18 indique que l’étape NodeSource n’a pas abouti. L’installation échouera ensuite lors de la vérification du moteur du projet.

Installer Memmy depuis les sources sur 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 compile l’espace de travail @memmy/memory dans Memory/dist. Rien d’autre dans l’arborescence ne doit être compilé sur un serveur headless. Vérifiez que le module natif est bien chargé :

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

Si cette ligne génère une erreur au lieu d’afficher le résultat, le module natif n’est pas compatible avec votre version de Node. Exécutez npm rebuild better-sqlite3. C’est exactement ce que fait le script de démarrage du projet avant de lancer quoi que ce soit.

Le README présente bash scripts/dev-start.sh comme une commande de démarrage unique. Ne l’exécutez pas sur un VPS headless. Cette commande démarre l’interface de bureau Electron et un serveur de développement Vite sur le port 19000, en plus du service de mémoire. Electron a besoin d’un affichage. Sur un serveur sans session graphique, le script se bloque ou se termine.

Démarrez le service de mémoire et vérifiez qu’il répond

npm run memory:serve:dev

C’est la méthode documentée pour exécuter le service de mémoire depuis les sources. Il se lie à 127.0.0.1:18960, conserve la base de données dans ~/.memmy/memory-service/memory.sqlite et lit la configuration depuis ~/.memmy/config.yaml. Le README indique les mêmes valeurs lorsque vous voulez les spécifier explicitement :

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

Depuis un second shell, demandez au service s’il est actif :

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

L’endpoint de health check est le seul qui ne demande jamais de token. C’est pourquoi il constitue la bonne sonde. Si curl se termine avec le code 7 et un message Failed to connect to 127.0.0.1 port 18960, aucun processus n’écoute. Consultez le terminal qui exécute le service, car un crash au démarrage s’y affiche. La cause habituelle est l’échec du chargement du module SQLite natif. ss -lntp | grep 18960 confirme que le socket est disponible une fois le service démarré.

Le reste de l’API HTTP (application programming interface) se trouve sous /api/v1.

  • POST /api/v1/memory/add écrit une mémoire et POST /api/v1/memory/search exécute des requêtes.
  • GET /api/v1/memory/:id et DELETE /api/v1/memory/:id lisent et suppriment une entrée.
  • POST /api/v1/sessions/open et POST /api/v1/sessions/:sessionId/close délimitent une session d’agent.
  • POST /api/v1/turns/start et POST /api/v1/turns/:turnId/complete enregistrent un tour.
  • GET /api/v1/panel/overview, /api/v1/panel/analysis et /api/v1/panel/items alimentent le dashboard.

Memmy réserve un bloc de ports. En mode headless, vous utilisez uniquement le premier : 18960 pour la mémoire, 18970 pour le health check de la gateway, 18980 pour l’interface web et l’HTTP d’administration, 18990 pour l’API compatible OpenAI démarrée par memmy serve, puis 19000 et 19010 pour le dev server du frontend desktop. Si l’un de ces ports est déjà utilisé sur votre machine, consultez cette liste.

D’où vient réellement la commande memmy-memory

C’est généralement à cette étape que la première installation échoue. Lisez donc la définition dans le paquet au lieu de la déduire. Le nom de la commande n’a aucun rapport avec le nom du dépôt. Il provient du champ bin de l’espace de travail qui la définit :

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

Cette commande affiche {"memmy-memory":"./dist/src/cli/index.js"}. Le point d’entrée compilé est donc Memory/dist/src/cli/index.js. Il n’existe qu’après npm run memory:build, car c’est la compilation qui crée dist et rend le fichier exécutable. Exécutez-le directement :

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

Si vous voulez utiliser le nom court depuis votre PATH, créez un lien vers ce même fichier :

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

Par défaut, la CLI utilise http://127.0.0.1:18960 et accepte --url, --token, --config, --source et --user-id. Ses sous-commandes sont init, health, search, add, get et delete, ainsi que des appels de session et de tour utilisés par les agents plutôt que par les utilisateurs. memmy-memory search "deploy steps" et memmy-memory add "staging migrates on deploy" sont les deux commandes qu’un agent exécute le plus souvent.

Comment connecter Claude Code à Memmy ?

Claude Code ne dispose pas d’interface pour les plugins de mémoire. Memmy ne s’y connecte donc pas directement. L’intégration est plus simple. Claude Code exécute memmy-memory comme une commande shell ordinaire, et un fichier d’instructions lui indique quand l’exécuter. L’installateur documenté de Memmy crée ce fichier pour vous : memmy-memory init --agent dépose un fichier d’instructions de mémoire dans le répertoire de règles de l’agent cible.

Écrivez vous-même l’instruction une fois. Vous saurez ainsi exactement ce qui a été demandé à l’agent. Claude Code lit CLAUDE.md à la racine du projet au début de chaque session. Une section comme celle-ci suffit donc pour l’intégration :

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

Soyez clair sur ce que cette intégration permet. Il s’agit d’une intégration au niveau des instructions. Elle fonctionne lorsque le modèle décide d’exécuter la commande, et pas dans les autres cas. Rien ne force l’appel. Si une session se termine sans add, rien n’est enregistré. Le seul signal est un résultat vide lors de la recherche suivante. C’est le même compromis que pour les propres fichiers de mémoire de Claude Code, avec une différence : le store est partagé. La note est donc également accessible à Codex et Cursor sur la même machine.

L’autre sens ne nécessite aucune configuration. Le scanner de Memmy lit déjà ~/.claude/projects/**/*.jsonl, l’emplacement où Claude Code écrit les transcriptions de session. Exécutez Memmy sur le même serveur que celui où vous utilisez Claude Code dans une session tmux. Le travail d’hier devient alors de la mémoire, sans configuration supplémentaire.

Memmy fonctionne-t-il comme serveur MCP pour Claude Code ?

Non. Connaître ce point vous évite d’y consacrer une après-midi. MCP (model context protocol) utilise des clients et des serveurs. Memmy est un client. Il se connecte aux serveurs MCP et fournit leurs outils à son propre agent runtime. Il ne publie pas de endpoint MCP vers lequel claude mcp add pourrait se connecter. Le seul bridge MCP du dépôt appartient à l’intégration Composio de l’API locale desktop. Cette API écoute sur un port aléatoire de 127.0.0.1, protégé par son propre en-tête x-memmy-mcp-token.

Le client se configure dans ~/.memmy/config.yaml, dans le fichier indiqué par MEMMY_CONFIG, sous tools.mcpServers :

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

type accepte stdio, sse et streamableHttp. Un serveur stdio s’exécute comme processus enfant de Memmy. Sa commande doit donc exister sur la même machine et s’exécuter avec le même utilisateur. Si vous maintenez déjà des serveurs MCP sur un VPS, ce sont ceux que vous devez répertorier ici.

Garder le magasin de mémoire privé

Tout ce que Memmy possède se trouve sous ~/.memmy : config.yaml, l’espace de travail, memory-service/memory.sqlite et les fichiers d’exécution. L’analyse et l’ingestion se déroulent localement, et les mémoires sont écrites dans ce fichier SQLite local. Le fonctionnement par défaut est donc réellement local.

Deux chemins accèdent au réseau. MEMMY_CLOUD_SERVICE pointe par défaut vers https://memmy-api.memtensor.cn et gère le mode compte avec ses tokens d’essai. Le mode avec clé API ne l’appelle donc jamais. Le programme d’amélioration de la mémoire est un réglage distinct des paramètres de confidentialité. Il est désactivé tant que vous ne l’activez pas.

Un troisième chemin est plus facile à manquer. Si vous configurez un fournisseur d’embeddings hébergé, le texte de chaque mémoire est envoyé à ce fournisseur pour être converti en vecteur. Le stockage local ne protège pas ce contenu. Le seul moyen de supprimer cet accès est d’héberger vous-même un endpoint d’embeddings.

Laissez le port 18960 lié à l’adresse loopback. Aucune règle de pare-feu n’est nécessaire, car un service lié à 127.0.0.1 n’est pas accessible depuis l’extérieur de la machine. Accédez-y depuis votre ordinateur portable avec SSH :

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

Si vous le liez un jour à une adresse plus large, définissez d’abord un token. Définir storage.token dans la configuration, ou la variable d’environnement MEMMY_MEMORY_TOKEN ou MEMORY_SERVICE_TOKEN, impose un bearer token à tous les endpoints, sauf health. Les valeurs de configuration prennent en charge les références ${ENV_NAME}. Le token et vos clés API de modèles restent ainsi en dehors du fichier lui-même. C’est la même règle que pour garder les secrets hors des agents IA ailleurs, et une politique ufw default deny constitue votre protection de secours si une version ultérieure modifie son adresse bind par défaut.

Sauvegardez ~/.memmy avant de lui faire confiance

memory.sqlite est l’intégralité du store. Les vecteurs se trouvent dans ce même fichier grâce à l’extension sqlite-vec : un seul fichier suffit donc pour la sauvegarde. Le copier avec cp pendant que le service écrit peut produire une base de données incohérente. Utilisez la commande de sauvegarde native de SQLite :

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

Cette commande produit une copie cohérente pendant que le service continue de fonctionner. Planifiez son transfert vers une autre machine, ce que permet restic vers un stockage hors site. La perte de config.yaml vous oblige à ressaisir les paramètres du fournisseur. La perte de memory.sqlite vous fait perdre tous les souvenirs, car aucune autre copie ne se trouve sur la machine.

Exécuter le service mémoire avec systemd

npm run memory:serve:dev lancé dans un shell s’arrête avec le shell. Un fichier d’unité maintient le service actif après les redémarrages.

[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

Ne placez pas le token dans l’unité. Mettez-le dans /etc/memmy/memory.env, avec root comme propriétaire et le 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

La présence de status=203/EXEC dans la sortie d’état signifie que systemd n’a pas pu exécuter ExecStart du tout. Vérifiez donc which npm : il se trouve dans /usr/bin/npm avec une installation NodeSource et sous le répertoire personnel de l’utilisateur avec nvm, emplacement que systemd ne trouvera pas. Une unité qui démarre puis s’arrête immédiatement a échoué dans npm. journalctl -u memmy-memory -n 50 affiche la cause. Le fonctionnement est le même que pour n’importe quel autre service systemd sur un VPS.

Ce que Memmy ne fait pas encore

  • Il n’existe pas de build Linux pour le bureau. Les scripts de packaging couvrent macOS et Windows. Le workbench, son assistant d’onboarding et le tableau de bord de la mémoire ne sont donc pas disponibles directement sur le serveur.
  • memory:serve:dev exécute le point d’entrée TypeScript via tsx, qui correspond à un chemin de développement. Le dépôt fournit également memory:serve pour la sortie compilée. Exécutez npm run sans argument pour voir quels scripts sont réellement disponibles dans votre checkout.
  • La récupération construit sa fenêtre de recherche à partir des 2,000 dernières lignes vectorielles, puis applique la sélection Top-K dans cette fenêtre. Dans un store très volumineux, une mémoire ancienne peut se trouver en dehors de cette fenêtre.
  • L’embedding intervient après la capture. En cas d’échec, l’opération est placée dans une file de retry au lieu de bloquer le tour de l’agent. Une mémoire ajoutée il y a quelques instants peut donc ne pas être disponible immédiatement via la recherche vectorielle.
  • Un seul fichier SQLite correspond à un seul nœud. Il n’y a pas de clustering. Un second serveur constitue donc une mémoire distincte.

La version 1.0.4 et environ 329 stars en juillet 2026 décrivent un projet encore jeune. Les flags, les chemins et les noms de scripts peuvent changer d’une release à l’autre. Consultez le champ bin et la sortie de npm run dans votre propre checkout, plutôt que de faire confiance à une commande copiée n’importe où, y compris ici.

FAQ

Pourquoi le health check renvoie-t-il « connection refused » ?

Rien n’écoute sur le port 18960. Un code de sortie curl égal à 7 avec Failed to connect to 127.0.0.1 port 18960 signifie que le service de mémoire ne fonctionne pas ou qu’il s’est arrêté au démarrage. Consultez donc le terminal ou le journal où il a été lancé. Les deux causes habituelles sont un module natif better-sqlite3 qui ne correspond pas à votre version de Node, ce qui se corrige avec npm rebuild better-sqlite3, et une version de Node antérieure à 22. Confirmez le socket avec ss -lntp | grep 18960 une fois le service démarré.

D’où vient la commande memmy-memory après une compilation depuis les sources ?

Elle vient du champ bin du package de workspace @memmy/memory, et non du nom du dépôt. Exécutez node -p "JSON.stringify(require('./Memory/package.json').bin)" dans la copie de travail. La commande affiche {"memmy-memory":"./dist/src/cli/index.js"}. Ce fichier n’existe qu’après npm run memory:build, car la compilation crée dist et rend le fichier exécutable. Exécutez-le avec node Memory/dist/src/cli/index.js health, ou créez un lien symbolique vers /usr/local/bin pour utiliser le nom court.

Puis-je ajouter Memmy à Claude Code avec claude mcp add ?

Non. Memmy est un client MCP, pas un serveur MCP. Il se connecte aux serveurs indiqués sous tools.mcpServers dans ~/.memmy/config.yaml et met leurs outils à la disposition de son propre runtime. Claude Code accède à Memmy dans l’autre sens, en exécutant la CLI memmy-memory comme une commande shell, avec l’aide d’un fichier d’instructions que memmy-memory init --agent écrit dans le répertoire de règles de l’agent.

L’exécution de Memmy envoie-t-elle mes souvenirs à un service cloud ?

L’analyse et l’ingestion s’effectuent localement, et les souvenirs sont écrits dans ~/.memmy/memory-service/memory.sqlite sur votre propre disque. MEMMY_CLOUD_SERVICE pointe vers https://memmy-api.memtensor.cn pour le mode compte et les tokens d’essai, et le programme d’amélioration de la mémoire reste désactivé tant que vous ne l’activez pas. Le point à surveiller est le fournisseur d’embeddings : un modèle d’embeddings hébergé reçoit le texte de chaque souvenir qu’il transforme en vecteur. Utilisez donc un endpoint que vous hébergez vous-même si cette contrainte est importante.