📅 Timeline Chronologique 🕰️
- : Lancement initial avec Nanobot v0.2.2. Déploiement des 5 agents (Sen, Calcifère, Sophie, Marco, Hinn) et configuration des ports API (port dédié-port dédié).
- : Intégration de LiteLLM (port 40**) et configuration des modèles (Nemotron, Llama 3.3, GLM-4.7, GPT-OSS 120B). Mise en place des fallbacks pour Cerebras.
-
:
Abandon de MCP Fédération Gateway (incompatibilité stdio/HTTP).
Remplacement par un gateway Python utilisant un socket Unix (
/tmp/nanobot_gateway.sock). -
:
Restrictions MCP appliquées :
- Logs obligatoires pour
rmetmv(dossier utilisateur/logs/mcp_audit.log). - Permissions différenciées par agent (ex: Calcifère = écriture restreinte à
memory/).
- Logs obligatoires pour
🏗️ Décisions Architecturales 🔧
1. Centralisation via MCP Nanobot Gateway
Problème :
Les appels directs aux outils système (ls, cat, grep) par chaque agent
généraient une surface d'attaque élargie et une consommation excessive de tokens
(chaque commande était encapsulée dans un prompt LLM).
- Réduction de ~40% des tokens utilisés par les agents.
- Traçabilité complète via
dossier utilisateur/logs/mcp_audit.log. - Contrôle granulaire des permissions (ex:
servers.jsonrestreintrmà Calcifère).
# Exemple de configuration dans servers.json
{
"local_tools": {
"read_only": ["ls", "cat", "grep", "df"],
"restricted": {
"rm": ["calcifere"],
"mv": ["calcifere"]
}
}
}
2. Utilisation d'un Socket Unix
Problème : Les ports TCP (ex: 50**) étaient déjà saturés par LiteLLM (40**), llama.cpp (80**), et les APIs des agents (port dédié-port dédié). Ajouter un nouveau service HTTP aurait nécessité une reconfiguration complexe du pare-feu et des règles SSRF.
/tmp/nanobot_gateway.sock) élimine les conflits de ports
et est nativement compatible avec le protocole stdio de MCP.
Avantages :
- Pas de collision avec les services existants.
- Latence réduite (communication inter-processus locale).
- Sécurité renforcée (accès limité à l'utilisateur
hauuru).
# Commande de test du socket
echo '{"jsonrpc": "2.0", "method": "ls", "params": {"path": "/home/hauuru"}, "id": 1}' | \
socat - UNIX-CONNECT:/tmp/nanobot_gateway.sock
💡 Leçons Apprises & Erreurs 🐛
1. Incompatibilité MCP Fédération Gateway
Erreur :
Le binaire officiel McpFederationGateway (C#) imposait un protocole HTTP/REST
alors que l'architecture existante utilisait stdio (JSON-RPC via socket).
Les tests avec netcat échouaient systématiquement avec :
HTTP/1.1 400 Bad Request
Solution :
Remplacement par un gateway Python (
nanobot_gateway_simple.py)
utilisant subprocess et un socket Unix.
Coût : 2 jours de développement, mais gain en stabilité.
2. Permissions MCP Mal Configurées
Erreur :
La première version de servers.json autorisait rm -rf
pour tous les agents, sans logs. Risque critique identifié lors d'un test :
hinn$ rm -rf dossier utilisateur/Desktop/
- Restriction de
rmetmvà Calcifère uniquement. - Ajout d'un système de logs dans
dossier utilisateur/logs/mcp_audit.log:[2026-07-28 14:00:00] [CALCIFERE] rm -f dossier utilisateur/tmp/test.txt - Validation des permissions via
check_permission()dans le gateway.
3. Fallbacks LiteLLM pour Cerebras
Erreur :
La configuration initiale de litellm_config.yaml utilisait
cerebras/gpt-oss-120b comme nom de modèle, ce qui provoquait des erreurs :
ProviderNotFoundError: No provider found for cerebras/gpt-oss-120b
Solution :
Correction du nom du modèle en gpt-oss-120b et ajout explicite
du provider cerebras dans la configuration :
providers:
cerebras:
api_key: "*****"
api_base: "https://api.cerebras.ai/v1"
Impact : Résolution immédiate des erreurs de fallback.
📜 Scripts Clés 🔑
1. demarrage_du_chateau_ambulant.sh
Rôle : Script principal pour démarrer l'ensemble des services du Foyer (LiteLLM, agents Nanobot, MCP Gateway).
- 40** : LiteLLM (proxy pour les modèles)
- port dédié-port dédié : APIs des agents (Calcifère, Sophie, Marco, Hinn)
- port dédié : Sen (WebSocket gateway)
- Libération forcée des ports avant redémarrage :
pkill -9 -f 'nanobot'. - Redirection des logs vers
dossier utilisateur/logs/(ex:nohup ... > "$LOG_DIR/litellm.log" 2>&1 &). - Vérification de l'état des services via
ss -tulnp | grep -E 'port dédié|port dédié|port dédié|port dédié|port dédié|40**'.
# Exemple de commande de démarrage
nohup nanobot serve --config ~/.nanobot-calcifere/config.json \
> "$LOG_DIR/calcifere.log" 2>&1 &
2. nanobot_gateway_simple.py
Rôle :
Gateway MCP simplifié en Python, remplaçant le binaire C# officiel.
Utilise un socket Unix (/tmp/nanobot_gateway.sock) pour
communiquer avec les agents Nanobot.
- Lecture seule :
ls,cat,grep,df,du(accessibles par Sen, Hinn, Marco). - Écriture restreinte :
rm,mv(uniquement Calcifère, avec logs). - Métatools :
list_servers,discover_tools,execute_tool.
- Validation des permissions via
check_permission(agent, tool)avant exécution. - Logs centralisés dans
dossier utilisateur/logs/mcp_nanobot_gateway.log(format :[TIMESTAMP] [AGENT] [TOOL] [PARAMS]). - Utilisation de
subprocesspour encapsuler les appels système (isolation).
# Exemple de configuration dans servers.json
{
"local_tools": {
"read_only": ["ls", "cat", "grep"],
"restricted": {
"rm": ["calcifere"],
"mv": ["calcifere"]
}
}
}
# Exemple d'appel via socket
{
"jsonrpc": "2.0",
"method": "execute_tool",
"params": {
"server_name": "local_tools",
"tool_name": "ls",
"arguments": {"path": "dossier utilisateur/Desktop"}
},
"id": 1
}
🤖 Agents du Château 🏰
| Agent | Rôle | Modèle (LiteLLM) | Port API | Port WS | Accès MCP |
|---|---|---|---|---|---|
| Sen | Gardienne conversationnelle (filtrage/routage) | mistral-medium-2508 |
— | port dédié | Lecture seule (ls, cat, grep) |
| Calcifère | Orchestrateur (route vers Sophie/Marco/Hinn) | nvidia-nemotron-ultra |
port dédié | port dédié | Lecture + écriture restreinte (rm, mv avec logs) |
| Sophie | Stratège (projets, mémoire vectorielle) | llama-3.3-70b |
port dédié | 87** | Aucun (définit les règles, n'exécute pas) |
| Marco | Créatif (code, emails, prompts) | glm-4.7-flash |
port dédié | 87** | Lecture seule (cat pour références) |
| Hinn | Exécutant système (shell, SQL, web) | gpt-oss-120b |
port dédié | 87** | Lecture seule (ls, df, grep) |
Flux de Communication
Utilisateur → Sen (WS port dédié) → Calcifère (API port dédié) → [Sophie|Marco|Hinn]
- Sen clarifie l'intention avant de router vers Calcifère.
- Calcifère route selon la tâche :
- Planification → Sophie
- Création de code/texte → Marco
- Exécution système → Hinn
🗺️ Architecture Globale 🌐
1. Schéma Global
Utilisateur (Discord/Telegram/WS)
↓
Sen (WS port dédié) — Gardienne du seuil
↓ (clarifie, dialogue, puis route)
Calcifère (API port dédié) — Orchestrateur
↓ (route selon la tâche)
├─→ Sophie (API port dédié) — Planification, projets, mémoire
├─→ Marco (API port dédié) — Code, emails, prompts créatifs
└─→ Hinn (API port dédié) — Exécution système (shell, SQL, web, MCP Gateway)
- Sen ↔ Calcifère :
HTTP POSTviasen_handoff.sh(port port dédié). - Calcifère ↔ [Sophie/Marco/Hinn] :
HTTP POSTviacalcifere_handoff.sh(ports port dédié-port dédié). - Hinn ↔ MCP Gateway :
Socket Unix(/tmp/nanobot_gateway.sock, protocole JSON-RPC 2.0).
2. Composants Techniques
LiteLLM (Port 40**)
Rôle : Proxy unifié pour les appels aux modèles (Nemotron, Llama, GLM, Cerebras). Gère les fallbacks et la charge des clés API.
Configuration clé :
# litellm_config.yaml
providers:
cerebras:
api_key: "*****"
api_base: "https://api.cerebras.ai/v1"
model_list:
- model_name: gpt-oss-120b
litellm_params:
model: gpt-oss-120b
api_key: "*****"
nvidia-nemotron-ultra→gpt-oss-120b→mistral-medium-2508llama-3.3-70b→mistral-medium-2508
MCP Nanobot Gateway
Rôle :
Centralise les appels aux outils système (ls, cat, rm, etc.)
via un socket Unix pour réduire la consommation de tokens et sécuriser les accès.
-
Socket :
/tmp/nanobot_gateway.sock(permissionssrwxrwxr-x, propriétairehauuru). -
Protocole : JSON-RPC 2.0 (exemple de requête :
{ "jsonrpc": "2.0", "method": "execute_tool", "params": { "server_name": "local_tools", "tool_name": "ls", "arguments": {"path": "/home/hauuru"} }, "id": 1 } -
Logs :
dossier utilisateur/logs/mcp_nanobot_gateway.log(format :[TIMESTAMP] [AGENT] [TOOL] [PARAMS]).
Exemple d'intégration avec Hinn :
# Dans ~/.nanobot-hinn/config.json
{
"tools": [
{
"name": "mcp_ls",
"exec": {
"command": [
"jq -n --arg tool 'execute_tool' --argjson params \
'{"server_name": "local_tools", "tool_name": "ls", "arguments": {"path": "{path}"}}' \
'{tool: $tool, parameters: $params}' | \
socat - UNIX-CONNECT:/tmp/nanobot_gateway.sock"
]
},
"parameters": {"path": {"type": "string"}}
}
]
}