📜 Mémoire du Foyer de Calcifère ✨

🗺️ Architecture, décisions et timeline du système multi-agents

📅 Timeline Chronologique 🕰️

  • 15/07/2026 : 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é).
  • 20/07/2026 : 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.
  • 25/07/2026 : Abandon de MCP Fédération Gateway (incompatibilité stdio/HTTP). Remplacement par un gateway Python utilisant un socket Unix (/tmp/nanobot_gateway.sock).
  • 28/07/2026 : Restrictions MCP appliquées :
    • Logs obligatoires pour rm et mv (dossier utilisateur/logs/mcp_audit.log).
    • Permissions différenciées par agent (ex: Calcifère = écriture restreinte à memory/).

🏗️ 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).

Solution : Un gateway MCP unique (Python, socket Unix) centralise tous les appels outils. Avantages :
  • 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.json restreint rm à 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.

Solution : Le socket Unix (/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/

Solution :
  • Restriction de rm et mv à 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).

Ports gérés :
  • 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)
Mécanismes de sécurité :
  • 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.

Outils exposés :
  • 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.
Mécanismes de sécurité :
  • 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 subprocess pour 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]
            
Règles de routage :
  • 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)
            
Protocoles :
  • Sen ↔ Calcifère : HTTP POST via sen_handoff.sh (port port dédié).
  • Calcifère ↔ [Sophie/Marco/Hinn] : HTTP POST via calcifere_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: "*****"
    

Fallbacks :
  • nvidia-nemotron-ultragpt-oss-120bmistral-medium-2508
  • llama-3.3-70bmistral-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.

Détails techniques :
  • Socket : /tmp/nanobot_gateway.sock (permissions srwxrwxr-x, propriétaire hauuru).
  • 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"}}
    }
  ]
}
                    

Annexes