Memmy : une mémoire locale partagée pour vos agents IA
Découvrez Memmy, son stockage SQLite local et son service sur le port 18960. Compilez la version 1.0.4 sur Ubuntu et partagez la mémoire entre vos agents.
Ce qu’est Memmy et ce qu’il stocke
Memmy est un hub de mémoire local pour les agents IA. Il s’exécute sur votre propre VPS (virtual private server). 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 du projet 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 pour ordinateur 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 les données stockées 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, concrétisée à partir d’une policy. Le service attribue une couche lors de l’ingestion d’un tour. Vous ne les créez donc pas manuellement.
Ce que change un hub de mémoire partagé par rapport à la mémoire propre à chaque outil
Chaque agent actuel fournit 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. Ainsi, un fait que vous avez enseigné lundi dans un outil est inconnu mardi dans un autre. Vous le payez deux fois : d’abord en tokens dépensés pour réexpliquer le même projet, puis dans le travail incorrect effectué lorsqu’un agent s’appuie sur une hypothèse que vous avez déjà corrigée ailleurs.
Un hub déplace le stockage en dehors 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 à l’emplacement ~/.claude/projects/**/*.jsonl, Codex à l’emplacement ~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-*.jsonl, OpenCode à l’emplacement ~/.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 avec 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 considéré comme complet s’il contient un contenu utilisateur non vide et se termine par un message assistant non vide. Une session interrompue ne contribue donc pas. Les messages sont dédoublonnés à l’aide de points de contrôle 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 au cours d’une même exécution.
C’est l’élément qui complète la façon dont Claude Code gère le contexte 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 dont vous avez besoin sur le VPS
- Node.js 22 ou version ultérieure. La documentation de Memmy l’exige, et Ubuntu 24.04 fournit Node 18.
gitet une toolchain de compilation, carbetter-sqlite3est 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 de build frontend.
- Quelques GB d’espace disque libre pour
node_moduleset 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 --versionnode --version doit afficher v22 ou une version ultérieure. Un v18 à ce stade indique que l’étape NodeSource n’a pas abouti. L’installation échouera ensuite lors de la vérification du moteur du projet.
Installer Memmy à partir des 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:buildnpm run memory:build compile l’espace de travail @memmy/memory dans Memory/dist. Rien d’autre dans l’arborescence ne doit être compilé pour 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 un résultat, le module natif ne correspond pas à 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 documente 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 le shell 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émarrer le service de mémoire et vérifier qu’il répond
npm run memory:serve:devC’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 définir explicitement :
npm run memory:serve:dev -- \
--host 127.0.0.1 --port 18960 \
--db ~/.memmy/memory-service/memory.sqlite \
--config ~/.memmy/config.yamlDepuis un deuxième shell, demandez au service s’il est actif :
curl -sS http://127.0.0.1:18960/api/v1/healthL’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 y est affiché. La cause habituelle est l’échec du chargement du module SQLite natif. ss -lntp | grep 18960 confirme le socket une fois le service démarré.
Le reste de l’API HTTP (interface de programmation d’application) se trouve sous /api/v1.
POST /api/v1/memory/addécrit une mémoire etPOST /api/v1/memory/searcheffectue des requêtes.GET /api/v1/memory/:idetDELETE /api/v1/memory/:idlisent et suppriment une entrée.POST /api/v1/sessions/openetPOST /api/v1/sessions/:sessionId/closeencadrent une session d’agent.POST /api/v1/turns/startetPOST /api/v1/turns/:turnId/completeenregistrent un tour.GET /api/v1/panel/overview,/api/v1/panel/analysiset/api/v1/panel/itemsalimentent 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’admin HTTP, 18990 pour l’API compatible OpenAI démarrée par memmy serve, puis 19000 et 19010 pour le serveur de développement 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 ici qu’une première installation échoue. Lisez donc la définition dans le package au lieu de la deviner. Le nom de la commande n’a aucun rapport avec le nom du dépôt. Il vient 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 existe uniquement après npm run memory:build, car le build crée dist et rend le fichier exécutable. Exécutez-le directement :
node Memory/dist/src/cli/index.js healthSi 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 healthPar 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 de plug-in de mémoire. Memmy ne s’y branche donc pas. 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.
Rédigez une fois l’instruction à la main. Vous saurez ainsi exactement ce qui a été demandé à l’agent. Claude Code lit CLAUDE.md depuis 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 cela vous apporte. 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 le cas contraire. Rien ne force l’appel. Si une session se termine sans add, rien n’est enregistré. Le seul indice 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 stockage 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, qui contient les transcriptions des sessions écrites par Claude Code. 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 disponible dans la mémoire sans aucune configuration supplémentaire.
Memmy fonctionne-t-il comme serveur MCP pour Claude Code ?
Non. Il est utile de connaître ce sens pour éviter d’y passer l’après-midi. MCP (model context protocol) utilise des clients et des serveurs. Memmy est un client. Il se connecte aux serveurs MCP et expose leurs outils à son propre agent runtime. Il ne publie pas d’endpoint MCP vers lequel claude mcp add pourrait se connecter. Le seul pont MCP du dépôt appartient à l’intégration Composio dans l’API locale desktop. Cette API écoute sur un port aléatoire de 127.0.0.1 et utilise son propre en-tête x-memmy-mcp-token.
Le côté client est configuré dans ~/.memmy/config.yaml, 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 avez déjà des serveurs MCP exécutés sur un VPS, ce sont ceux que vous devez répertorier ici.
Garder le magasin de mémoire privé
Tout ce que Memmy gère 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 s’effectuent 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 prend en charge le mode compte avec ses tokens d’essai. Le mode clé d’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 afin d’être converti en vecteur. Le stockage local ne change rien à cela. Un endpoint d’embeddings que vous hébergez vous-même est le seul moyen de supprimer ce transfert.
Conservez le port 18960 sur l’adresse loopback. Aucune règle de firewall n’est nécessaire, car un service lié à 127.0.0.1 n’est pas du tout accessible depuis l’extérieur de la machine. Accédez-y depuis votre laptop via SSH :
ssh -N -L 18960:127.0.0.1:18960 you@your-vpsSi vous le liez un jour à une adresse plus large, définissez d’abord un token. La définition de storage.token dans la configuration, ou de la variable d’environnement MEMMY_MEMORY_TOKEN ou MEMORY_SERVICE_TOKEN, impose un bearer token à tous les endpoints, sauf celui de health. Les valeurs de configuration prennent en charge les références ${ENV_NAME}. Le token et vos clés d’API de modèles restent donc hors du fichier lui-même. C’est la même pratique que ne pas exposer les secrets aux agents IA ailleurs, et une policy ufw en deny par défaut 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 via 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 intégrée à SQLite :
mkdir -p ~/memmy-backup
sqlite3 ~/.memmy/memory-service/memory.sqlite ".backup '$HOME/memmy-backup/memory.sqlite'"Cette commande crée une copie cohérente pendant que le service continue de fonctionner. Planifiez son transfert hors du serveur, par exemple avec 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 toutes les mémoires, et aucune autre copie n'est conservée sur la machine.
Exécuter le service de mémoire avec systemd
npm run memory:serve:dev lancé dans un shell s'arrête avec le shell. Un unit file 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.targetNe placez pas le token dans l'unit. Placez-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-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/healthLa présence de status=203/EXEC dans la sortie de status 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 dans un emplacement sous le répertoire personnel de l'utilisateur avec nvm. systemd ne trouvera pas ce dernier. Une unit qui démarre puis s'arrête immédiatement a échoué dans npm. journalctl -u memmy-memory -n 50 affiche la raison. Le fonctionnement est identique à celui de tout autre service systemd sur un VPS.
Ce que Memmy ne fait pas encore
- Il n’existe pas de build pour le bureau Linux. Les scripts de packaging couvrent macOS et Windows. Le workbench, son assistant de mise en route et le tableau de bord de la mémoire ne sont donc pas disponibles directement sur le serveur.
memory:serve:devexécute le point d’entrée TypeScript viatsx, qui correspond à un chemin de développement. Le dépôt fournit égalementmemory:servepour la sortie compilée. Exécuteznpm runsans argument pour voir quels scripts sont réellement présents dans votre checkout.- La récupération construit sa fenêtre de recherche à partir des 2,000 dernières lignes de vecteurs, 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 a lieu après la capture. En cas d’échec, la mémoire 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 encore trouvable par la recherche vectorielle.
- Un seul fichier SQLite correspond à un seul nœud. Il n’y a pas de clustering. Un deuxième serveur correspond donc à une mémoire distincte.
La version 1.0.4 et environ 329 stars en juillet 2026 décrivent un projet encore récent. 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 au lieu 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 7 avec Failed to connect to 127.0.0.1 port 18960 signifie que le memory service n'est pas en cours d'exécution ou qu'il s'est arrêté au démarrage. Consultez donc le terminal ou le journal où il a été lancé. Les 2 causes habituelles sont un module natif better-sqlite3 incompatible avec 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 provient du champ bin du package workspace @memmy/memory, et non du nom du repository. Exécutez node -p "JSON.stringify(require('./Memory/package.json').bin)" dans le checkout. La commande affiche {"memmy-memory":"./dist/src/cli/index.js"}. Ce fichier n'existe qu'après npm run memory:build, car le build 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 répertoriés sous tools.mcpServers dans ~/.memmy/config.yaml et fournit leurs outils à son propre runtime. Claude Code accède à Memmy dans l'autre sens, en exécutant la CLI memmy-memory comme une commande shell, à partir 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 memories à un cloud service ?
Le scanning et l'ingestion s'exécutent localement, et les memories sont écrites dans ~/.memmy/memory-service/memory.sqlite sur votre propre disque. MEMMY_CLOUD_SERVICE utilise https://memmy-api.memtensor.cn pour le mode compte et les trial tokens. Le programme d'amélioration des memories reste désactivé tant que vous ne l'activez pas. Le point à surveiller est l'embeddding provider : un hosted embedding model reçoit le texte de chaque memory qu'il convertit en vecteur. Utilisez donc un endpoint que vous exécutez vous-même si ce point est important.