Hermes Agent : un agent autonome sur Telegram
1. Quoi ? — Définition et contexte
Section intitulée « 1. Quoi ? — Définition et contexte »Hermes Agent est un agent conversationnel autonome publié par Nous Research sous licence MIT. Contrairement aux briques IA déjà en place sur le VPS — qui sont des passerelles appelées par des workflows — Hermes est un processus long qui garde le fil : il conserve sa mémoire entre les conversations, choisit lui-même quels outils appeler, et n’a besoin d’aucun workflow pour décider quoi faire.
Sur cette infrastructure, il tourne dans un conteneur de l’ai-stack avec un bot Telegram dédié comme seule interface. Aucun port publié, aucune route Caddy, aucun dashboard.
Composants
Section intitulée « Composants »| Brique | Détail |
|---|---|
| Conteneur | nousresearch/hermes-agent:latest — aucun port publié, réseaux n8n-internal + mcp-backend |
| LLM | Abonnement ChatGPT/Codex via le provider natif openai-codex (gpt-5.5) |
| Outils métier | 32 outils MCP servis par le workflow N8N Hermes MCP Tools |
| Outils debug | 4 outils N8N en lecture seule (n8n-mcp), réservés au diagnostic de workflows |
| Mémoire | Provider externe Mnemosyne — SQLite local, recherche hybride vecteur + FTS5 |
| Plugins | 3 plugins maison greffés sur les hooks du gateway |
Architecture visuelle
Section intitulée « Architecture visuelle »Dans cette section
Section intitulée « Dans cette section »Cet article couvre le déploiement : conteneur, configuration, modèle de sécurité et exploitation. Trois articles détaillent ce qui s’y greffe.
| Article | Contenu |
|---|---|
| Les 32 outils MCP | Catalogue complet, gateways à entrées typées, écriture confinée dans le vault, pièges de la couche MCP N8N |
| La mémoire longue Mnemosyne | Mode wrapper, recherche hybride, 20 outils de mémoire, consolidation et exploitation |
| Les skills sur mesure | Le système de skills et les douze procédures écrites pour ce déploiement |
| Les plugins et leurs hooks | Quatre plugins Python greffés sur le cycle de vie du gateway |
2. Pourquoi ? — Enjeux et motivations
Section intitulée « 2. Pourquoi ? — Enjeux et motivations »Six décisions structurantes
Section intitulée « Six décisions structurantes »Prises en session de cadrage avant la première ligne de configuration, elles expliquent la quasi-totalité de la forme du déploiement.
| Décision | Raison |
|---|---|
LLM en direct via openai-codex, sans passer par cli-ollama | L’abonnement est consommé nativement par le provider Hermes. Interposer la passerelle ajouterait un saut, un timeout et une perte de contexte pour zéro gain |
| Accès N8N en double canal | Un canal d’outils métier curés, un canal de diagnostic en lecture seule. La séparation est explicite, pas implicite |
| Bot Telegram uniquement | Pas de port, pas de route Caddy, pas de dashboard : la surface d’attaque HTTP est nulle |
Service dans ai-stack/docker-compose.yaml | Cohabitation avec Qdrant et cli-ollama, mêmes réseaux internes, même cycle de vie |
| Réactif seulement en v1 | Le scheduler et les automations restent désactivés : un agent qui agit sans qu’on le lui demande est difficile à auditer tant qu’on n’a pas confiance dans ses garde-fous |
| Data dir dans le backup quotidien | Toute la valeur accumulée (mémoire, sessions, skills) vit dans un seul répertoire — le perdre, c’est repartir de zéro |
Pourquoi deux canaux MCP plutôt qu’un seul ?
Section intitulée « Pourquoi deux canaux MCP plutôt qu’un seul ? »Le serveur MCP administrateur (n8n-mcp) expose 24 outils, dont n8n_delete_workflow et n8n_manage_credentials. Les brancher tels quels reviendrait à donner à l’agent les clés de l’automatisation entière pour lui permettre de lire un log d’exécution.
Le déploiement les sépare donc :
n8n-tools— le flow normal. Des outils métier écrits à la main, à entrées typées, exposés par un workflow N8N dédié. C’est ce que l’agent utilise 99 % du temps.n8n-admin— filtré à 4 outils de diagnostic en lecture seule (n8n_list_workflows,n8n_get_workflow,n8n_executions,n8n_validate_workflow), et réservé par une règle du system prompt au seul débogage de workflows.
Pourquoi une mémoire externe ?
Section intitulée « Pourquoi une mémoire externe ? »La mémoire native de Hermes est un fichier MEMORY.md réinjecté dans le prompt. Simple, mais elle plafonne : pas de recherche, et un budget de caractères qui force à arbitrer entre tout garder et rester lisible.
Mnemosyne remplace ce mécanisme par une base SQLite locale avec recherche hybride (vecteur + FTS5) et capture en tâche de fond à chaque tour. Local-first : aucune donnée de conversation ne quitte le VPS pour être vectorisée.
3. Comment ? — Mise en œuvre technique
Section intitulée « 3. Comment ? — Mise en œuvre technique »Le service Docker
Section intitulée « Le service Docker »hermes: image: nousresearch/hermes-agent:latest container_name: hermes command: gateway run networks: - n8n-internal # MCP Server Trigger (n8n:5678) - mcp-backend # n8n-mcp:3000 (debug uniquement) environment: - PUID=${CLAUDE_USER_ID:-1000} - PGID=${CLAUDE_GROUP_ID:-1000} - TELEGRAM_BOT_TOKEN=${HERMES_TELEGRAM_BOT_TOKEN} - TELEGRAM_ALLOWED_USERS=${HERMES_ALLOWED_CHAT_ID} - HERMES_N8N_MCP_TOKEN=${HERMES_N8N_MCP_TOKEN} - N8N_MCP_AUTH_TOKEN=${N8N_MCP_AUTH_TOKEN} volumes: - ./hermes/data:/opt/data security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - SETUID - SETGID - DAC_OVERRIDE deploy: resources: limits: memory: 3G cpus: '2' healthcheck: test: ['CMD-SHELL', 'pgrep -f "bin/hermes[ ]gateway run" > /dev/null || exit 1'] interval: 30sAucune section ports : c’est volontaire et c’est le cœur du modèle de sécurité. Le seul chemin entrant est le long-polling Telegram sortant.
La configuration
Section intitulée « La configuration »Hermes génère et migre son config.yaml tout seul au premier démarrage ; seules les clés de ce déploiement sont reportées à la main.
model: provider: "openai-codex" default: "gpt-5.5" base_url: "https://chatgpt.com/backend-api/codex"
mcp_servers: n8n-tools: # flow normal url: "http://n8n:5678/mcp/hermes-tools" headers: Authorization: "Bearer ${HERMES_N8N_MCP_TOKEN}" timeout: 120 n8n-admin: # debug de workflows UNIQUEMENT url: "http://n8n-mcp:3000/mcp" headers: Authorization: "Bearer ${N8N_MCP_AUTH_TOKEN}" tools: include: [n8n_list_workflows, n8n_get_workflow, n8n_executions, n8n_validate_workflow]
memory: provider: "mnemosyne"
plugins: enabled: - telegram-voice-transcriptor
gateway: platforms: telegram: extra: allow_from: - "<CHAT_ID>" # valeur LITTÉRALE obligatoireLe system prompt comme couche de sécurité
Section intitulée « Le system prompt comme couche de sécurité »Certaines règles ne peuvent pas être imposées par la plomberie : elles vivent dans SOUL.md, occupant le premier slot du system prompt.
- Flow normal : toute action métier passe par
n8n-tools. n8n-admin= debug uniquement, jamais pour une action métier, et jamais pour modifier un workflow.docker_manage= action sensible : aucune chaîne d’approbation n’existe en aval, donc l’agent doit demander une confirmation explicite avant chaquestart/stop/restart/update, en nommant la stack et l’action.- Vault : toujours citer le chemin du fichier source ; écriture uniquement via
vault_write, confinée, et jamais de sa propre initiative. - Pas d’action non sollicitée : l’agent exécute ce qui est demandé et propose le reste.
Ce qui se greffe sur le gateway
Section intitulée « Ce qui se greffe sur le gateway »Trois mécanismes d’extension cohabitent, et la distinction entre eux structure tout le déploiement.
| Mécanisme | Nature | Où il vit | Détail |
|---|---|---|---|
| Outils MCP | Nodes N8N | Workflow Hermes MCP Tools | 32 outils sur 8 domaines |
| Skills | Markdown | /opt/data/skills/ | 145 actives, dont 12 sur mesure |
| Plugins | Python | /opt/data/plugins/ | 4 plugins, greffés sur les hooks |
La règle de partage : un outil MCP rend une action possible, une skill la rend bien faite, un plugin la déclenche sans que l’agent décide. Et la mémoire longue — Mnemosyne — s’installe par le troisième mécanisme, en mode wrapper.
Sécurité
Section intitulée « Sécurité »| Surface | Protection |
|---|---|
| Endpoint MCP N8N | Bearer obligatoire — 403 sans token, vérifié en E2E |
| Endpoint MCP depuis Internet | /mcp/* et /mcp-test/* renvoient 404 côté Caddy ; seul le chemin interne n8n:5678 fonctionne |
| Bot Telegram | Allowlist stricte fail-closed — un chat_id inconnu est bloqué sans réponse |
| Actions destructrices Docker | Whitelist d’actions dans Docker Actions, security-stack non actionnable |
docker_manage, crm_delete_lead, timesheet_delete | Pas de chaîne d’approbation en aval → confirmation exigée par le system prompt |
| Écriture vault | Confinée à research/ et inbox/, extension .md, anti-traversal, plafond 150 000 octets |
| Secrets | Passés par l’environnement compose, jamais écrits dans /opt/data (qui part en backup) |
Le confinement de vault_write mérite un mot, parce qu’il résout un problème classique des agents qui écrivent : l’écrasement à l’aveugle. Une lecture via vault_read renvoie un contentHash ; modifier un fichier existant exige de repasser ce hash en Base_Hash. Sans hash, la réponse est __EXISTS__ ; si le fichier a bougé depuis la lecture, __STALE_READ__. Et les erreurs ne renvoient jamais le hash courant — sinon le modèle pourrait le récupérer et écraser sans avoir lu. Détail de l’implémentation.
Sauvegarde
Section intitulée « Sauvegarde »Le répertoire de données part dans le backup quotidien vers Google Drive, après exclusions : les credentials OAuth (auth.json, google_token.json, google_client_secret.json), les credentials Git, le venv Mnemosyne et les caches de modèles. La base de mémoire, elle, est incluse. L’archive tombe ainsi à 8,2 Mo au lieu de 58 Mo.
Après une restauration complète, trois gestes manuels : refaire le device flow Codex, refaire le flow OAuth Google, réinstaller le venv Mnemosyne.
Commandes d’exploitation
Section intitulée « Commandes d’exploitation »docker exec hermes hermes mcp test n8n-tools # connexion MCP live + liste d'outilsdocker exec hermes hermes auth list # credential OAuth chargé ?docker exec hermes hermes plugins list # plugins enabled/disableddocker exec hermes hermes memory status # provider mémoire actifdocker exec hermes hermes gateway statusdocker exec hermes hermes -z "ping" # tour LLM one-shot (consomme du quota)4. Et si ? — Perspectives et limites
Section intitulée « 4. Et si ? — Perspectives et limites »Limites actuelles
Section intitulée « Limites actuelles »| Limite | Impact | Mitigation |
|---|---|---|
| Quota ChatGPT partagé | L’abonnement sert Hermes, Codex CLI et les workflows N8N. Plafond atteint = le bot renvoie des erreurs jusqu’au reset | Plugin codex-usage-alert sur seuil ; router les usages non interactifs vers gemini-flash |
| Garde-fous portés par le prompt | docker_manage et les suppressions n’ont pas de validation technique en aval | Whitelist d’actions dans Docker Actions ; une vraie chaîne d’approbation Telegram reste à câbler |
| v1 réactive | Aucune tâche planifiée : l’agent ne fait rien sans sollicitation | Volontaire tant que les garde-fous ne sont pas durcis |
employee_id figé | timesheet_log_hours écrit toujours sur l’employé 1 | Sans objet aujourd’hui (un seul employé), à paramétrer si l’équipe grandit |
| Mapping des étapes CRM | Les IDs d’étapes sont encodés dans les descriptions $fromAI | crm_list_stages fournit désormais la source dynamique |
| Sous-nodes MCP non désactivables | Désactiver un outil dans Hermes MCP Tools fait exécuter le mauvais node à tous les outils suivants, en silence | Supprimer le node plutôt que le désactiver (détail) |
Scénarios d’évolution
Section intitulée « Scénarios d’évolution »Si l’agent devient proactif :
- Déposer des jobs dans
/opt/data/cron/active le scheduler (inactif tant qu’il est vide). - Prérequis : une chaîne d’approbation réelle sur les actions sensibles, pas seulement une règle de prompt.
- Candidats naturels : digest matinal des alertes Prometheus, relance des leads CRM dormants.
Si la mémoire doit sortir du VPS :
- Export des mémoires Mnemosyne en notes markdown dans le vault, pour les rendre lisibles et versionnées.
- Puis synchronisation bidirectionnelle VPS ↔ poste de travail, pour une mémoire unique entre l’agent et l’assistant local. Détail.
Si le périmètre d’écriture s’élargit :
- Le confinement
research/+inbox/est une liste blanche de préfixes : l’étendre est trivial, mais chaque nouveau préfixe doit venir avec sa justification. - La séquence commit + push immédiat propage déjà vers les clients Obsidian ; augmenter le débit d’écriture augmentera le bruit dans l’historique Git.
Si un second utilisateur doit y accéder :
- L’allowlist accepte plusieurs chat_id, mais la mémoire et le profil utilisateur sont globaux au conteneur.
- Il faudrait un conteneur par utilisateur (répertoires de données distincts) plutôt qu’une allowlist élargie.
Commandes de dépannage
Section intitulée « Commandes de dépannage »# Le bot ne répond pasdocker logs hermes --tail 100docker inspect hermes --format='{{.State.Health.Status}}'
# Message ignoré → allowlistdocker logs hermes 2>&1 | grep -i "unauthorized"
# Outils MCP absents ou périmésdocker exec hermes hermes mcp test n8n-toolsdocker compose -f ai-stack/docker-compose.yaml restart hermes
# Mémoire indisponibledocker exec hermes hermes memory statusdocker exec --user hermes -e HOME=/opt/data -e HERMES_HOME=/opt/data hermes \ /opt/data/.mnemosyne/venv/bin/mnemosyne stats
# Vérifier que l'endpoint MCP reste bien fermé de l'extérieurcurl -so /dev/null -w '%{http_code}\n' https://n8n.guigpap.com/mcp/hermes-tools # attendu : 404Pages liées
Section intitulée « Pages liées »- Les 32 outils MCP — Catalogue, gateways et écriture confinée
- La mémoire longue Mnemosyne — Mode wrapper, rappel hybride
- Les skills sur mesure — Douze procédures écrites pour ce déploiement
- Les plugins et leurs hooks — Quatre extensions Python du gateway
Infrastructure
Section intitulée « Infrastructure »- AI Stack — Qdrant, CLI Ollama et la gateway MCP
- Architecture VPS — Vue d’ensemble et topologie réseau
- Security Stack — Caddy, blocage externe des endpoints internes
- Backup des bases de données — Sauvegarde du répertoire de données
Workflows
Section intitulée « Workflows »- Content Pipeline — Le vault Obsidian
vps-vaultet ses miroirs - Système conversationnel — L’autre agent Telegram, via CLI Ollama
- Codex CLI Integration — Le login Codex de
cli-ollama, distinct de celui d’Hermes - Error Handler — Workflow d’erreur des gateways
Référence
Section intitulée « Référence »- Glossaire — MCP, Agent autonome, Mémoire à long terme, LLM