Chatbotaurus
Documentation
MCP Gateway as a Service, plateforme souveraine européenne
Komi Djibrile CAMARA (@chatbotaurus)
Imprimé le
Chatbotaurus en 5 minutes
Chatbotaurus est une plateforme MGaaS (MCP Gateway as a Service) souveraine
européenne, écrite en Rust : un backend Axum (forge-api) et un frontend
Dioxus compilé en wasm (forge-ui). Elle réunit un agent conversationnel, une
passerelle MCP et des fiches de connecteurs YAML.
Cette page montre un chemin court : lancer la pile en local, ouvrir l'application, poser une première question.
Chiffres du catalogue : 195 fiches YAML de connecteurs, mesurées le 3 octobre 2026 (
connectors/*.yaml). Le nombre exact change à chaque ajout ; la source est le dossier, pas cette page.
Trois parcours de lecture
Ce livre se lit selon votre rôle. Chaque étape renvoie au chapitre qui la traite ; la page que vous lisez reste un chemin court pour lancer la pile en local.
Décideur (dirigeant, délégué à la protection des données, acheteur)
- Cas d'usage par secteur : ce que la plateforme fait pour votre métier
- Tarification et offres : les quatre offres et les capacités par plan
- SLA, support et niveaux de service : disponibilité, délais de support, pénalités
- Conformité RGPD : données personnelles, hébergement et sous-traitants dans l'UE
- Comparatifs : ce qui distingue une passerelle hébergée dans l'UE
- Limites et ce que la plateforme ne fait pas : le périmètre, dit sans détour
Délégué à la protection des données (répondre à une demande d'un utilisateur, documenter la sous-traitance) : Conformité RGPD, Paramètres (la page Compte porte l'export et la suppression), Journaux (chaîne d'audit) et Réponse aux incidents (notification d'une violation).
Utilisateur (responsable métier, équipe)
En production, l'application est sur app.chatbotaurus.eu (voir En production). En local, lancez d'abord la pile avec le chemin court plus bas.
- Prise en main guidée : du compte au premier workflow
- Tableau de bord : la première page après la connexion
- Workflows : l'éditeur, la palette de nœuds, les exécutions
- Chat : parler à un workflow déployé
- Connaissances : collections de documents et recherche ancrée (l'envoi de documents depuis l'application n'est pas encore branché)
- Questions fréquentes : les réponses courtes aux questions courantes
Pour brancher votre Odoo : Sécurité et identifiants (enregistrer les identifiants), puis Connecter Odoo à la passerelle MCP (un premier outil appelé, puis le chat).
Opérateur ou intégrateur (développeur, administrateur système)
- Installation de Chatbotaurus : compiler et lancer la pile
- Variables d'environnement : chaque variable lue par le code
- Déploiement avec Podman : deux plans, unités Quadlet en production
- Créer votre premier connecteur MCP : une fiche YAML, sans Rust
- Routes MCP (Streamable HTTP) : le transport, les sessions, le catalogue
- Supervision : points de santé et métriques en service
Une fois la pile en service : Sauvegarde et restauration, Gestion des conteneurs (mise à jour, dépannage) et Réponse aux incidents.
Pour appeler l'API depuis un script : Documentation Swagger (obtenir un jeton), puis Connecter Odoo à la passerelle MCP (un premier appel d'outil de bout en bout) et Gestion des erreurs (lire un code d'erreur).
Prérequis
| Outil | Version | Usage |
|---|---|---|
| Rust (rustup) | 1.91 ou plus (rust-version du workspace) | Compiler forge-api et forge-ui |
Dioxus CLI (dx) | 0.7 | Serveur de développement et bundler wasm |
| Git | 2.x | Récupérer le dépôt |
| Podman | 4.x ou plus | Conteneurs d'infrastructure (PostgreSQL, Valkey, Qdrant, Ollama, entre autres) |
podman-compose | avec un tiret | Lancer les deux plans compose du dépôt |
| Cible wasm | wasm32-unknown-unknown | rustup target add wasm32-unknown-unknown, nécessaire à la compilation de forge-ui (étapes 3 et 6) |
Installez le CLI Dioxus avec :
cargo install dioxus-cli --locked
1. Récupérer le dépôt
git clone <url-du-depot>
cd <dossier-du-depot>
cp .env.example .env
Éditez .env. Les valeurs secrètes de .env.example sont des gabarits
CHANGE_ME_... : l'application refuse de démarrer avec elles. Générez les
vôtres, par exemple avec openssl rand -hex 64.
Variables minimales (toutes lues par le code ; la liste complète est dans Variables d'environnement) :
DATABASE_URL=postgresql://<utilisateur>:<mot-de-passe>@localhost:5432/<base>
REDIS_URL=redis://localhost:6380
JWT_SECRET=<64 octets hexadécimaux>
QDRANT_URL=http://localhost:6334
OLLAMA_BASE_URL=http://localhost:11434
SMTP_HOST=<serveur-smtp>
SMTP_USER=<compte>
SMTP_PASSWORD=<mot-de-passe-applicatif>
Pourquoi le SMTP : le second facteur (FORCE_2FA, vrai par défaut) envoie un
code par courriel. Sans SMTP configuré, le démarrage est refusé.
2. Lancer l'infrastructure
Le dépôt a deux plans compose (voir Déploiement avec Podman).
Pour un premier essai, le plan
chatbotaurus-vps1 suffit (PostgreSQL, Valkey, Qdrant, Ollama, Authentik,
OpenBao, voix, observabilité) :
podman-compose -p chatbotaurus-vps1 -f podman-compose.yml up -d
Le plan mgaas-vps2 (passerelle et serveurs mcp-*) se lance de la même
façon avec podman-compose.vps2.yml. Il n'est pas nécessaire pour ce
tutoriel.
Téléchargez ensuite le modèle de dialogue souverain dans Ollama :
podman exec forge-ollama ollama pull cas/eurollm-1.7b-instruct-q8
3. Lancer le backend et le frontend
Appliquer les migrations :
cargo run -p forge-cli -- db migrate
Backend, port 3000 :
cargo run -p forge-api
Frontend, port 8080, dans un second terminal :
dx serve --platform web --port 8080 --package forge-ui
La première compilation wasm est longue. Ensuite le rechargement à chaud prend
quelques secondes : ne relancez pas dx pour une modification.
Vérifiez que le backend répond (les autres sondes sont dans Diagnostics et signalement) :
curl http://localhost:3000/api/v1/health
La réponse est un JSON avec "status":"ok", le nom du service et la version.
4. Première conversation
- Ouvrez l'interface locale (http://localhost:8080). Sans session, elle vous renvoie vers l'écran de connexion (
/auth/login). - Créez un compte sur
/auth/signup, puis connectez-vous sur/auth/login. Le code à usage unique arrive par courriel (/auth/verify-otp). - Au premier accès, l'assistant d'accueil (
/onboarding) vous demande votre secteur et un modèle de départ. Voir Prise en main guidée. - Ouvrez
/chatou/orchestratoret posez une question, par exemple :
Quels connecteurs sont disponibles pour l'ERP ?
L'assistant s'appuie sur le catalogue de connecteurs de votre instance. La page est décrite dans Chat.
5. Interroger l'API
Les routes de l'API sont sous /api/v1. Le catalogue des connecteurs (contrat et
authentification : Documentation Swagger) exige un
jeton (Authorization: Bearer <jeton>), obtenu par la connexion (voir
Authentification) :
curl -H "Authorization: Bearer <jeton>" \
http://localhost:3000/api/v1/mcp/catalogue
Le transport MCP (JSON-RPC 2.0, HTTP streamable) est monté sur
/api/v1/mcp, lui aussi authentifié. Voir Routes MCP.
Les passerelles (Routes des gateways et de la prédiction) se manipulent par
/api/v1/mcp-gateway/*.
6. Vérifier
cargo test -p forge-replay
cargo build -p forge-ui --target wasm32-unknown-unknown --bin chatbotaurus
Pour regénérer ce livre en local : cargo run -p forge-docs. dx serve le
sert ensuite sous /docs/.
En production
L'application publique est servie sur chatbotaurus.eu (site) et
app.chatbotaurus.eu (application). Les prix publics sont sur la page
/pricing : Starter 9 EUR, Pro 29,90 EUR, Enterprise 99,90 EUR par mois
(HT), Souverain sur devis. Le détail des offres est dans
Tarification.
Prochaines étapes
- Installation complète
- Prise en main guidée
- Fournisseurs de modèles
- Utiliser les connecteurs MCP
- Architecture
- Guide utilisateur
- Contribuer
Voir aussi
- Glossaire : les termes du livre (MCP, gateway, connecteur, nœud) définis en une ligne
- Problèmes connus : ce qui bloque fréquemment au premier lancement
- Fichiers de configuration : les fichiers que le code lit, au-delà du fichier d'environnement
- Gestion des conteneurs : commandes courantes une fois les plans démarrés
Cas d'usage par secteur
Chatbotaurus propose 16 secteurs préconfigurés, plus une entrée « Autre »
pour les métiers qui n'y figurent pas. Chaque secteur associe un jeu de
connecteurs de départ à un vocabulaire métier. Cette page reprend ces
associations telles qu'elles sont décrites dans l'application ; les pages
/solutions/<secteur> du site présentent les mêmes secteurs.
Comment lire cette page
- Dirigeant : repérez votre secteur dans le tableau et lisez la colonne « Pour quoi faire ».
- Responsable métier : le tableau des cas d'usage, plus bas, montre ce qu'on peut demander au chat et avec quels outils.
- Développeur : les connecteurs de départ du premier tableau sont ceux du catalogue (voir Vue d'ensemble des connecteurs). La colonne « Outils mobilisés » du second tableau cite aussi des services de la plateforme, par exemple CrowdSec, qui n'ont pas de fiche de connecteur.
Un secteur ne limite pas la plateforme : il choisit les connecteurs proposés par défaut. Vous pouvez ajouter ou retirer des connecteurs ensuite. Le secteur se choisit dans l'Orchestrateur (carte « Déployer les outils de votre métier »). L'assistant d'accueil le demande aussi (voir Prise en main guidée), mais le serveur n'en conserve rien aujourd'hui.
Les 16 secteurs
| Secteur | Connecteurs de départ | Pour quoi faire |
|---|---|---|
| Thérapeute et bien-être | Odoo, CalRS, Jitsi, CryptPad | rendez-vous, suivi des consultations, téléconsultation, documents partagés |
| Consultant et services | Odoo, CalRS, n8n, Mautic | clients, missions, devis et factures, planification, relances |
| E-commerce et vente en ligne | Odoo, Matomo, Mautic, Typesense | produits, commandes, stock, audience du site, campagnes, recherche catalogue |
| Formation et e-learning | Chamilo, Jitsi, Odoo | cours, apprenants, classes virtuelles, inscriptions |
| Ressources humaines | Odoo, CalRS, Authentik | employés, contrats, congés, recrutement, identité |
| Finance et comptabilité | Odoo, Paperless | factures, paiements, comptabilité, documents comptables |
| Juridique et conformité | Odoo, Paperless, CryptPad | dossiers, contrats, documents, rédaction partagée |
| Immobilier et agences | Odoo, CalRS, Nextcloud | biens, mandats, visites, fichiers des dossiers |
| Tourisme et hôtellerie | Odoo, CalRS, Matomo | réservations, séjours, activités, audience du site |
| Association et ONG | Odoo, Listmonk, Discourse | adhérents, bénévoles, cotisations, lettres d'information, forum |
| Industrie et production | Odoo, n8n, VictoriaMetrics | production, maintenance, qualité, stocks, mesures machines |
| Logistique et transport | Odoo, n8n | livraisons, entrepôts, expéditions, alertes |
| Créatif et média | Nextcloud, OnlyOffice, Mautic | fichiers, documents collaboratifs, campagnes |
| Agriculture et viticulture | Odoo, n8n | cultures, récoltes, élevage, stocks, alertes |
| Médical et cliniques | Odoo, CalRS, OpenBao | patients, consultations, dossiers, secrets protégés |
| Mobilier et décoration | Odoo, Nextcloud | agencement, devis, livraisons, fichiers de projet |
Chaque secteur est aussi relié à des catalogues de données publiques européennes (par exemple santé, énergie, industrie, agriculture, environnement) que le chat peut consulter en lecture (voir API-as-a-Service EU souverain).
Et si votre métier n'est pas dans la liste ?
L'entrée Autre décrit votre besoin et laisse l'équipe adapter les connecteurs, les workflows et la conformité à votre métier. Les secteurs de l'énergie, de l'informatique et de l'administration publique n'ont pas de parcours préconfiguré : ils passent par cette entrée, ou par le plan Souverain pour les exigences renforcées (voir plus bas).
Rappel pour les métiers de la santé
Les données de santé sont des données sensibles au sens de l'article 9 du RGPD. Les secteurs Thérapeute et Médical s'appuient sur des serveurs hébergés dans l'Union ; le secteur Médical ajoute un coffre de secrets (OpenBao et secrets) à ses connecteurs de départ. Le secrétariat de cabinet assisté ne fournit aucune aide au diagnostic et ne prend aucune décision médicale. Voir Conformité RGPD.
Les 13 cas d'usage transverses
Ces cas d'usage ne dépendent pas d'un secteur : chacun combine un modèle
local (Fournisseurs de modèles), des
connecteurs et, quand c'est utile, une base de recherche
(Connaissances). Ils sont
décrits sous /solutions/usecases/<cas>.
| Cas d'usage | Outils mobilisés | Secteurs concernés |
|---|---|---|
| Support client assisté par chat | Ollama, n8n, Qdrant, Odoo | finance, e-commerce, tourisme |
| Signalement d'anomalies et conformité | Ollama, Qdrant, Odoo, VictoriaLogs | finance, e-commerce |
| Automatisation de workflows | n8n, Ollama, Odoo, Nextcloud | consultant, RH, industrie, logistique |
| Hygiène de sécurité assistée | CrowdSec, OpenBao, VictoriaLogs, Grafana | finance, médical, industrie |
| Aide à la décision sur vos données | Ollama, Qdrant, Grafana, n8n | finance, consultant, industrie, RH |
| Recherche et synthèse documentaire | Ollama, Qdrant, Paperless, n8n | juridique, médical, finance, RH |
| Marketing assisté | Mautic, Matomo, Ollama, n8n | e-commerce, tourisme, créatif |
| Secrétariat de cabinet assisté | Ollama, Qdrant, OpenBao, CalRS | médical, thérapeute |
| Suivi de maintenance | Ollama, n8n, VictoriaMetrics, Grafana | industrie, logistique |
| Gestion locative assistée | Odoo, CalRS, Nextcloud, Ollama | immobilier |
| Veille et synthèse | Ollama, Qdrant, n8n, Typesense | consultant, finance, juridique |
| Logistique et stocks assistés | Odoo, n8n, Ollama, Grafana | logistique, industrie, e-commerce |
| Formation assistée | Moodle, Chamilo, Ollama, Jitsi | formation, RH |
Ces cas d'usage assistent vos équipes : l'assistant propose, résume, alerte ; la décision, l'envoi et la validation restent à vos équipes. Une écriture sensible dans un outil (par exemple dans la comptabilité Odoo) passe par une approbation humaine (voir Workflows).
Exemple : un flux de commande en e-commerce
Avec le secteur E-commerce, un flux typique est le suivant :
- Vous demandez au chat de chercher une commande ou un produit : l'assistant
interroge Odoo (outils comme
sales_order_search). - Vous lui demandez de créer un devis ou un contact : il propose l'écriture, que vous validez.
- Un workflow n8n peut déclencher la suite (notification, relance) ; Mautic prend les campagnes, Matomo mesure l'audience.
Chaque étape utilise un connecteur réel du catalogue ; ce que vous automatisez ensuite dépend de votre configuration.
Quel plan choisir ?
Les plans (Starter, Pro, Enterprise, Souverain) se distinguent par le nombre de connecteurs, le niveau de support (SLA, support et niveaux de service) et le mode de déploiement. Le plan Souverain, sur devis, vise les banques et l'État : infrastructure dédiée isolée, déploiement isolé du réseau possible. Les prix et le détail de chaque plan sont sur la page de tarification du site et dans Tarification, seule source à jour.
Voir aussi
- Prise en main guidée — choisir son secteur dans l'assistant d'accueil, puis tester le chat.
- MCP et Orchestrateur — la Gateway Business, une carte par métier.
- Connecteur Odoo — le connecteur de départ commun à presque tous les secteurs.
- Comparatifs — pourquoi une passerelle hébergée dans l'UE plutôt qu'un SaaS hors UE.
- Questions fréquentes — les questions courantes d'un décideur avant de choisir.
Tarification et offres
Cette page décrit les quatre offres publiées sur la page Tarifs du site, état au 3 octobre 2026. Les prix sont hors taxes, mensuels et fixes. Le prix inclut la passerelle MCP, l'IA souveraine (Fournisseurs de modèles), les connecteurs MCP (Vue d'ensemble), la conformité UE (Conformité RGPD) et le support. Les outils métier (Odoo, n8n et autres) sont auto-hébergés par vos soins, ou disponibles en déploiement assisté, en option.
Le prix qui fait foi est celui de la page Tarifs et du contrat.
Les quatre offres
Chaque offre est décrite par son public et par ce qu'elle inclut.
Starter : 9 EUR par mois
Pour les TPE et les indépendants.
| Inclus | Détail |
|---|---|
| IA souveraine | pilote vos outils métier |
| Connecteurs | 3 à 5 outils métier |
| Tutoriels | auto-hébergement inclus |
| Conformité | conçue pour le RGPD et NIS2 |
| Support | par courriel |
| SLA | 99,5 % de disponibilité (objectif) |
Pro : 29,90 EUR par mois
Pour les PME. C'est l'offre mise en avant sur la page.
| Inclus | Détail |
|---|---|
| IA avancée | libellé de la page Tarifs : « raisonnement multi-étapes ». Les quatre moteurs de raisonnement du code (arbre de pensées, auto-cohérence, chaîne de vérification, MCTS) n'ont aucun appelant en production : ils sont en sommeil (Architecture) |
| Connecteurs | 10 outils métier et plus |
| Intégration | avec vos systèmes existants |
| Déploiement assisté | de vos outils, en option |
| Support | prioritaire |
| SLA | 99,9 % de disponibilité (objectif) |
| Formation | équipes, 2 jours |
Enterprise : 99,90 EUR par mois
Pour les ETI et les institutions.
| Inclus | Détail |
|---|---|
| Infrastructure | dédiée, connecteurs illimités |
| Déploiement | sur site (on-premise) ou cloud privé dans l'UE |
| Code source | complet et transférable |
| Support | prioritaire, avec un chargé de compte |
| SLA | 99,99 % de disponibilité (objectif) |
| Sécurité | test d'intrusion annuel et audit de conformité (programme cible : aucun exercice daté n'est encore publié) |
| Conseil | stratégique, 12 jours par an |
Souverain : sur devis
Pour les banques et l'État.
| Inclus | Détail |
|---|---|
| Infrastructure | dédiée et isolée |
| Cryptographie post-quantique | ML-KEM-768, disponible sur activation dédiée |
| Conformité | DORA, EUCS, Gaia-X : trajectoire et auto-évaluation, sans certification |
| Audit | de conformité permanent (libellé de la page Tarifs ; aucun audit de conformité indépendant n'est publié, voir NIS2) |
| Chargé de compte | dédié |
| SLA | 99,99 % et plan de continuité |
| Déploiement | isolé du réseau possible |
Les délais de réponse du support, par sévérité et par offre, sont dans la page SLA. Trois jeux de délais coexistent sur le site : la page Tarifs affiche 48 h, 4 h et 1 h (Starter, Pro, Enterprise) ; la page SLA donne, pour les incidents critiques, 48 h, 8 h et 2 h en heures ouvrées ; le tableau des conditions générales donne 48 h, 24 h et 4 h ouvrées. La page Tarifs parle en outre d'un support 24/7 pour Enterprise, que les deux autres textes ne confirment pas (heures ouvrées). Le contrat fait foi.
Capacités par offre
La page Tarifs publie aussi une table « Capacités par plan » : 20 lignes, chacune avec le plan minimum qui débloque la capacité. Elle compte six niveaux (Essentiel, Starter, Pro, Business, Enterprise, Souverain) ; la grille de prix n'en publie que quatre, et Essentiel et Business n'y ont pas de prix. Chaque palier supérieur conserve les capacités des précédents. Cette table est lue dans un registre unique du dépôt (docs/audit/capacites-par-plan.yaml) : ce livre ne la recopie pas, pour ne pas dériver. Les sections du menu visibles par plan sont dans Tableau de bord.
Les limites chiffrées de chaque offre (douze ressources, énumérées dans Limites) sont lues en base.
Essai gratuit
D'après les conditions générales de vente :
- 14 jours, sans engagement et sans carte bancaire ;
- accès à l'ensemble des fonctionnalités de l'offre Pro ;
- à la fin, vous choisissez une offre ; sans souscription, le compte est désactivé et les données sont conservées 30 jours avant suppression définitive.
État du code au 3 octobre 2026 : ce parcours n'est pas câblé. L'inscription publique crée une organisation au plan « free » (un espace de travail, un workflow, un utilisateur et 100 conversations par mois), sans souscription ni essai de l'offre Pro. En terminant ou en passant l'assistant d'accueil, l'application pose pour une organisation sans souscription active une souscription simulée perpétuelle au niveau « essentiel » : jamais facturée, sans les fonctions de l'offre Pro. Tant que le code ne l'applique pas, lisez l'essai comme une promesse des conditions générales, pas comme une fonction de l'application.
Paiement et facturation
| Sujet | Règle (conditions générales de vente) |
|---|---|
| Prix | hors taxes ; TVA selon la législation applicable |
| Engagement | mensuel ou annuel, avec 20 % de remise sur l'annuel |
| Moyens de paiement | carte bancaire, virement SEPA, iDEAL ou Bancontact, via Mollie (Pays-Bas) |
| Facturation | à la souscription, puis à chaque date anniversaire |
| Renouvellement | tacite ; vous pouvez le désactiver avant l'échéance |
| Retard de paiement | pénalités de 3 fois le taux d'intérêt légal et indemnité forfaitaire de 40 EUR |
Comment choisir
- Indépendant ou TPE. Starter couvre l'essentiel avec 3 à 5 outils.
- PME avec une équipe. Pro apporte 10 outils et plus, l'IA avancée annoncée par la page Tarifs (ses moteurs de raisonnement sont en sommeil, voir plus haut) et une formation.
- ETI ou institution. Enterprise apporte une infrastructure dédiée et le code source transférable.
- Banque ou administration. Demandez un devis Souverain (voir aussi Cas d'usage par secteur).
- Vous hésitez. Les conditions générales prévoient un essai de 14 jours avec les fonctions de l'offre Pro (voir « Essai gratuit » plus haut : le code ne l'applique pas encore). Commencez par la prise en main guidée.
Le tarif agence est sur devis.
Voir aussi
- SLA, support et niveaux de service — disponibilité, délais de support et pénalités, par offre.
- Limites et ce que la plateforme ne fait pas — les quotas que chaque offre plafonne.
- Comparatifs — ce que le prix achète face aux autres familles d'offres.
- Tableau de bord — les sections du menu que chaque plan rend visibles.
- Questions fréquentes — « Est-ce gratuit ? » et l'essai de l'offre Pro.
SLA, support et niveaux de service
Cette page reprend la page publique « Accord de niveau de service » du site. Le texte qui fait foi est le contrat et les conditions générales de vente. En cas d'écart, ils priment sur ce livre.
Un SLA est ici un objectif contractuel sur les environnements de production sous contrat. Ce n'est pas une garantie sans condition.
Disponibilité
| Offre | Disponibilité | Indisponibilité maximale par mois | Pénalité (notation de la page SLA) |
|---|---|---|---|
| Starter | 99,5 % | 3 h 39 min | 5 % avoir / 10 % indispo |
| Pro | 99,9 % | 43 min | 10 % avoir / 10 % indispo |
| Enterprise | 99,99 % | 4,3 min | 15 % avoir / 10 % indispo |
| Souverain | 99,99 % | 4,3 min | 20 % avoir / 10 % indispo |
La disponibilité est mesurée chaque mois par le système de supervision de la plateforme (voir Supervision). Les maintenances programmées, annoncées 72 heures à l'avance, sont exclues du calcul.
Les conditions générales plafonnent les pénalités à 30 % du montant mensuel de l'abonnement concerné. L'avoir est proportionnel au temps d'indisponibilité.
Temps de réponse du support
Les temps sont en heures ouvrées : du lundi au vendredi, de 9 h à 18 h (CET).
| Sévérité | Définition | Starter | Pro | Enterprise | Souverain |
|---|---|---|---|---|---|
| P1 critique | service indisponible | 48 h | 8 h | 2 h | 30 min |
| P2 majeur | fonctionnalité dégradée | 72 h | 24 h | 4 h | 1 h |
| P3 mineur | impact limité | 5 jours | 48 h | 8 h | 4 h |
| P4 information | question, demande | 10 jours | 5 jours | 24 h | 8 h |
L'offre Souverain relève d'un SLA personnalisé sous contrat. L'astreinte sur incidents P1 et P2 y est négociée au cas par cas.
L'assistant automatisé (niveau 1) est disponible à toute heure pour le premier tri. C'est un objectif : il suppose que l'API publique soit exposée.
Escalade
| Niveau | Délai | Interlocuteur |
|---|---|---|
| N1, support technique | immédiat | équipe support |
| N2, ingénierie | +2 h (P1), +8 h (P2) | ingénieur senior |
| N3, direction technique | +4 h (P1), +24 h (P2) | CTO |
| N4, direction générale | +8 h (P1) | CEO |
Communication des incidents
- La page de statut publique est
/status. - Un courriel automatique part pour les incidents P1 et P2.
- Un post-mortem est publié dans les 5 jours ouvrés suivant un incident P1 (voir Réponse aux incidents).
- Une violation de données est notifiée à la CNPD et aux clients sous 72 heures (article 33 du RGPD, article 23 de NIS2).
Reprise après incident
| Mesure | Cible | Remarque |
|---|---|---|
| RTO | moins de 2 h | temps de reprise après un incident majeur |
| RPO | moins de 24 h | perte de données maximale ; sauvegardes quotidiennes, sans restauration à un instant précis |
| Sauvegardes | quotidiennes | conservation de 30 jours, tests mensuels |
| Exercice de reprise | trimestriel | exercice complet |
Ces cibles sont un programme, pas un constat. Aucune restauration chronométrée n'est encore publiée : le premier exercice daté fera passer la cible en résultat.
Le RPO de 24 heures vient du rythme des sauvegardes (Sauvegarde et restauration). Une perte allant jusqu'à une journée de données est donc possible.
Ce que le SLA ne couvre pas
- Les services tiers que vous connectez (votre Odoo, votre n8n).
- La force majeure, la maintenance programmée et l'usage non conforme.
Voir aussi
- Tarification — le contenu de chaque offre.
- Réponse aux incidents — sévérités et phases de la procédure interne.
- Sauvegarde et restauration — le rythme des sauvegardes dont découle le RPO.
- Limites et ce que la plateforme ne fait pas — les quotas par offre, à côté de la disponibilité.
- Supervision — ce que la supervision mesure réellement aujourd'hui.
- Questions fréquentes — à qui écrire quand un workflow ne répond plus.
Comparatifs
Cette page compare Chatbotaurus à deux familles d'offres, sans nommer de tiers. Elle suit la page publique « Comparatif souverain » du site, état au 3 octobre 2026.
Deux règles :
- on compare des critères que le code ou la configuration de la plateforme permettent de vérifier ;
- quand une capacité d'une autre offre n'est pas documentée publiquement, on écrit « non documenté », pas « absent ».
Les deux familles
| Famille | Ce qu'elle fait | Où elle est hébergée |
|---|---|---|
| Offres SaaS hors UE | assistant d'IA généraliste, ou outil d'automatisation en ligne | chez un hébergeur sous juridiction hors UE |
| Outils d'automatisation auto-hébergés | orchestration de flux que vous installez vous-même | chez vous |
Chatbotaurus est une passerelle MCP hébergée dans l'UE (voir Architecture Chatbotaurus), qui relie un assistant à vos outils métier (voir Vue d'ensemble). Ce n'est ni un assistant généraliste, ni un simple outil de flux.
Verdict critère par critère
| Critère | Chatbotaurus | Offres SaaS hors UE |
|---|---|---|
| Hébergement | dans l'UE ; test et production sur des serveurs européens | hébergeur sous juridiction hors UE |
| Facturation | Mollie (Pays-Bas) | prestataire de paiement hors UE |
| Courriel transactionnel | ProtonMail (Suisse, décision d'adéquation RGPD) | messagerie transactionnelle hors UE |
| Voix | LiveKit, Kokoro et Speaches, auto-hébergés | voix et synthèse tierces hors UE |
| Authentification unique | Authentik, open source européen | SSO hébergé hors UE |
| Chiffrement | AES-256-GCM ; ML-KEM-768, Schnorr et Shamir en option | AES-GCM uniquement |
| Vérification des sorties | gardes de sortie en cours (routes et outils) | non documenté |
| AI Act, RGPD, NIS2 | documenté, avec Cedar et RLS (isolation en base) | non documenté |
| Connecteurs | 195 fiches YAML (3 octobre 2026) | non comparé |
| Prix agence | sur devis | tarif public non comparé |
« En option » veut dire désactivé par défaut. « En cours » veut dire prévu, pas livré.
Ce qui différencie la plateforme
- Routage déterministe. EntityRouter choisit le connecteur par des règles. Aucune mesure de latence du routage n'est publiée.
- Cryptographie en option. Quatre modules sont disponibles sur activation : ML-KEM-768 (canal hybride), compute-mode, preuves Schnorr, partage de secret de Shamir. Ils ne sont pas actifs par défaut (voir Glossaire, entrées PQC et Compute-mode).
- Voix européenne. La reconnaissance vocale (Voix et Canaux) couvre 7 langues.
- Catalogue de connecteurs. 195 fiches de connecteurs, dont le connecteur Odoo à 711 outils au registre.
Ce que la comparaison ne dit pas
- Elle ne mesure ni la qualité des réponses, ni la vitesse d'un autre produit.
- Elle ne compare pas les prix publics d'un tiers : ils changent et ne sont pas dans notre code.
- Elle ne vaut pas certification. La plateforme est conçue pour répondre au RGPD, à NIS2 et à l'AI Act, et ne détient aucune certification à ce jour.
Voir aussi
- Tarification : les offres et leurs prix.
- Limites : ce que la plateforme ne fait pas.
- Migration : passer d'un outil d'automatisation à Chatbotaurus.
- Conformité RGPD : le détail réglementaire.
- SLA, support et niveaux de service : disponibilité et support, par offre, avec leurs pénalités.
- Questions fréquentes : « Pourquoi pas une offre SaaS d'IA hors UE ? » en réponse courte.
- SSO Authentik : l'authentification unique européenne citée dans le verdict.
Limites et ce que la plateforme ne fait pas
Cette page dit ce que Chatbotaurus fait, ce qu'il ne fait pas, et les limites mesurées dans le code. Les valeurs sont celles par défaut au 3 octobre 2026. Un opérateur qui héberge sa propre instance peut en régler certaines par variable d'environnement.
Ce que la plateforme fait
| Domaine | Détail |
|---|---|
| Automatisation | workflows visuels qui appellent vos outils métier |
| Assistant | chat qui route vers vos connecteurs par des règles déterministes (EntityRouter) |
| IA locale | modèles exécutés par la plateforme, dans l'UE (EuroLLM 1,7B, repli ministral-3:3b) |
| Connecteurs | 195 fiches YAML ; 175 cartes de serveurs dans l'application, dont 30 prouvées opérationnelles ; 108 entrées au catalogue public, dont 15 disponibles |
| Odoo | 711 outils au registre |
Ce que la plateforme ne fait pas
- Ce n'est pas un chatbot généraliste. Le chat de support répond aux questions sur la plateforme. Il ne tient pas de conversation libre sans contexte métier.
- Ce n'est pas un ERP. Elle se connecte à Odoo ou à un autre outil ; les données métier restent dans cet outil.
- Ce n'est pas un hébergeur web. Elle n'héberge ni site, ni application, ni base de données générique.
- Ce n'est pas un stockage de fichiers. Les documents vivent dans les outils connectés.
- Elle n'exécute pas de code JavaScript dans un workflow. Les nœuds « fonction personnalisée » sont refusés à l'exécution (doctrine Rust uniquement ; voir Migration depuis d'autres outils).
- Elle ne route pas vers des services hors UE. À l'exécution, les identifiants de serveur de 25 services hors UE sont refusés, et seuls les serveurs de la liste autorisée sont appelés (voir Conception des connecteurs MCP).
Limites de débit
Le débit est limité par adresse IP. Au-delà, l'API répond 429 (format des erreurs : Documentation Swagger).
| Chemin | Limite par défaut |
|---|---|
/api/v1/* | 100 requêtes par seconde |
/api/v1/stats/route-events | 30 par minute |
/api/v1/prediction (chat public du site) | 20 par minute (la règle porte sur le préfixe : elle s'applique aussi à /api/v1/predictions) |
| autres chemins | 1 000 par minute |
Le chat public du site a un seau à part, parce qu'une réponse coûte 20 à 36 secondes de calcul au modèle local (mesure du 3 octobre 2026).
La connexion a ses propres limites, par compte et par adresse : au-delà d'un nombre d'échecs, l'adresse est bloquée pendant un temps réglable (voir Sécurité).
Taille des requêtes
| Limite | Valeur par défaut |
|---|---|
| Corps de requête | 2 Mio |
| Fichier téléversé | 25 Mio |
Au-delà, l'API répond 413.
Quotas par offre
Le code sait plafonner douze ressources : espaces de travail, workflows, utilisateurs, conversations par mois, connecteurs, serveurs MCP, connecteurs par gateway, appels d'API, stockage (en Go), minutes de voix, lignes d'appel concurrentes et enregistrements vectoriels. Les valeurs sont lues en base, par offre ; une valeur vide veut dire illimité.
- Un quota atteint répond
402avec le codeQUOTA_EXCEEDEDet un lien de montée en gamme. - Un quota que la plateforme n'a pas pu mesurer répond
503, jamais « illimité ».
La table des capacités par offre est sur la page Tarification.
Langues
| Élément | Langues |
|---|---|
| Interface | français et anglais (jeux complets de 1 610 clés) |
| Voix | 7 langues : français, anglais, allemand, espagnol, italien, néerlandais, portugais |
| Documentation | français |
Limites de l'IA
- Erreurs possibles. Un modèle peut se tromper. L'ancrage dans vos documents (RAG, voir Connaissances) réduit les erreurs, il ne les supprime pas. Vérifiez les informations critiques.
- Latence. Sur processeur seul, une réponse du modèle local (Fournisseurs de modèles) peut prendre de 20 à 36 secondes (chat public, mesure du 3 octobre 2026).
- Pas d'analyse d'images. Aucune analyse d'image ni de page scannée n'est annoncée. La recherche visuelle de pages est hors périmètre (spec 115).
- Pas de GPU. L'inférence se fait sur processeur. Aucune tâche de spec ne prévoit de GPU ; tout achat de GPU est soumis à validation (spec 68, DEC-68-004).
Prévu
| Évolution | Source |
|---|---|
| Kit de développement Python et JavaScript | spec 22, chantier 22.E (tâches 22.E.3 et 22.E.4) |
| Livraison du déploiement en un clic depuis le catalogue | spec 16, tâche P5.5 |
Ce qui n'a pas de tâche dans une spec n'est pas annoncé ici.
Voir aussi
- Tarification et offres — les capacités par plan que ces quotas chiffrent.
- SLA, support et niveaux de service — disponibilité et délais de support, par offre.
- Gestion des erreurs — le format des erreurs de l'API et le code de limite de débit.
- Questions fréquentes — « Mon workflow ne fonctionne pas » : lire un 429 ou un 402.
- Comparatifs — ce que la plateforme est, face aux autres familles d'offres.
Installation de Chatbotaurus
Ce guide installe Chatbotaurus en développement local. La pile est écrite en
Rust : forge-api (Axum, SeaORM) pour le backend et forge-ui (Dioxus 0.7)
pour l'interface. Pour aller plus vite, voir le démarrage rapide.
Ce guide ne couvre pas l'installation sur un serveur : pour la production (réseaux, volumes, unités Quadlet, mise à jour), voir Déploiement avec Podman.
Prérequis
| Outil | Version | Installation |
|---|---|---|
| Rust | 1.91 ou plus (rust-version du workspace) | rustup.rs |
dioxus-cli (dx) | 0.7 | cargo install dioxus-cli --locked |
| Cible wasm | rustup target add wasm32-unknown-unknown | |
| Git | 2.x | git-scm.com |
Podman et podman-compose | Podman 4.x ou plus | Podman Desktop |
Le chemin de référence du dépôt est Windows (PowerShell) : les lanceurs de
développement sont des scripts .ps1. Sous Linux ou macOS, utilisez les
commandes cargo et dx ci-dessous.
1. Cloner le dépôt
git clone <url-du-depot>
cd <dossier-du-depot>
2. Compiler le workspace
cargo build --workspace
Le workspace compte 20 crates (forge-core, forge-api, forge-ui,
forge-auth, forge-db, forge-mcp, forge-cli, forge-gateway,
forge-voice, forge-ops, forge-audit, forge-docs, entre autres). Une première
compilation à froid est longue.
3. Configurer l'environnement
cp .env.example .env
Les valeurs secrètes de .env.example sont des gabarits CHANGE_ME_... que
l'application refuse au démarrage : remplacez-les. Pour générer un secret :
openssl rand -hex 64.
Variables essentielles (chacune est lue par le code, voir
crates/forge-core/src/config.rs) :
# Backend
PORT=3000
DATABASE_URL=postgresql://<utilisateur>:<mot-de-passe>@localhost:5432/<base>
REDIS_URL=redis://localhost:6380
JWT_SECRET=<secret-genere>
AT_REST_ENCRYPTION_KEY=<secret-genere>
# Vecteurs et secrets
QDRANT_URL=http://localhost:6334
BAO_ADDR=http://localhost:8200
# Modèles (Ollama)
OLLAMA_BASE_URL=http://localhost:11434
# Courriel (second facteur par code)
SMTP_HOST=<serveur-smtp>
SMTP_PORT=587
SMTP_USER=<compte>
SMTP_PASSWORD=<mot-de-passe-applicatif>
SMTP_FROM=<adresse-expediteur>
# SSO OIDC (Authentik), facultatif
AUTHENTIK_SERVER_URL=http://localhost:9000
AUTHENTIK_CLIENT_ID=<identifiant-client>
AUTHENTIK_CLIENT_SECRET=<secret-client>
# Journalisation
RUST_LOG=info,forge_api=debug
Notes (la liste complète des variables est dans Variables d'environnement) :
FORCE_2FAvaut vrai par défaut : le démarrage exige alorsSMTP_HOST.AT_REST_ENCRYPTION_KEYchiffre les identifiants stockés ; sans elle, la clé dérive deJWT_SECRET..envdoit être lisible pardotenvy: une valeur contenant un espace doit être entre guillemets, sinon tout le fichier est ignoré.- Il n'existe pas de variables
CSRF_SECRETniTOTP_ISSUER.
4. Démarrer l'infrastructure
podman-compose -p chatbotaurus-vps1 -f podman-compose.yml up -d
Ce plan (détail dans Déploiement avec Podman)
démarre PostgreSQL, Valkey, Qdrant, Ollama, Authentik, OpenBao, les
services de voix et l'observabilité. Le second plan, mgaas-vps2
(podman-compose.vps2.yml), porte la passerelle et les serveurs mcp-*. Tout
service futur y est ajouté dans ce fichier, jamais lancé à la main.
Vérifiez que les conteneurs tournent avec podman ps (voir Gestion des conteneurs). Si l'un d'eux manque, voir Problèmes connus. Téléchargez aussi les modèles de dialogue avant la première conversation (section « Modèles » plus bas).
5. Initialiser la base
Les migrations s'appliquent aussi au démarrage de forge-api. Pour migrer
sans lancer le serveur :
cargo run -p forge-cli -- db migrate
6. Lancer en développement
Backend, port 3000
cargo run -p forge-api
Sous Windows, le lanceur de référence est scripts/dev/run-forge-api.ps1. Il
copie le binaire avant de le lancer (la compilation reste possible pendant que le
serveur tourne) et exige la variable ADMIN_PASSWORD (12 caractères ou plus) :
$env:ADMIN_PASSWORD = "<mot-de-passe-admin-12-caracteres-ou-plus>"
powershell -File scripts\dev\run-forge-api.ps1
scripts/dev/watch-forge-api.ps1 recompile et remplace le binaire à chaque
modification du backend.
Routes principales (contrat complet : Documentation Swagger) :
GET /api/v1/healthetGET /api/v1/healthz: état du service.GET /api/v1/readyz: base et Valkey joignables.POST /api/v1/predictionsetPOST /api/v1/predictions/stream: inférence.GET /api/v1/mcp/catalogue: catalogue des connecteurs (authentifié).POST /api/v1/mcp: transport MCP (authentifié).
Frontend, port 8080
dx serve --platform web --port 8080 --package forge-ui
Sous Windows : pwsh -File scripts\dev\run-dx.ps1. Ce lanceur utilise un
répertoire de build séparé (target-dx) pour que cargo build ne bloque pas
dx. dx recharge à chaud : ne le relancez pas pour un changement de code.
pwsh -File scripts\dev\run-dx.ps1 -Status donne l'état du serveur.
Ouvrez l'interface locale (http://localhost:8080).
Autres plateformes
forge-ui se compile pour les cibles de Dioxus (web, desktop, android,
ios, server, liveview), par exemple :
dx serve --platform desktop --package forge-ui
La cible web est la seule suivie en continu.
Ce livre
cargo run -p forge-docs # construit le livre et le copie dans forge-ui/public/docs
cargo run -p forge-docs -- --clean # purge book/ et public/docs/ avant de construire
dx serve sert ensuite le livre sous /docs/. L'option --serve (aperçu avec rechargement) n'existe pas : le binaire n'accepte que --src, --dst, --clean, --no-copy et --keep-html-urls.
Modèles
Le dialogue utilise EuroLLM 1.7B, avec ministral-3:3b en repli. Le modèle
d'embedding (384 dimensions) est chargé par fastembed dans le processus
forge-api : il ne passe pas par Ollama. Détails dans
Fournisseurs.
podman exec forge-ollama ollama pull cas/eurollm-1.7b-instruct-q8
podman exec forge-ollama ollama pull ministral-3:3b
Vérification
curl http://localhost:3000/api/v1/health
cargo test -p forge-replay
cargo test -p forge-api
La première commande rend un JSON avec "status":"ok" (le même que dans le démarrage rapide) ; les deux suivantes doivent se terminer sans test en échec.
La CI (voir Contribuer) exécute aussi cargo clippy --workspace -- -D warnings et
cargo fmt --check.
Prochaines étapes
Voir aussi
- Prise en main guidée : créer le compte et tester le chat une fois la pile lancée
- Déploiement avec Podman : passer du développement local aux unités Quadlet
- Problèmes connus : pannes fréquentes au démarrage : Podman, Ollama, OpenBao, Authentik
- Diagnostics et signalement : vérifier chaque service après le démarrage
Prise en main guidée
Ce guide va de la création du compte au premier workflow. Chaque étape dit à qui elle s'adresse.
Quel est votre profil ?
- Dirigeant ou décideur : étapes 1, 2 et 8.
- Responsable métier : étapes 1 à 4, 6 et 7.
- Développeur ou intégrateur : toutes les étapes, surtout 3, 5 et 6.
- Administrateur système : étapes 3, 5 et 8, puis déploiement Podman.
- Délégué à la protection des données : conformité RGPD.
Étape 1 : créer le compte
Tous les profils
- Ouvrez
/auth/signupsur votre instance (en local :http://localhost:8080). - Renseignez les champs demandés et validez.
- Connectez-vous sur
/auth/login. - Saisissez le code à usage unique reçu par courriel (
/auth/verify-otp). Le second facteur est actif par défaut (FORCE_2FA). - À la première connexion, l'assistant d'accueil s'ouvre (étape suivante). Si la connexion échoue, voir Questions fréquentes (« Comment me connecter ? »).
Les conditions générales prévoient un essai gratuit de 14 jours, sans engagement et sans carte bancaire. Il donne accès à l'ensemble des fonctionnalités de l'offre Pro. Sans souscription à la fin de l'essai, le compte est désactivé et les données sont conservées 30 jours avant suppression.
Étape 2 : l'assistant d'accueil
Tous les profils
À la première connexion, l'application ouvre /onboarding. L'assistant vous
fait choisir :
| Réglage | Choix |
|---|---|
| Langue | français, anglais, néerlandais ou allemand (seuls le français et l'anglais ont une interface complète ; le néerlandais et l'allemand n'ont que 26 clés traduites, le reste s'affiche en français) |
| Espace de travail | un nom et un secteur parmi les 16 secteurs du catalogue |
| Odoo | facultatif : l'adresse de votre serveur Odoo |
| Modèle de départ | Support client IA, Chat confidentiel, ou workflow personnalisé (canvas vierge) |
Terminer l'assistant vous amène au tableau de bord (/dashboard). Aujourd'hui, le serveur ne retient de l'assistant que le fait de l'avoir terminé ou passé : langue, secteur, adresse Odoo et modèle de départ ne sont pas enregistrés, et l'organisation reçoit le niveau « essentiel » si elle n'a aucune souscription (voir Tarification). Prenez
cinq minutes pour parcourir les pages principales :
| Page | Adresse | Pour qui |
|---|---|---|
| Tableau de bord | /dashboard | Tous |
| Chat | /chat | Tous |
| Orchestrateur | /orchestrator | Tous |
| Workflows | /workflows | Métier, développeur |
| Serveurs MCP | /mcp-servers | Développeur, admin |
| Identifiants | /credentials | Développeur, admin |
| Intégration au site web | /embeds | Développeur |
| Documents | /documents | Métier, développeur |
| Facturation | /billing | Dirigeant, admin |
| Paramètres | /settings | Admin, dirigeant |
Étape 3 : enregistrer vos identifiants
Développeur, administrateur système, responsable métier
Les identifiants permettent à Chatbotaurus de se connecter à vos outils (la page est décrite dans Sécurité et identifiants).
- Ouvrez
/credentials. Dans le menu, la page est dans la section Sécurité, visible à partir du plan Business ; sur un plan inférieur, ouvrez-la par son adresse (voir la section Navigation du Tableau de bord). - Cliquez sur la carte du service voulu (Odoo, n8n, Matomo, Nextcloud, entre autres).
- Remplissez le formulaire : adresse du serveur, identifiant, clé d'API ou mot de passe applicatif selon le service.
- Enregistrez.
Les identifiants sont chiffrés au repos en base (clé AT_REST_ENCRYPTION_KEY).
Ils ne sont jamais réaffichés en clair : en modification, un champ secret
laissé vide ou inchangé conserve la valeur enregistrée. Voir aussi
OpenBao et gestion des secrets pour les
secrets d'infrastructure.
Pour Odoo, le parcours complet (les quatre champs à renseigner, puis un premier appel d'outil) est dans Connecter Odoo à la passerelle MCP.
Étape 4 : tester le chat
Tous les profils
- Ouvrez
/chat. - Posez une question simple : « Bonjour, que sais-tu faire ? »
- Observez la réponse. La page est décrite dans Chat.
Le chat parle à un workflow déployé : si le sélecteur de workflow est vide, créez d'abord un workflow (étape 6), puis revenez à cette étape.
Si un identifiant Odoo est enregistré, posez une question métier, par exemple
« Combien de contacts dans le CRM ? ». Le registre d'outils Odoo compte 711
outils (mesure du 3 octobre 2026, odoo_tools_registry.rs).
Le modèle de dialogue par défaut est EuroLLM 1.7B, exécuté localement via Ollama, avec
ministral-3:3ben repli. Il tourne sur le processeur : les réponses longues prennent quelques secondes. Pour utiliser un autre fournisseur, voir Fournisseurs.
Étape 5 : parcourir le catalogue de serveurs MCP
Développeur, administrateur système
Ouvrez /mcp-servers. Le catalogue se filtre par secteur et par catégorie (voir
MCP et Orchestrateur). Le
catalogue public compte 108 entrées dont 15 marquées « disponibles »
(mesure du 3 octobre 2026) ; la page de l'application en liste 175.
Le déploiement en un clic n'est pas encore câblé. Les actions déployer, démarrer, arrêter et redémarrer un serveur du catalogue répondent
503 FEATURE_PENDINGtant que l'adaptateur Podman n'est pas branché surforge-api. C'est prévu (spec 16, tâche P5.5, route prévueops/deploy). En attendant, un serveur se lance par le plan composemgaas-vps2(podman-compose.vps2.yml). Consulter le catalogue est possible dès maintenant (voir parcourir le catalogue de services).
Pour les dirigeants : cette étape relève de votre équipe technique.
Étape 6 : créer votre premier workflow
Responsable métier, développeur
Un workflow est une suite d'actions que vous assemblez sur un canvas (voir Workflows).
- Ouvrez
/workflowset créez un nouveau workflow. - Placez un nœud d'entrée (MCP Start) sur le canvas.
- Ajoutez un nœud agent.
- Ajoutez un nœud de sortie (MCP End).
- Reliez les nœuds en tirant des lignes.
- Configurez l'agent : modèle et consigne système.
- Enregistrez, puis testez depuis
/chat.
Un nœud est une brique du workflow. Un agent est un nœud qui s'appuie sur le modèle. Un connecteur est un nœud qui parle à un outil externe (Odoo, n8n, entre autres). Voir le glossaire.
Étape 7 : intégrer le chat à votre site
Développeur, responsable métier
- Ouvrez
/embeds: la page liste vos workflows. - Choisissez celui à publier ; le générateur d'intégration s'ouvre.
- Réglez l'apparence (couleurs, message d'accueil).
- Copiez le code généré et collez-le dans votre site.
Le code est un extrait <script> qui s'ajoute à n'importe quel site. Voir
aussi Voix et Canaux pour la page Marque (widget).
Étape 8 : passer à une offre payante
Dirigeant, administrateur
Les prix publics sont sur la page /pricing. Tous sont HT et mensuels.
| Offre | Prix | Pour qui |
|---|---|---|
| Starter | 9 EUR/mois | TPE, indépendants : connecteurs pour 3 à 5 outils, RGPD et NIS2 |
| Pro | 29,90 EUR/mois | PME : connecteurs pour 10 outils et plus, IA avancée (moteurs de raisonnement en sommeil, voir Tarification), support prioritaire |
| Enterprise | 99,90 EUR/mois | ETI et institutions : infrastructure dédiée, code source transférable, support prioritaire avec gestionnaire de compte |
| Souverain | sur devis | Banques, État : infrastructure isolée, cryptographie post-quantique sur activation dédiée |
Le détail des offres et des capacités par plan est sur /pricing et dans la
page Tarification, les délais de support dans
SLA. La gestion de
l'abonnement est sur /billing (voir Paramètres).
Liste de contrôle
| Étape | Fait ? |
|---|---|
| Compte créé, code reçu par courriel | |
| Assistant d'accueil terminé | |
| Au moins un identifiant enregistré | |
| Chat testé | |
| Premier workflow créé ou testé | |
Équipe ajoutée (page /users, menu Gestion à partir du plan Business ; voir Paramètres) | |
| Intégration au site (facultatif) |
Et ensuite
- Guide utilisateur
- Cas d'usage par secteur
- FAQ
- Une question : la page
/contactde votre instance
Voir aussi
- Fournisseurs de modèles : changer de modèle ou brancher un fournisseur européen
- Utiliser les connecteurs MCP : où vivent les fiches et comment le catalogue est lu
- Glossaire : nœud, agent, connecteur, gateway : les termes définis
- Limites et ce que la plateforme ne fait pas : quotas par offre et limites de débit
Fournisseurs de modèles
Chatbotaurus répond par défaut avec un modèle souverain européen exécuté localement. Un fournisseur supplémentaire se branche par un identifiant (voir Sécurité et identifiants) enregistré dans l'application, pas par une variable d'environnement globale.
Les trois modèles souverains
La liste est dans crates/forge-core/src/model_governance.rs
(SOVEREIGN_LOCAL_MODELS). C'est l'unique source des défauts du code.
| Rôle | Modèle | Où il tourne |
|---|---|---|
| Dialogue | cas/eurollm-1.7b-instruct-q8 (EuroLLM 1.7B, environ 1,8 Go) | Ollama |
| Repli | ministral-3:3b | Ollama |
| Embedding | paraphrase-multilingual-MiniLM-L12-v2, 384 dimensions | fastembed, dans le processus forge-api |
Télécharger les deux modèles de dialogue (le conteneur Ollama vient du plan décrit dans Déploiement avec Podman) :
podman exec forge-ollama ollama pull cas/eurollm-1.7b-instruct-q8
podman exec forge-ollama ollama pull ministral-3:3b
Le modèle d'embedding n'est pas un modèle Ollama : ollama pull ne le
concerne pas. fastembed le télécharge dans son cache au premier usage (le
pipeline d'indexation est décrit dans Connaissances). La
collection Qdrant du pipeline wiki est donc créée en 384 dimensions.
Ollama local (par défaut)
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=ministral-3:3b
OLLAMA_EMBEDDING_MODEL=paraphrase-multilingual-MiniLM-L12-v2
Valeurs par défaut (crates/forge-core/src/config.rs) : OLLAMA_BASE_URL
vaut http://localhost:11434 et OLLAMA_MODEL prend le modèle de repli de la
liste souveraine. Le délai d'appel (OLLAMA_TIMEOUT_SECS) vaut 120 s.
Ajouter un autre fournisseur
La résolution du modèle de chat d'une organisation suit cet ordre
(crates/forge-api/src/routes/llm_provider.rs) :
- le dernier identifiant de type IA enregistré par l'organisation ;
- l'ancienne configuration
/llm-provider(compatibilité) ; - EuroLLM en local.
Pour ajouter un fournisseur :
- Ouvrez
/credentials(section Sécurité du menu à partir du plan Business, sinon par son adresse) et choisissez la catégorie des modèles de langage. - Choisissez la famille (par exemple
mistralApipour Mistral AI, France, ouollamapour votre propre serveur Ollama). Le formulaire préremplit l'adresse et le modèle. - Pour un serveur auto-hébergé, indiquez son adresse de base. Pour un service en ligne, saisissez la clé d'API.
- Enregistrez. La carte active est signalée dans la liste.
- Vérifiez dans le chat : si le fournisseur est refusé, le chat répond avec EuroLLM (voir « Fournisseurs refusés » plus bas).
La clé n'est stockée qu'une fois, chiffrée en base. Le fournisseur choisi n'est utilisé que si son point d'accès est local ou européen (voir « Fournisseurs refusés »). Les variables
LLM_PROVIDER et MISTRAL_API_KEY du fichier .env.example ne sont pas lues
par le backend pour choisir le fournisseur de chat : n'en dépendez pas.
Les métadonnées du code (llm_provider_metadata.rs) décrivent Ollama et
Mistral AI comme fournisseurs européens. Des fiches ollama et localai
existent dans connectors/.
Fournisseurs refusés
Avant chaque appel à un modèle, le code applique deux contrôles
(assert_llm_sovereign, crates/forge-core/src/agent/memory/sovereignty.rs) :
- le nom du modèle ne doit contenir aucun de ces huit noms : OpenAI,
Anthropic, Azure, Google, AWS, Bedrock, Cohere, Groq
(
US_PROVIDERS) ; - l'adresse du point d'accès doit être locale (boucle locale, réseau privé),
se terminer par
.eu, ou être celle d'un fournisseur européen connu (Ollama, Mistral AI et un hébergeur européen référencé dans le code).
Un appel qui échoue l'un des deux contrôles est refusé avant l'envoi du
message. Quand le fournisseur choisi par l'organisation est refusé, le
chat
bascule sur EuroLLM. La liste de dix noms LLM_PROVIDER_US_BLOCKLIST
(avec Together et Replicate) existe dans le code mais aucun chemin de
production ne l'appelle.
La liste des familles proposées dans
/credentialsévolue : certaines familles passent par un agrégateur ou un service hors UE. Le formulaire affiche l'origine de chaque famille. Une famille dont le point d'accès n'est ni local ni européen s'enregistre, mais ses appels sont refusés par le contrôle ci-dessus.
Voir aussi
- Installation : compiler et lancer la pile en local
- Variables d'environnement : chaque variable lue par le code
- Conformité RGPD : données personnelles, hébergement et sous-traitants dans l'UE
- Chat : quel modèle répond, et le repli quand un fournisseur est refusé
- Conception des connecteurs MCP : le contrôle de conformité UE appliqué aux connecteurs
- Questions fréquentes : « Quels modèles d'IA sont utilisés ? » en une réponse courte
Utiliser les connecteurs MCP
Chatbotaurus utilise le Model Context Protocol (MCP) pour parler à des services externes. Un connecteur expose des outils que l'agent peut appeler.
Où vivent les connecteurs
| Emplacement | Contenu |
|---|---|
connectors/*.yaml (racine du dépôt) | Fiches déclaratives : adresse de base, authentification, outils. Lues par crates/forge-mcp/src/connector/yaml_loader.rs. |
crates/forge-mcp/src/connector/ | Code Rust commun : client HTTP, import OpenAPI, client XML-RPC Odoo, client CLI calrs. |
Le dossier connectors/ compte 195 fiches YAML (mesure du 3 octobre 2026).
Ajouter un outil HTTP se fait en ajoutant une fiche, sans écrire de Rust. Voir
Créer votre premier connecteur MCP.
Exemples de fiches présentes
Chaque nom ci-dessous correspond à un fichier de connectors/.
| Domaine | Fiches |
|---|---|
| ERP, gestion | odoo, dolibarr, akaunting, invoiceninja |
| Automatisation, rendez-vous | n8n, calrs |
| Analytique, recherche | matomo, typesense, searxng |
| Communication, support | rocketchat, element, freescout, discourse, listmonk |
| Fichiers, code | nextcloud, forgejo |
| Identité, secrets | authentik, openbao |
| IA, vecteurs, voix | ollama, localai, qdrant, kokoro-tts |
| Observabilité | grafana, victoriametrics, victorialogs |
| Données publiques UE | cordis, eurostat, europeana, eurlex, enisa, europe-pmc, data-europa |
Pour l'ERP, odoo porte un registre de 711 outils (mesure du
3 octobre 2026) et un client XML-RPC. Voir
Connecter Odoo à la passerelle MCP et la
vue d'ensemble des connecteurs.
Le nombre de fiches n'est pas le nombre de services prouvés. Le catalogue public compte 108 entrées, dont 96 avec une fiche et 15 marquées « disponibles » (mesure du 3 octobre 2026).
Identifiants
Un connecteur lit ses secrets au moment de la requête, depuis les identifiants
enregistrés sur /credentials (chiffrés en base, voir
Sécurité et identifiants). Ne placez jamais une clé
dans une fiche YAML : une fiche référence une variable, par exemple
${NOM_DE_VARIABLE}.
Transport MCP
Le backend expose le transport HTTP streamable (voir
Architecture Chatbotaurus). La version de protocole
courante du code est 2025-03-26. La route est authentifiée :
POST /api/v1/mcp -> JSON-RPC 2.0 (initialize, tools/list, tools/call)
GET /api/v1/mcp -> flux SSE de notifications
DELETE /api/v1/mcp -> fermer la session
La session est portée par l'en-tête Mcp-Session-Id. Le transport est actif
si MCP_ENABLED et API_ENABLED le sont. Voir Routes MCP.
Consulter le catalogue par l'API
Le jeton s'obtient par la connexion : voir Authentification.
# Connecteurs chargés par l'instance (jeton requis)
curl -H "Authorization: Bearer <jeton>" \
http://localhost:3000/api/v1/mcp/catalogue
# Une entrée
curl -H "Authorization: Bearer <jeton>" \
http://localhost:3000/api/v1/mcp/catalogue/<identifiant>
La famille /api/v1/mcp-gateway/* (par exemple /mcp-gateway/servers)
porte la passerelle (Routes des gateways et de la prédiction). Le
catalogue d'applications métier (Routes du catalogue métier) est sous
/api/v1/mcp/catalog-business.
Déploiement : pas encore. Les routes
deploy,start,stop,restart,securityetsecretsde/api/v1/mcp/catalog-business/{id}/...répondent503 FEATURE_PENDINGavec un en-têteRetry-Afterà un administrateur (un autre rôle reçoit403, saufsecurityqui répond503à tout rôle). Elles attendent l'adaptateur Podman deforge-api(spec 16, tâche P5.5). Il n'existe pas de route/mcp/gateways/<nom>/deploy. Pour lancer un serveur aujourd'hui, utilisez le plan composemgaas-vps2.
Voir aussi
- Parcourir le catalogue de services et préparer un déploiement : ce qui marche et ce qui est en sommeil
- Conception des connecteurs MCP : manifestes YAML, connecteurs natifs et contrôle de conformité UE
- Connecteur Odoo : le connecteur qui porte le registre d'outils nommés et génériques
- MCP et Orchestrateur : les catalogues de serveurs tels que l'application les montre
- Déploiement avec Podman : lancer le plan client qui porte les serveurs
- Fichiers de configuration : la structure des manifestes de connecteurs
Tableau de bord
Le tableau de bord (/dashboard) est la première page après la connexion. Il résume l'activité de votre espace de travail : vos workflows, vos exécutions, vos premiers pas.
Se connecter
Toute page de l'application exige une session. Sans session, vous êtes renvoyé vers l'écran de connexion (/auth/login).
L'écran de connexion offre deux voies :
- courriel et mot de passe, suivis d'un second facteur quand il est actif pour votre compte : code reçu par courriel, ou code de votre application d'authentification (TOTP, voir Paramètres) ;
- le bouton « Authentik SSO » (connexion unique).
Voir SSO Authentik pour la configuration côté administrateur.
Ce que vous voyez, de haut en bas
| Bloc | Contenu |
|---|---|
| Titre et saisie de l'Orchestrateur | Une zone de saisie. Envoyer un texte ouvre /orchestrator. |
| Activité | Exécutions réussies, en échec, en cours. Workflows déployés et brouillons. Liste des exécutions récentes. Lien « Voir tout » vers /executions. |
| Pour démarrer | Liste de quatre étapes : créer un workflow, ajouter un identifiant, déployer une gateway, importer un document. Elle s'affiche tant que l'espace n'est pas configuré. |
| À traiter | Remplace la liste précédente une fois l'espace configuré : exécutions en échec, brouillons non déployés. Affiche « Tout est en ordre » sinon. |
| Leads / CRM et Voix / Appels | Deux cartes de synthèse : prospects de la semaine, gagnés, conversion ; appels terminés, abandonnés, durée moyenne. |
| Quatre compteurs | Workflows, Identifiants, Documents, Gateway Projet UE. Chaque carte renvoie vers sa page. |
| Actions rapides | Nouveau workflow, Gateway Projet UE, Gateways Business. |
| Parcours patient - Centre de rééducation | Cinq étapes cliquables : Orchestrateur, Médiathèque, Chat, Marque (image de marque et déploiement), Cockpit clinique. |
| Modèles de workflow | Une grille de modèles prêts à déployer. |
| Workflows récents | Les derniers workflows, avec le badge Déployé ou Brouillon. |
Un compteur ou une carte qui ne peut pas être lu affiche zéro ou un tiret : une seule lecture en échec ne vide pas toute la page.
Navigation
La barre latérale et la barre haute affichent le même modèle : une catégorie par section, puis les pages de la section. Les sections visibles dépendent de votre plan.
| Plan | Sections visibles (hors Paramètres) |
|---|---|
| Essentiel | Principal, Écosystème MCP (3 pages), Déployer, Connaissances (2 pages), Analytique (2 pages) |
| Starter | Principal, Écosystème MCP (3 pages), Connaissances, Déployer (script d'intégration), Analytique (2 pages) |
| Pro | Starter, plus Canaux (marque, intégrations, campagnes) et Analytique complète |
| Business | Pro, plus voix et numéros, Sécurité, Gestion |
| Enterprise, Souverain | Tout, y compris Agence et Évaluations |
Essentiel et Business sont des niveaux de la table des capacités par plan ; la page Tarifs ne publie pas de prix pour eux (voir Tarification). La section Paramètres est visible à tous les plans. Les pages d'administration /admin* n'apparaissent qu'aux comptes administrateur. Un plan inférieur peut encore ouvrir une page par son adresse : la limite porte sur le menu, et l'API applique ses propres refus (voir Limites et ce que la plateforme ne fait pas).
Source de ce tableau : docs/audit/nav-par-tier.yaml.
Voir aussi
- Chat : parler à un workflow déployé
- Workflows : l'éditeur, la palette de nœuds, les exécutions
- Paramètres : réglages, facturation, compte et gestion des utilisateurs
- MCP et Orchestrateur : la saisie du tableau de bord ouvre l'Orchestrateur
- Analytique : les cartes Leads et Appels renvoient à ces pages
- Prise en main guidée : les étapes « Pour démarrer », une à une
- Tarification et offres : les capacités par plan derrière les sections visibles
Workflows
Un workflow est une suite de nœuds qui relie un message à des actions : appeler un outil, un modèle, un autre service. Les pages ci-dessous servent à les créer, les déployer et suivre leurs exécutions.
Les pages
| Page | Adresse | Rôle |
|---|---|---|
| Workflows | /workflows | Liste de vos workflows (vue cartes ou liste) |
| Éditeur | /workflows/<id> | Édition d'un workflow |
| Versioning | /workflow-versions | État de déploiement de chaque workflow |
| Exécutions | /executions | Journal des exécutions |
La page Exécutions n'a pas d'entrée dans la barre latérale. On l'ouvre depuis le lien « Voir tout » du tableau de bord, ou par son adresse.
Liste des workflows
Le bouton « Nouveau workflow » en crée un et ouvre l'éditeur. Le menu de chaque carte propose : modifier, dupliquer, générer le script d'intégration (voir l'étape 7, « intégrer le chat à votre site », de la prise en main guidée), supprimer.
Éditeur
L'éditeur a trois zones :
- à gauche, la palette de nœuds, classée par catégorie ;
- au centre, le canevas où l'on dépose et relie les nœuds ;
- à droite, le panneau de propriétés du nœud choisi.
Vous pouvez enregistrer, déployer ou mettre en pause, supprimer, et annuler ou refaire (Ctrl+Z, Ctrl+Y). Un nœud choisi a une adresse partageable : /workflows/<id>/nodes/<nœud>.
Palette de nœuds
La palette compte 9 catégories et 74 nœuds. Un nœud grisé ne peut pas être déposé dans un workflow : il sert de brique interne à l'agent.
| Catégorie | Exemples |
|---|---|
| MCP Gateway Flows (21) | MCP Start, MCP End, MCP Gateway Agentic Workflow, MCP LLM, MCP Router, MCP Condition, MCP Loop, MCP Parallel, MCP Aggregator, MCP Fallback, MCP Retry, MCP Rate Limiter, MCP Cache, MCP Approval, MCP Audit Log |
| Formation (12) | Parcours pédagogique, Vidéo, Image, Note audio, Quiz, Formulaire, Leçon, Carte, Carrousel, Rendez-vous |
| MCP Connectors EU (19) | Un nœud par service (Odoo, n8n, Matomo, Nextcloud, entre autres) |
| MCP Security (6) | Chiffrement, Sécurité FHE, Post-quantique, ZKP, SMPC, Audit SIEM |
| MCP Storage EU (5), MCP AI EU (3), MCP Data Processing (2), MCP Utilities (2) | Briques internes de l'agent |
| Playbook (4) | Say, Ask, Goto, Handoff |
Deux précisions :
- le nœud « MCP FHE Processor » et le nœud « MCP FHE Security » ne font pas de chiffrement homomorphe. Ils déchiffrent, calculent et rechiffrent en AES-256-GCM côté serveur. Le catalogue le dit lui-même ;
- le nœud « MCP LLM » appelle un modèle de langage local (voir Fournisseurs de modèles). Son modèle par défaut est
ministral-3:3b, modifiable dans ses propriétés. Le fournisseur refuse un modèle hors du périmètre souverain (voir Chat pour le modèle du chat).
Versioning
La page liste vos workflows avec leur type, leur état (déployé ou brouillon) et leurs dates de création et de mise à jour. Elle n'enregistre pas d'historique de versions et n'a pas de numéro de version : le serveur n'en garde aucun.
Exécutions
Le tableau a cinq colonnes : Statut, Gateway, Entrée, Durée, Date. Une recherche filtre la liste. Ouvrir une ligne montre le déroulé du graphe : pour chaque nœud, OK ou ECHEC, son nom et l'erreur éventuelle.
Connexion aux services
Les workflows appellent vos services par les connecteurs MCP (identifiants : Sécurité et identifiants). Le dépôt décrit 195 connecteurs (fichiers connectors/*.yaml). Tous ne sont pas déployés : un connecteur n'est dit « opérationnel » que s'il a été prouvé avec des données réelles. Voir la liste des connecteurs.
Pages annoncées, non disponibles
Les adresses /workflows/folders, /workflows/tags, /workflows/notes et /workflows/sharing affichent « Fonctionnalité v2.1 » : le dossier, l'étiquette, la note et le partage par workflow sont planifiés pour la v2.1. D'ici là, les droits se règlent au niveau de l'espace de travail (voir Paramètres).
Voir aussi
- MCP et Orchestrateur : l'assistant qui construit vos workflows et les catalogues de serveurs MCP
- Analytique : l'usage de l'agent et la qualité de ses réponses, en chiffres
- Chat : tester un workflow déployé en lui parlant
- Migration depuis d'autres outils : l'équivalent de chaque concept d'un autre outil en nœud MCP
- Routes des gateways et de la prédiction : un workflow est une gateway pour l'API
- Questions fréquentes : « Mon workflow ne fonctionne pas », l'ordre des vérifications
Chat
La page Chat (/chat) est l'endroit où vous parlez à un de vos workflows déployés. Il faut d'abord en avoir créé un : voir l'étape 6 de la prise en main guidée.
Une page, trois onglets
La page /chat porte trois onglets. Chacun a aussi sa propre adresse.
| Onglet | Adresse directe | Contenu |
|---|---|---|
| Gateway Chat | /chat | La conversation, avec la liste de vos conversations à gauche |
| Historique | /chat-history | Les conversations passées |
| Messages Proactifs | /proactive-messages | Les règles de messages proposés au visiteur |
Gateway Chat
- Choix du workflow : un sélecteur en haut choisit le workflow qui répond.
- Liste des conversations : nouvelle conversation, recherche, favoris, dossiers, renommer, dupliquer, supprimer. Les favoris, dossiers et noms sont gardés dans votre navigateur.
- Saisie : texte, ou micro pour dicter (la reconnaissance vocale est décrite dans Voix et Canaux).
- Outils utilisés : quand l'agent appelle un outil, la réponse l'indique.
- Export : une conversation s'exporte en JSON ou en Markdown.
- Serveurs MCP : le menu du sélecteur propose six serveurs à activer ou non (Odoo, n8n, Matomo, un agenda, CryptPad, Jitsi).
Comment une réponse est produite
- Le routeur déterministe (EntityRouter) analyse votre message. Quand sa confiance atteint 0,80 ou plus, il appelle l'outil lui-même et formate le résultat. Aucun modèle de langage ne décide dans ce cas.
- Sinon, la question passe au modèle de langage local.
- Un outil irréversible ne s'exécute pas seul : le chat crée une demande d'approbation, qu'un humain décide ensuite.
Quel modèle
| Rôle | Modèle | Remarque |
|---|---|---|
| Défaut | EuroLLM 1.7B (q8), via Ollama, en local | Modèle européen. |
| Secours | ministral-3:3b (Mistral AI, France), en local | Prend le relais si le défaut échoue. L'administrateur peut le changer. |
| Choix du client | Un identifiant LLM enregistré dans votre espace | Il a la priorité sur le défaut, à une condition : son point d'accès doit être local ou européen (adresse locale, nom de domaine en .eu, ou fournisseur européen connu). Sinon l'appel est refusé avant l'envoi du message et le chat bascule sur EuroLLM. L'événement llm_provider_non_eu est tout de même inscrit au journal d'audit. |
Le choix des outils, lui, reste celui du routeur déterministe. Pour brancher un autre fournisseur, voir Fournisseurs de modèles.
Contrôles de réponse
Un moteur anti-hallucination existe (validation multicouche, recherche de sources). Il démarre seulement si la recherche vectorielle (Connaissances) et Ollama sont disponibles. Le moteur de vérification factuelle « GroundingEngine » est dans le code mais n'est pas branché : /mgaas/engines le déclare « dormant ». N'attendez donc pas une vérification factuelle automatique de chaque réponse.
Historique
La page liste vos conversations et leurs messages. Elle sert aussi de page seule (/chat-history).
Messages proactifs
La page permet de créer, activer, modifier et supprimer des règles. Une règle porte un déclencheur (temps passé sur la page, profondeur de défilement, intention de sortie, inactivité, page visitée, horaire), une audience et un workflow. Le déclenchement côté visiteur n'est pas couvert par ce chapitre.
Voir aussi
- MCP et Orchestrateur : l'assistant qui construit vos workflows et les catalogues de serveurs MCP
- Voix et Canaux : la reconnaissance vocale, le widget et les canaux de diffusion
- Workflows : le workflow choisi dans le sélecteur se construit ici
- Analytique : l'historique des conversations et les messages proactifs en chiffres
- Routes des gateways et de la prédiction : la même conversation, par l'API
- Limites et ce que la plateforme ne fait pas : latence du modèle local et limites de débit du chat
- Questions fréquentes : « Mon workflow ne fonctionne pas », l'ordre des vérifications
Connaissances
La section Connaissances regroupe ce que votre agent peut retrouver : collections de documents, fichiers, outils personnalisés, wiki. Le principe du RAG est défini dans le Glossaire. Aujourd'hui, l'application affiche et gère les collections ; l'ajout de documents depuis l'interface n'est pas encore branché (détail plus bas).
Les pages
| Page | Adresse | Rôle | État |
|---|---|---|---|
| Collections | /document-stores | Vos bases de connaissances | Création, modification, duplication, suppression en service |
| Outils | /tools | Outils personnalisés de l'agent | Création, modification, suppression en service |
| Vecteurs | /vectors | Collections de la base vectorielle | Réservée à l'opérateur de la plateforme (voir plus bas) |
| Fichiers | /files | Fichiers de votre espace | Liste et suppression (l'envoi est prévu, voir plus bas) |
| Intents & NLU | /intents | Intentions et entités | Page présente (non détaillée ici) |
| Wiki LLM | /wiki | État de la synchronisation du wiki | Voir plus bas |
| Médiathèque | /mediatheque | Médias par discipline | Page présente (non détaillée ici) |
| Formulaire pré-chat | /pre-start | Formulaire avant la conversation | Page présente (non détaillée ici) |
Les plans Essentiel n'affichent que Collections et Fichiers. Les autres pages apparaissent à partir du plan Starter (voir Tarification et offres).
Collections
La page liste vos collections avec quatre compteurs (collections, documents, morceaux, synchronisées). Une collection se crée, se modifie, se duplique, se supprime. Supprimer demande de retaper le nom.
Ouvrir une collection mène à /document-stores/<id>, une page à quatre onglets : Documents, Configuration, Preview, Vector Store. Cette page de détail est aujourd'hui une coquille avec des données d'exemple. Le bouton d'ajout de document propose cinq onglets (Fichier, URL, Sitemap, Table, Configuration), mais son envoi n'est pas branché.
Ce que l'API ne fait pas encore
Ces appels de l'API (Routes des ressources) répondent 503 FEATURE_PENDING : traiter un document (loader/process), l'envoyer par URL (loader/upload-url), l'envoyer en table (loader/upload-table), supprimer ou remplacer un document d'une collection.
Formats de fichier
| Format | État |
|---|---|
| Texte, Markdown, CSV, JSON, HTML, journaux | La fonction d'analyse du code (kb_parse.rs) les lit comme du texte |
| PDF, DOCX, XLSX, PPTX | La même fonction les refuse explicitement : l'analyse de ces formats n'est pas branchée |
| Pages web, sitemaps | Routes d'exploration présentes (scrape/page, scrape/sitemap, crawl) |
Aucune route de l'API n'appelle encore cette fonction d'analyse : l'ingestion actuelle reçoit du texte déjà extrait (/rag/ingest). L'analyse des PDF et des documents Office est prévue : spec 115, tâches T-115-22 (admission des fichiers), T-115-23 (envoi), T-115-25 (branchement de l'analyse). Le crate d'extraction documentaire est en cours de livraison (T-115-31) ; il n'est pas branché sur l'API.
En attendant, l'API sait indexer un texte déjà extrait : voir « Indexer un texte » dans Routes des ressources.
Pipeline d'indexation
- Le texte est extrait.
- Il est découpé en morceaux. Le service de découpage intelligent propose cinq techniques, dont certaines appellent le modèle local
ministral-3:3b. - Chaque morceau reçoit un vecteur de 384 dimensions, calculé en local par
paraphrase-multilingual-MiniLM-L12-v2(fastembed, licence Apache-2.0 ; voir Fournisseurs de modèles). - Les vecteurs sont rangés dans Qdrant (variables dans Variables d'environnement), dans des collections préfixées par l'identifiant de l'organisation. Ce cloisonnement est décrit dans Architecture Chatbotaurus.
Le suivi de progression en temps réel d'une ingestion n'est pas couvert par la page de détail actuelle.
Vecteurs
La liste des collections Qdrant est une vue de plateforme : elle exige une élévation d'opérateur et répond 403 sinon. La page décode un tableau alors que l'API rend un objet (engine, collections, total_vectors) : la liste ne s'affiche pas correctement. Les routes de lecture des enregistrements, de recherche et de synchronisation par collection (/vectors/<id>/...) n'existent pas dans l'API. Cette page est donc, pour un client, une page annoncée et non utilisable.
Fichiers
La page liste les fichiers de l'espace et permet d'en supprimer. L'envoi de fichiers depuis l'application, avec contrôle et chiffrement, est prévu : T-115-23 et T-115-24.
Outils
Un outil personnalisé a un nom, une couleur, une description, un schéma d'entrée (JSON Schema) et un corps de fonction. La page enregistre ces champs dans votre espace. L'exécution du corps de fonction par l'agent n'est pas couverte par ce chapitre.
Wiki LLM
Le wiki est un arbre de pages Markdown (format OKF : un fichier à en-tête type, l'identifiant est le chemin). Le serveur le lit depuis un dossier, un WebDAV ou un stockage S3. Aucun éditeur web n'est hébergé : on édite les fichiers dans le stockage. La page /wiki offre le bouton « Reindex now » et l'état de la synchronisation.
Voir aussi
- Chat : parler à un workflow déployé
- Sécurité et identifiants : les accès aux services externes et à l'API
- Routes des ressources : les routes du Document Store et des outils personnalisés
- Sauvegarde et restauration : ce qui est sauvegardé, dont les collections Qdrant
- Limites et ce que la plateforme ne fait pas : taille des fichiers et limites de l'IA ancrée
- Conseils : sessions courtes, demandes itérées, données protégées
Sécurité et identifiants
La section Sécurité gère les accès aux services externes et les accès à l'API. Elle apparaît dans le menu à partir du plan Business. Sur un plan inférieur, la limite porte sur le menu : voir la section Navigation du Tableau de bord.
Les pages
| Page | Adresse | Rôle |
|---|---|---|
| Conformité EU | /compliance-dashboard | Matrice de conformité (voir Analytique) |
| Identifiants | /credentials | Secrets de connexion aux services externes |
| Variables | /variables | Valeurs réutilisables dans les workflows |
| Clés API | /api-keys | Création et révocation de clés API (aucune route ne les accepte encore, voir plus bas) |
| Webhooks | /webhooks | Adresses notifiées, et réception des fournisseurs |
Identifiants
Un identifiant contient les informations de connexion à un service (Odoo, n8n, Matomo, un fournisseur de paiement, entre autres). La page est un catalogue de cartes rangées en 21 catégories (IA, ERP/CRM, Automatisation, Paiements EU, Données EU, Sécurité, Connecteurs, entre autres). Chaque carte a ses propres champs. Les cartes OAuth portent un choix de portées et une durée de jeton.
Comment un secret est gardé
- Il est chiffré en AES-256-GCM dans la base, avec une clé propre à chaque identifiant. La clé dérive d'une clé racine « au repos » (variable
AT_REST_ENCRYPTION_KEY) distincte du secret de session quand elle est fournie. Sans elle, le secret de session sert de racine. Le détail des clés est dans Variables d'environnement. - La valeur en clair ne revient jamais dans une réponse de l'API : la liste montre un masque.
- À la modification, la page recharge l'identifiant sans ses valeurs secrètes : chaque champ secret est remplacé par un marqueur avant d'entrer dans l'écran. Les champs secrets sont masqués, avec un bouton pour les afficher le temps de la saisie.
- Un identifiant est lié à un espace de travail. Vous ne voyez que ceux de vos espaces.
Comment un connecteur le lit
Quand un connecteur appelle un service, le serveur déchiffre l'identifiant de l'organisation qui fait la requête, et d'elle seule. Ce mécanisme est décrit dans Conception des connecteurs MCP. Au démarrage, il peut aussi publier les identifiants d'un déploiement à locataire unique comme variables d'environnement.
OpenBao
OpenBao est optionnel. Une organisation peut y garder ses secrets de connecteurs : elle enregistre un identifiant d'AppRole nommé openbaoAppRole. Le serveur lit alors ses secrets dans le coffre, avec la priorité sur ceux de la base. Sans cet identifiant, OpenBao n'est jamais contacté. La carte « OpenBao Secrets » du catalogue sert à un client qui apporte sa propre instance à un connecteur.
Variables
La page a cinq onglets : Toutes, Système, Capture, Statiques, Runtime. Les variables système sont remplies par la plateforme et ne se modifient pas. Une valeur se masque et s'affiche d'un clic. On crée et on modifie les autres. Elles se consomment dans les workflows ; les routes correspondantes sont dans Routes des ressources.
Clés API
Une clé API se crée et se gère depuis cette page ; à ce jour aucune route de l'API ne l'accepte à la place du jeton de session (l'extracteur existe dans le code, sans route consommatrice) : un appel programmatique passe par le jeton obtenu à la connexion, décrit dans Swagger. Le formulaire demande un nom et un espace de travail. La page montre la clé une seule fois à la création, puis, dans la liste, un extrait (8 premiers et 4 derniers caractères) jusqu'au rechargement de la page, et ensuite ****. Supprimer une clé la révoque. L'extracteur prévu à cet effet attend l'en-tête X-Api-Key. Voir aussi Documentation Swagger pour l'authentification de l'API.
La clé est gardée sous forme hachée. La page n'offre ni choix de portées, ni rotation automatique.
Webhooks
La page permet de créer un webhook (nom, adresse, événements parmi 12), de l'activer, de le modifier, de le supprimer et d'envoyer un test. Les 12 événements proposés : conversation démarrée ou terminée, message reçu ou envoyé, intention détectée, transfert demandé, prospect créé, workflow démarré, terminé ou échoué, appel démarré ou terminé.
Ce qui est branché, ce qui ne l'est pas :
- Envoi de test : réel. Le serveur appelle l'adresse (avec un filtre contre les adresses internes) et note la date.
- Émission automatique des événements : non branchée. Le code qui lit la table des webhooks se limite à la gestion et à l'envoi de test.
- Livraisons récentes : aucun journal de livraison n'est enregistré.
- Régénérer le secret : répond
503 FEATURE_PENDING.
En sens inverse, le serveur reçoit les notifications de fournisseurs : paiement (Mollie, PayPlag, Adyen, Stripe, Lyra, SlimPay, Wero), LiveKit, et une entrée générique. Seul Mollie sert à la facturation de la plateforme (voir Tarification) ; les autres routes de paiement existent dans le code.
Voir aussi
- Paramètres : réglages, facturation, compte et gestion des utilisateurs
- OpenBao et secrets : le coffre de secrets optionnel d'une organisation
- Workflows : où les identifiants et variables sont consommés
- Routes des ressources : variables, identifiants et outils par l'API
- Sécurité : principes, secrets et chiffrement côté exploitation
- Architecture de confiance zéro : ce que chaque requête traverse avant d'atteindre un secret
MCP et Orchestrateur
La section « Écosystème MCP » regroupe l'assistant qui construit vos workflows et les catalogues de serveurs MCP.
Les pages
| Page | Adresse | Rôle |
|---|---|---|
| Orchestrateur | /orchestrator | Assistant qui construit un workflow avec vous |
| Gateway Business | /mcp/gateways/business | Une carte par métier |
| Marketplace | /marketplace | Modèles de workflow à déployer |
| Console Admin MCP | /mcp/admin | Inventaire des services (voir l'état, plus bas) |
| Gateway Projet UE | /mcp/gateways/projet-ue | Catalogues de données européennes |
| Serveurs MCP Business | /mcp/servers/business | Catalogue de serveurs métier |
| Serveurs MCP Projet UE | /mcp/servers/projet-ue | Serveurs des catalogues européens |
| Démo Crypto | /crypto-demo | Simulation pédagogique |
Selon votre plan (voir Tarification et offres), le menu montre les trois premières pages seulement (Orchestrateur, Gateway Business, Marketplace). Les cinq autres apparaissent aux plans Enterprise et Souverain. Les anciennes adresses (/mcp-admin, /mcp-servers-business, /mcp-gateway-business) redirigent vers les adresses du tableau.
Orchestrateur
L'Orchestrateur ouvre sur deux cartes :
- « Déployer les outils de votre métier » : vous choisissez un ou plusieurs métiers, puis l'assistant prépare l'ensemble ;
- « Déployer un parcours support (pédagogique) » : un parcours pour accompagner une personne (explications, vidéos, exercices, questions).
Puis une conversation s'ouvre. Elle est portée par une session de l'API (/orchestrator/sessions). Une carte de progression montre cinq étapes :
- Accueil
- Secteur
- Template
- Validation (confirmation et identifiants)
- Déploiement (sauvegarde, puis ouverture du chat)
Le serveur utilise des noms de phase plus fins (coaching, discovery, identification, credentials, tels qu'ils sont écrits dans le code). L'écran les ramène à ces cinq étapes.
Gateway Business
La page montre 16 métiers (détaillés dans Cas d'usage par secteur) : thérapeute, consultant, mobilier, e-commerce, formation, juridique, immobilier, médical, logistique, industrie, agriculture, créatif, association, tourisme, RH, finance. Chaque carte donne le nombre de serveurs inclus par palier. Elle ouvre la page du métier (/mcp/gateways/business/<metier>).
Gateway Projet UE
La page présente 26 catalogues de serveurs MCP pour des données publiques européennes (par exemple CORDIS, OpenAIRE, Eurostat, EPO). Les 26 sont marqués « disponibles ». Les compteurs de la page (serveurs, endpoints, opérationnels) sont calculés depuis le catalogue, pas écrits à la main. Ces sources sont décrites dans API-as-a-Service EU souverain.
Serveurs MCP Business
Cette page est un catalogue de 175 cartes de connecteurs. Elle ne décrit pas votre infrastructure. Le même catalogue, lu par l'API, est dans parcourir le catalogue de services.
- Une carte porte la mention « Déployé » seulement si le serveur figure à l'inventaire des serveurs prouvés : un outil de lecture y a rendu des données réelles. À la date du 2026-10-03, ce sont 30 serveurs sur 175. Les autres affichent « Bientôt disponible » (une seule carte affiche « Disponible » à cette date).
- Le bouton « Déployer » (info-bulle « Déployer ce serveur et ouvrir son workflow ») crée un workflow pour ce serveur et ouvre l'éditeur. Sur une carte « Bientôt disponible », il est désactivé et se lit « En préparation ».
- Vous pouvez chercher, filtrer par catégorie ou certification, et n'afficher que les serveurs déployés.
Ce qui n'est pas encore branché
Le cycle de vie des conteneurs n'est pas relié à l'API (le format des erreurs de l'API est dans Gestion des erreurs). Les appels suivants répondent 503 FEATURE_PENDING à un administrateur (un autre rôle reçoit 403) : déployer, démarrer, arrêter, redémarrer un serveur, enregistrer ses secrets, déployer un profil. La lecture du profil de sécurité répond 503 à tout rôle. L'analyse de sécurité Trivy avant déploiement n'est donc pas disponible depuis cette page. Les secrets de vos connecteurs se saisissent dans la page Sécurité et identifiants, pas par ces boutons.
Voir la référence API Catalogue Business.
Console Admin MCP
La console est prévue pour lister les services Podman (Core, MGaaS), leur santé, et pour lire leurs journaux. Elle n'est pas reliée à l'infrastructure : l'API rend une liste vide, la sonde de santé répond 503 FEATURE_PENDING, et la page affiche un bandeau qui signale que la console n'est pas câblée à l'infrastructure. Aucun chiffre n'est inventé. En attendant, un administrateur lit l'inventaire en ligne de commande avec podman ps (voir Gestion des conteneurs).
Démo Crypto
La page propose trois onglets : chiffrement homomorphe (FHE), preuve à divulgation nulle (ZKP), cryptographie post-quantique (PQC). Un bandeau « SIMULATION » le dit : la page calcule dans le navigateur, avec des entrées de démonstration. Elle ne protège aucune de vos données.
Marketplace
La page liste 93 modèles de workflow. Le bouton « Déployer » crée le workflow dans votre espace.
Voir aussi
- Workflows : l'éditeur, la palette de nœuds, les exécutions
- Sécurité et identifiants : où se saisissent les secrets de vos connecteurs
- Utiliser les connecteurs MCP : où vivent les fiches qui alimentent ces catalogues
- Routes du catalogue métier : lecture du catalogue et routes qui répondent 503
- Cas d'usage par secteur : les métiers de la Gateway Business, avec leurs connecteurs de départ
- Vue d'ensemble : ce qui est mesuré et prouvé, connecteur par connecteur
Voix et Canaux
La section Canaux décrit comment votre agent atteint vos visiteurs : apparence du widget, voix, campagnes d'appels, numéros, messageries. Les plans cités ci-dessous sont décrits dans Tarification et offres.
Les pages
/channels ouvre une page unique. Ses cinq sections ont aussi chacune leur adresse.
| Section | Adresse | Plan minimum dans le menu |
|---|---|---|
| Marque | /channels/branding | Pro |
| Voix | /channels/voice | Business |
| Campagnes Voice | /channels/voice-campaigns | Pro |
| Numéros EU | /channels/phone-numbers | Business |
| Intégrations | /channels/integrations | Pro (le plan Essentiel la trouve dans la section Déployer) |
L'analytique des appels est une page de la section Analytique : /call-analytics. Les adresses /channels/whatsapp, /channels/telegram et /channels/sms mènent à la page Intégrations.
Marque (widget)
La page est un ensemble de huit sections repliables, suivies d'un aperçu :
- Titre et description de l'assistant
- Apparence et images
- Police, thème et couleurs
- Variantes d'interface
- Configuration des onglets
- Confidentialité et mentions
- Paramètres avancés
- Code widget et déploiement (voir aussi l'étape 7, « intégrer le chat à votre site », de la prise en main guidée)
Voix
La page a quatre onglets : reconnaissance vocale (STT), synthèse vocale (TTS), WebRTC, paramètres. Au-dessus, quatre cartes reprennent les statistiques d'appels.
| Brique | Moteur | Hébergé |
|---|---|---|
| Reconnaissance vocale | Faster-Whisper (Large v3, Medium, Small) | Dans la pile de l'application |
| Synthèse vocale | Kokoro (v1, voix française, voix allemande) | Dans la pile de l'application |
| Temps réel | LiveKit | Dans la pile de l'application |
Les boutons « Tester » de cette page sont désactivés. Le micro de la page Chat et de l'Orchestrateur utilise la même reconnaissance vocale.
Le code contient un pont téléphonique (LiveKit vers une ligne SIP européenne, avec une règle anti-fraude sur les destinations). Aucune page ne le pilote encore. Les variables de la chaîne vocale sont dans Variables d'environnement.
Campagnes Voice et Numéros EU
Ces deux pages sont annoncées mais non disponibles. Le bouton « Nouvelle campagne » et le bouton « Acheter un numéro » sont désactivés (« Bientôt disponible »). La page Numéros liste trois fournisseurs candidats ; elle ne gère aucun numéro.
Intégrations
La page a trois onglets : Canaux actifs, Ajouter un canal, Webhook URL. Les canaux « Via n8n » passent par le connecteur n8n.
| Canal | Mode de connexion | Plan minimum |
|---|---|---|
| Telegram | Direct | Essentiel |
| WhatsApp Business | Via n8n | Pro |
| Discord | Via n8n | Pro |
| Messenger (Meta) | Via n8n | Pro |
| WebRTC | Direct | Business |
Deux écarts à connaître :
- le formulaire de la page propose Telegram, Courriel (SMTP/IMAP), WhatsApp Business, Discord et Slack. L'API n'accepte que cinq genres : WhatsApp, Telegram, Discord, Messenger et WebRTC. Le courriel et Slack sont donc refusés à l'enregistrement, et Messenger et WebRTC n'ont pas encore de carte dans le formulaire ;
- l'état de connexion affiche « Déconnecté » pour tous les canaux : aucune sonde de connexion n'existe, et la page ne montre pas un « Connecté » qu'elle ne peut pas mesurer.
Analytique des appels
La page /call-analytics liste les appels (30 derniers jours) et ouvre le détail d'un appel (transcription, coût, latence). Le service de statistiques d'appels rend le nombre d'appels, les appels terminés ou abandonnés et la durée moyenne. Les champs avancés (temps de réponse, sentiment, heures de pointe, intentions) sont renvoyés vides, faute de données stockées : la page n'invente pas de taux de résolution ni de satisfaction.
Voir aussi
- Analytique : la page des appels et les autres mesures d'usage
- Sécurité et identifiants : les accès aux services externes et à l'API
- Chat : le micro du chat utilise la même reconnaissance vocale
- Déploiement avec Podman : les services de voix font partie du plan backend
- Connecteur n8n : le relais des canaux WhatsApp, Discord et Messenger
- Limites et ce que la plateforme ne fait pas : les langues de la voix et les minutes par offre
Analytique
Les pages d'analytique et d'évaluation mesurent l'usage de votre agent et la qualité de ses réponses. Certaines mesures sont encore partielles : ce chapitre dit lesquelles.
Les pages
| Page | Adresse | Section du menu | Plan minimum |
|---|---|---|---|
| Analytique | /analytics | Analytique | Essentiel (vue simple) |
| Historique Chat | /chat-history | Analytique | Essentiel (vue simple) |
| Analytique Appels | /call-analytics | Analytique | Pro |
| Leads / CRM | /leads | Analytique | Pro |
| Lead Funnel | /lead-funnel | Analytique | Pro |
| Messages Proactifs | /proactive-messages | Analytique | Pro |
| Logs App | /logs | Analytique | Pro |
| Logs Serveur | /server-logs | Analytique | Pro |
| Conformité EU | /compliance-dashboard | Sécurité | Business |
| Datasets, Évaluateurs, Évaluations, A/B Testing | /datasets, /evaluators, /evaluations, /ab-testing | Évaluations | Enterprise |
Les plans Essentiel et Starter ont l'analytique simple : deux pages (Analytique et Historique Chat). Les plans sont décrits dans Tarification et offres.
Analytique 360
La page offre une période (24 heures, 7, 30 ou 90 jours), un filtre de canal (Tous, Web, WhatsApp, Telegram, Voix ; voir Voix et Canaux) et quinze onglets. Le filtre de canal n'est pas transmis à l'API : il ne change aucun chiffre aujourd'hui.
Un seul onglet est branché : Vue d'ensemble. Les quatorze autres affichent « Section en cours de portage V1 » (Interactions, Performance, Outils MCP, Gateways, Ollama / LLM, Voix, Base de connaissances, Workflows, Infrastructure, Sécurité / Crypto, Protocole MCP, Leads / CRM, Conformité EU, Anti-Hallucination).
Dans la Vue d'ensemble :
| Carte | Source |
|---|---|
| Conversations totales, Messages envoyés | Mesures de l'API |
| Taux de résolution (cible > 85 %) | Mesure de l'API quand elle existe, sinon un tiret |
| Temps de réponse moyen (cible < 2000 ms) | Mesure de l'API quand elle existe, sinon un tiret |
| Satisfaction, Taux d'abandon (cible < 8 %) | Pas de source : un tiret |
| Appels outils MCP, Minutes vocales, Ops crypto | Pas de source : zéro fixe |
| Score Gaia-X, Anti-hallucination (cible < 3 %) | Pas de source : un tiret |
Les graphiques (conversations par jour, messages par heure, répartition par canal) n'ont pas encore de données et s'affichent vides. Le bouton d'export est désactivé. Un zéro ou un tiret sur cette page ne signifie donc pas « rien ne s'est passé » : cela peut signifier « non mesuré ».
Les cibles affichées (résolution, temps de réponse, abandon, hallucination) sont des objectifs de la page, pas des résultats mesurés.
Leads / CRM
La page suit les prospects de votre espace :
- liste avec recherche et filtre de statut, ou tableau en colonnes (nouveau, contacté, qualifié, proposition, négociation) ;
- création, modification, suppression d'un prospect ;
- quatre compteurs de synthèse ;
- une liste des prospects venus des formulaires publics du site (contact, lettre d'information).
La page ne crée pas de prospect à partir de l'Orchestrateur.
Lead Funnel
La page affiche cinq paliers de score (Cold, Engaged, Qualified, Hot, Highly Qualified). Les compteurs y sont à zéro : la page est une base d'éditeur, pas encore une mesure.
Journaux
- Logs App (
/logs) : les 50 derniers événements du serveur, lus en mémoire. L'historique long via VictoriaLogs est annoncé pour plus tard (voir Journaux pour les journaux côté serveur). - Logs Serveur (
/server-logs) : filtre par niveau et par recherche sur les dernières 24 heures, pause, effacement, export, rafraîchissement.
Conformité EU
La page affiche une matrice par référentiel : RGPD, NIS2, EUCS, Gaia-X, eIDAS, avec un score, des vérifications réussies, en alerte ou en échec, et un filtre. Le rapport vient de l'API (/compliance/report). Ce rapport est une auto-évaluation déclarative, pas un audit indépendant ; chaque vérification porte sa base (« self-declared » ou « measured »). Si l'API ne répond pas, la page affiche un rapport local fixe à la place.
Voir le chapitre Conformité RGPD.
Évaluations
Réservées aux plans Enterprise et Souverain.
- Datasets : importez un fichier CSV de questions et de réponses attendues.
- Évaluateurs : créez un évaluateur de l'un de ces types : personnalisé, juge LLM, similarité, expression régulière.
- Évaluations : lancez une évaluation en choisissant un workflow, un dataset et un ou plusieurs évaluateurs. Le détail d'une évaluation a sa page (
/evaluations/<id>). - A/B Testing : comparez des variantes de prompt.
Les mesures de précision, de rappel ou de F1 ne figurent pas parmi les types d'évaluateur.
Voir aussi
- Voix et Canaux : apparence du widget, voix, campagnes d'appels, numéros, messageries
- Workflows : l'éditeur, la palette de nœuds, les exécutions
- Chat : l'historique et les messages proactifs vus depuis la page Chat
- Supervision : les métriques et points de santé côté exploitation
- Journaux : où le backend écrit, et l'export vers VictoriaLogs
- Conformité RGPD : le fond du référentiel que la matrice auto-évalue
Paramètres
Ce chapitre couvre la section Paramètres (réglages, facturation, compte) et la section Gestion (utilisateurs, rôles, SSO, connexions). Les espaces de travail vivent dans la section Agence. Les plans minimums du tableau sont ceux de Tarification et offres.
Les pages
| Page | Adresse | Section du menu | Plan minimum |
|---|---|---|---|
| Paramètres | /settings | Paramètres | Tous |
| Facturation | /billing | Paramètres | Tous |
| Compte | /account | Paramètres | Tous |
| Utilisateurs | /users | Gestion | Business |
| Rôles | /roles | Gestion | Business |
| Config SSO | /sso-config | Gestion | Business |
| Activité Connexion | /login-activity | Gestion | Business |
| Observabilité | /observability | Gestion | Business |
| Espaces de Travail | /workspaces | Agence | Enterprise |
La page des tarifs (/pricing) est une page publique du site, pas une page de l'application. Pour gérer votre abonnement, utilisez Facturation.
Paramètres
La page a trois onglets : Général, Fonctionnalités, Accès rapides.
- Général : six champs (nom du site, adresse du site, courriel de support, taille maximale de fichier, délai de session, langue par défaut).
- Fonctionnalités : neuf interrupteurs (réponses en flux continu, envoi de fichiers, entrée vocale, tableau de bord analytique, interface générative, multi-locataire, SSO, journaux d'audit, limitation de débit).
- Accès rapides : huit raccourcis vers d'autres pages (apparence, sécurité, clés API, entre autres).
Limite actuelle : le bouton Enregistrer envoie les six champs et les neuf interrupteurs sous les clés generalSettings et featureFlags. L'API de cette page ne lit que timezone et language, que la page n'envoie pas : rien n'est enregistré depuis cette page. Le fuseau horaire et la langue de l'utilisateur se règlent dans Compte, qui les enregistre.
Compte
La page porte le profil, le mot de passe, la double authentification, les notifications, l'export de vos données et la suppression du compte (voir Conformité RGPD pour l'exercice des droits). Les langues proposées sont le français, l'anglais, le néerlandais et l'allemand. Seuls le français et l'anglais ont une interface complète (1 610 clés au 2026-10-03) : le néerlandais et l'allemand n'ont que 26 clés traduites, le reste s'affiche en français.
Double authentification
Après le mot de passe, la connexion demande un second facteur : un code envoyé par courriel, ou le code d'une application d'authentification (TOTP) si vous l'avez activée dans Compte. L'administrateur du déploiement peut exiger le TOTP pour tous les comptes, ou pour des rôles choisis. Cette exigence est une option de configuration du serveur, pas une règle fixe par rôle (voir Variables d'environnement).
Utilisateurs et rôles
La page Utilisateurs liste les comptes de votre organisation, avec leur état, et permet de les modifier. Le bouton « Ajouter un utilisateur » crée un compte à partir d'un courriel, d'un nom, d'un rôle et d'un statut. La page Rôles liste les rôles de votre organisation, en crée et en supprime.
Les rôles ne sont pas une liste fixe : chaque organisation définit les siens. Le moteur de politiques est décrit dans Architecture de confiance zéro. Une permission s'écrit ressource:action (par exemple credentials:view). Le catalogue compte 88 permissions en 18 catégories, parmi lesquelles mcpgateways, mcpgatewayflows, tools, credentials, variables, apikeys, documentStores, datasets, executions, evaluators, evaluations, workspace, logs. Le joker * donne tous les droits. Il n'existe pas de permission workflows:view : les workflows relèvent de mcpgateways et mcpgatewayflows.
Les pages d'administration /admin* sont réservées aux rôles admin, superadmin, super_admin et owner. Tout autre rôle, ou un rôle inconnu, voit un écran « accès réservé ».
Espaces de travail
Un espace de travail regroupe des workflows, identifiants et historiques. La page /workspaces liste, crée et modifie les espaces de votre organisation. Les données sont cloisonnées par organisation (voir Architecture Chatbotaurus). OpenBao n'intervient que si votre organisation a choisi cette option (voir Sécurité et identifiants).
SSO
La page Config SSO a trois onglets : configuration, fournisseurs, sessions. La configuration Authentik demande un identifiant court (slug), un identifiant client et l'adresse du serveur d'authentification. Deux interrupteurs activent le SSO et la création automatique des utilisateurs. L'onglet sessions permet de terminer une session. Le bouton « Ajouter un provider » (SAML, LDAP) est désactivé : l'ajout de fournisseurs supplémentaires est en cours d'intégration côté serveur.
Voir le guide SSO Authentik.
Activité de connexion
Le tableau liste, pour chaque connexion : l'utilisateur, le statut, l'adresse IP, la localisation, l'appareil et l'heure. Il offre des filtres de recherche, de statut et de dates, une alerte quand des connexions suspectes sont détectées, et un export CSV. Les limiteurs de connexion sont décrits dans Sécurité.
Voir aussi
- Tableau de bord : la première page après la connexion
- Sécurité et identifiants : les accès aux services externes et à l'API
- SSO Authentik : la configuration côté serveur du bouton de connexion unique
- Tarification et offres : la facturation, l'engagement et les moyens de paiement
- Conformité RGPD : export et suppression des données, les droits exercés depuis Compte
- Prise en main guidée : créer le compte et inviter l'équipe
Conseils
Une page de conseils courts, tous vérifiables dans le produit ou dans le code.
Parlez en langage naturel
Il n'y a pas de syntaxe spéciale. Décrivez la tâche comme à un collègue : Chatbotaurus choisit l'outil du connecteur qui y répond. Plus la demande nomme l'objet (un client, une facture, un rendez-vous), plus le choix de l'outil est sûr.
Étendez avec des connecteurs
Chatbotaurus parle le protocole MCP. Chaque
service métier est un connecteur décrit par un fichier connectors/<id>.yaml.
Le dépôt en contient 195 (mesure du 2026-10-03 : ls connectors/*.yaml | wc -l).
Le chapitre Vue d'ensemble des connecteurs
présente le catalogue. Pour en écrire un, voir
Fichiers de configuration.
Les modèles tournent chez vous
L'inférence passe par Ollama, sur votre infrastructure. La liste des modèles
retenus est fixée dans crates/forge-core/src/model_governance.rs :
| Rôle | Modèle |
|---|---|
Traduction (rôle Main du code, jamais d'appel d'outil) | cas/eurollm-1.7b-instruct-q8 |
Génération : repli et défaut de OLLAMA_MODEL | ministral-3:3b |
Embeddings (calculés en local par fastembed) | paraphrase-multilingual-MiniLM-L12-v2 (vecteurs de 384 dimensions) |
Changer cette liste est une décision de souveraineté, pas un réglage : elle se
modifie avec une justification de licence. Le modèle de génération se choisit
avec OLLAMA_MODEL et le modèle d'embeddings du pipeline RAG avec
EMBEDDING_MODEL (voir
Variables d'environnement).
Gardez les sessions courtes
Une conversation longue remplit la fenêtre de contexte du modèle, et les réponses perdent en précision. Si elles deviennent moins pertinentes, ouvrez une nouvelle conversation. C'est un conseil d'usage, pas une mesure de ce dépôt.
Itérez sur vos demandes
Vous n'avez pas à trouver la bonne formulation du premier coup. Reformulez, précisez l'objet, relancez.
Profils du catalogue
Le catalogue regroupe ses serveurs en quatre profils :
| Profil | Contenu |
|---|---|
solo | 1 serveur : Odoo |
starter | 5 serveurs |
business | 12 serveurs |
enterprise | tous les serveurs du catalogue |
GET /api/v1/mcp/catalog-business/profiles les liste. La route
POST /api/v1/mcp/catalog-business/profiles/{name}/deploy existe, mais elle répond
aujourd'hui 503 FEATURE_PENDING : le pilotage de Podman par le backend n'est pas
branché, elle ne déploie rien. Le tutoriel
Parcourir le catalogue de services et préparer un déploiement
explique ce qui marche et ce qui est en sommeil.
Protégez vos données
- Les points d'accès de la voix doivent être dans l'UE : le code refuse les
autres (
validate_eu_endpoint,crates/forge-voice/src/stt.rs). - Le registre des connecteurs rejette un connecteur dont les données ne restent pas dans l'UE ou chez vous.
- Aucun secret n'est stocké dans les manifestes de connecteurs : ils lisent l'environnement.
- Les journaux masquent clés, jetons et adresses e-mail avant écriture.
Détails et limites : Sécurité.
Surveillez
Sondez GET /api/v1/readyz depuis votre supervision. Le chapitre
Supervision dit ce qui est mesuré aujourd'hui et ce qui ne
l'est pas encore.
Mettez à jour avec méthode
Si vous disposez des sources sous licence : récupérez les changements, puis reconstruisez le workspace.
git pull
cargo build --workspace --release
En développement, dx serve (lancé depuis crates/forge-ui) recharge le
frontend à chaque modification. Le backend se redémarre.
Voir aussi
- Variables d'environnement — régler le modèle, les embeddings et les points d'accès vocaux
- Fichiers de configuration — écrire ou corriger le manifeste YAML d'un connecteur
- Contribuer — construire, vérifier et livrer si vous disposez des sources
- Questions fréquentes — réponses courtes aux questions générales, techniques et de positionnement
- Glossaire — définitions des termes techniques employés dans ces conseils
Connecteurs MCP
Un connecteur est un fichier YAML du dossier connectors/ du dépôt. Il déclare un service, sa méthode d'authentification, sa licence et la liste des outils que l'agent peut appeler. Ce chapitre donne les chiffres mesurés le 2026-10-03 et renvoie vers les douze connecteurs décrits dans ce livre.
Ce qui est mesuré
| Quoi | Valeur | Comment c'est mesuré |
|---|---|---|
| Fichiers de connecteurs | 195 | ls connectors/*.yaml (dont TEMPLATE.yaml, le gabarit, que le chargeur saute) |
| Entrées du catalogue métier | 108 | catalog-business.json, nombre d'entrées |
Entrées au statut available | 15 | même fichier, champ status |
Entrées au statut coming-soon | 93 | même fichier, champ status |
Services mcp-* du plan client | 43 | container_name: mcp- dans podman-compose.vps2.yml |
Les trois premiers chiffres sont aussi ceux du site public. Ils viennent de crates/forge-ui/src/config/chiffres_mesures.rs, fichier généré, daté du 2026-10-03.
Le nombre de fichiers (195) et le nombre d'entrées du catalogue (108) ne se recouvrent pas. Douze entrées du catalogue n'ont pas de fiche YAML : collabora, faster-whisper, gnuhealth, logseq, mywms, openmom, pgadmin, postgresql, property-base, timescaledb, valkey et une entrée de détection d'intrusion. À l'inverse, 99 fichiers YAML n'ont pas d'entrée au catalogue (gabarit compris).
Un connecteur du catalogue au statut coming-soon est annoncé, pas ouvert. Le statut est une donnée du catalogue, il ne dit rien de l'état du fichier YAML.
Comment un connecteur est chargé
Au démarrage, forge-api lit le dossier connectors/, remplace les variables ${VAR:-défaut} par l'environnement, puis enregistre un connecteur par fichier. Le moteur HTTP sert les fichiers à authentification HTTP. Le connecteur odoo a son propre client XML-RPC. Le connecteur calrs passe par une commande dans un conteneur (voir CalRS). Source : connectors/README.md et crates/forge-mcp/src/connector/catalogue.rs.
Dans tools/list, le nom d'un outil des connecteurs HTTP est préfixé par l'identifiant du connecteur : l'outil get_visits du fichier matomo.yaml s'appelle matomo.get_visits (moteur HTTP des connecteurs). Les chapitres suivants donnent les noms tels qu'ils sont écrits dans les fichiers, sans ce préfixe.
Chaque connecteur déclare sa conformité. Le registre le refuse si gdpr_compliant vaut false ou si data_residency n'appartient pas à la liste eu, eu-west, eu-central, france, germany, finland, netherlands, ireland, self-hosted (connectors/README.md, section « Gate EU / Gaia-X »). Cette règle porte sur ce que le fichier déclare. Elle ne prouve pas où tourne l'instance du client.
Une seconde règle décide du dispatch : seuls les identifiants de la liste ALLOWED_MCP_SERVERS (liste des serveurs autorisés du code) sont exécutés, et tools/list n'affiche que leurs outils. Mesuré le 2026-10-03 : sur les 194 fichiers hors gabarit, 98 sont dans cette liste et 96 n'y sont pas. dolibarr et freescout font partie des 96 (un test du dépôt le verrouille) : leur fiche se charge, leurs outils ne sont pas appelables tant que l'identifiant n'est pas ajouté à la liste.
Authentification
Types d'authentification présents dans les 195 fichiers, mesurés le 2026-10-03 : aucune (73), bearer (52), clé d'API en en-tête (33), basic (20), jeton de connexion (5), jeton en paramètre d'URL (4), oauth2 (3), et quelques cas particuliers. Deux fichiers (odoo, calrs) n'ont pas de bloc auth parce que leur transport n'est pas HTTP.
Les chapitres suivants nomment les variables que chaque fichier lit. Côté locataire, les valeurs sont saisies comme identifiants de la plateforme et stockées chiffrées en base. OpenBao est un mode optionnel : une organisation qui y a enregistré son AppRole voit ses secrets lus depuis OpenBao en priorité. Sans cet AppRole, OpenBao n'est jamais contacté (résolution des identifiants du code).
Les douze connecteurs décrits ici
Compte d'outils mesuré dans chaque YAML le 2026-10-03. Pour odoo, le YAML ne déclare que 6 outils ; les 711 outils nommés vivent dans le registre Rust.
| Connecteur | Outils | Lecture seule | Authentification | Statut au catalogue | Service dans le plan client | Autorisé au dispatch |
|---|---|---|---|---|---|---|
| Authentik | 442 | oui | bearer | available | non | oui |
| CalRS | 7 | sans objet | aucune (commande dans le conteneur) | available | oui | oui |
| Dolibarr | 263 | oui | clé en en-tête | coming-soon | non | non |
| Forgejo | 482 | non | bearer | coming-soon | oui, pour le poste de développement | oui |
| FreeScout | 15 | oui | clé en en-tête | coming-soon | non | non |
| Listmonk | 76 | non | basic | coming-soon | oui | oui |
| Matomo | 113 | oui | jeton en paramètre | available | oui | oui |
| n8n | 49 | non | clé en en-tête | available | oui | oui |
| Nextcloud | 167 | non | basic | available | non | oui |
| Odoo | 711 (registre) | non | XML-RPC | available | oui, 17 services | oui |
| Rocket.Chat | 338 | non | clé en en-tête et identifiant | coming-soon | non | oui |
| Typesense | 79 | non | clé en en-tête | coming-soon | oui | oui |
« Lecture seule » veut dire que tous les outils du YAML utilisent la méthode GET. « Service dans le plan client » veut dire qu'un container_name: mcp-… existe dans podman-compose.vps2.yml. Une réponse « non » ne dit pas que le service est inutilisable : le client peut apporter sa propre instance. « Autorisé au dispatch » veut dire que l'identifiant figure dans ALLOWED_MCP_SERVERS.
Les outils d'écriture sont classés par leur nom (classification de sécurité des outils, dans le code). Un nom qui porte drop, truncate, erase, purge, wipe, ou qui se termine par unlink ou destroy, n'est jamais exécuté par l'agent. Un nom qui porte delete, cancel, refund, pay, charge, transfer, remove ou revoke n'est exécuté qu'après une autorisation humaine explicite. Les outils create, update et send passent sans cette étape. Les chapitres qui suivent écrivent « supprime » pour ce que le fichier déclare ; ce que l'agent exécute seul est plus étroit.
Le catalogue métier
Le catalogue est servi par l'API sous /api/v1/mcp/catalog-business, pour un utilisateur authentifié. GET /api/v1/mcp/catalog-business renvoie les 108 entrées embarquées dans le binaire, avec un filtre optionnel par catégorie. GET /api/v1/mcp/catalog-business/{id}/registry-tools liste les outils que le registre connaît pour un connecteur. Les routes de cycle de vie (déployer, démarrer, arrêter, secrets) répondent encore 503 avec le marqueur feature_pending : l'adaptateur Podman n'est pas branché (crates/forge-api/src/routes/mcp_catalog_business.rs, commentaire de tête).
Les entrées sont rangées en 34 catégories. Par taille décroissante, au 2026-10-03 : Communication (7 entrées), puis CRM & ERP, DevOps, Monitoring et Database (5 entrées chacune).
Les connecteurs de données publiques de l'UE
Dix-huit fichiers portent un nom de secteur : agriculture, culture, cybersecurity, education, employment, energy, environment, fintech, foodsafety, governance, innovation, industry, legaltech, maritime, sme, health, spatial, quantum. Chacun interroge le portail de données ouvertes de l'UE, sans authentification, avec 28 à 30 outils. Un dix-neuvième, broadcast, est un connecteur à jeton avec 2 outils.
Utiliser un connecteur
- Vérifiez dans le tableau ci-dessus que la colonne « Autorisé au dispatch » vaut « oui » : sinon les outils ne sont pas appelables.
- Ayez une instance du service : la vôtre, ou celle du plan client si la colonne « Service dans le plan client » vaut « oui ».
- Enregistrez les identifiants : page Identifiants (
/credentials) de l'application, fiche du connecteur. Le chapitre du connecteur donne le nom de la fiche et ses champs (CalRS n'a rien à saisir). Connecter Odoo à la passerelle MCP déroule ce parcours de bout en bout. - Posez la question dans le chat, ou appelez l'outil par
tools/call(Routes MCP).
Ajouter un connecteur
Le tutoriel Créer votre premier connecteur MCP décrit la forme d'un fichier YAML.
Voir aussi
- Conception des connecteurs MCP : deux types de connecteurs, contrôle de conformité UE et cycle de vie
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Routes du catalogue métier : routes du catalogue métier, lecture opérationnelle et cycle de vie prévu
- Utiliser les connecteurs MCP : fiches de connecteurs présentes et consultation du catalogue par l'API
- Tarification : nombre de connecteurs métier inclus dans chaque offre
Connecteur Authentik
Authentik est un fournisseur d'identité (SSO, OIDC, SAML, LDAP). Le connecteur lit l'API REST v3 d'une instance Authentik. Il est en lecture seule : aucun de ses outils ne crée, ne modifie ni ne supprime quoi que ce soit.
Mesuré le 2026-10-03 dans connectors/authentik.yaml : 442 outils, tous en méthode GET.
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/authentik.yaml |
| Protocole | API REST, chemins sous /api/v3/ |
| Authentification | jeton Authorization: Bearer, lu dans AUTHENTIK_API_KEY |
| Adresse de l'instance | variable AUTHENTIK_URL |
| Licence déclarée | MIT |
| Résidence déclarée | auto-hébergé |
Outils
Les noms d'outils sont de la forme authentik_<ressource>_<action>. Exemples réels : authentik_users_list, authentik_users_get, authentik_groups_list, authentik_applications_list, authentik_applications_check_access.
Répartition par préfixe de nom, mesurée sur les 442 outils :
| Préfixe | Outils | Préfixe | Outils |
|---|---|---|---|
stages | 80 | events | 17 |
sources | 61 | flows | 12 |
providers | 56 | rbac | 11 |
propertymappings | 45 | admin | 9 |
policies | 33 | oauth2 | 9 |
authenticators | 32 | enterprise, rac | 6 chacun |
core | 23 | crypto | 5 |
outposts | 21 | applications, managed | 4 chacun |
Les 8 autres outils se répartissent entre users et groups (2 chacun) et quatre ressources isolées (brands, root, schema, property, 1 chacune).
Les ressources users et groups n'ont chacune que deux outils : lister et lire. Il n'existe pas d'outil authentik_create_user ou authentik_delete_user.
Configuration
| Variable | Rôle |
|---|---|
AUTHENTIK_URL | Adresse de l'instance Authentik à interroger |
AUTHENTIK_API_KEY | Jeton d'API (porté en en-tête Bearer) |
Les valeurs se saisissent comme identifiants de la plateforme : page Identifiants (/credentials), fiche Authentik IAM, champs « URL du serveur » et « API Token » (ce dernier alimente AUTHENTIK_API_KEY). Le délai d'attente déclaré par le fichier est de 30 000 ms.
Déploiement
Le fichier compose du plan backend (podman-compose.yml) déploie un service Authentik pour l'authentification de la plateforme. Le fichier du plan client (podman-compose.vps2.yml) ne contient aucun service Authentik. Le connecteur ne dépend pas de ce service : il vise l'instance désignée par AUTHENTIK_URL.
Cas d'usage
- Lister les utilisateurs, groupes et applications d'une instance.
- Vérifier l'accès d'un utilisateur à une application (
authentik_applications_check_access). - Consulter les flux, fournisseurs, politiques et événements pour un audit.
Limites
- Lecture seule. Le provisionnement d'utilisateurs n'est pas fait par ce connecteur.
- Le statut du connecteur au catalogue est
available. Cela décrit l'entrée du catalogue, pas une preuve de service sur votre instance.
Fichier source
Le connecteur est déclaré dans connectors/authentik.yaml.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- SSO Authentik : le même produit, utilisé pour la connexion à la plateforme
Connecteur CalRS
CalRS est un outil de prise de rendez-vous écrit en Rust, sous licence AGPL-3.0, avec une base SQLite et le protocole CalDAV. Il est le seul connecteur d'agenda de ce type dans connectors/ : connectors/calrs.yaml (décision notée dans l'en-tête de ce fichier, ADR-0009).
Ce chapitre garde le nom de fichier calcom.md pour que les liens existants continuent de fonctionner.
Transport
CalRS n'expose pas d'API HTTP, selon l'en-tête de connectors/calrs.yaml. Le connecteur ne parle donc pas à une adresse web. Il lance une commande podman exec … calrs <sous-commande> dans le conteneur CalRS. Conséquences :
- il n'y a ni adresse d'instance, ni clé d'API, ni en-tête d'authentification à configurer ;
- l'autorisation est celle du socket Podman, en amont du connecteur ;
- aucune variable d'environnement n'est lue par ce connecteur.
Le nom d'identifiant historique calcomApi existe encore côté plateforme. Il est rattaché au connecteur calrs et ne publie aucune variable d'environnement (table de correspondance des identifiants du code, entrée calcomApi).
Outils
Mesuré le 2026-10-03 : 7 outils déclarés dans connectors/calrs.yaml. Le client Rust qui les exécute est crates/forge-mcp/src/connector/calrs_cli_client.rs.
| Outil | Rôle |
|---|---|
list_bookings | Lister les rendez-vous réservés |
show_calendar | Afficher le calendrier |
list_event_types | Lister les types de rendez-vous |
list_slots | Lister les créneaux disponibles d'un type de rendez-vous (paramètre slug obligatoire, days optionnel) |
create_booking | Créer un rendez-vous |
cancel_booking | Annuler un rendez-vous |
create_event_type | Créer un type de rendez-vous |
Trois de ces outils écrivent : create_booking, cancel_booking, create_event_type.
Déploiement
Un service CalRS figure dans podman-compose.vps2.yml, avec une image construite localement et un volume de données. Un commentaire de ce fichier le classe « catalogue » et précise qu'il est hors des plans thérapeute depuis le 2026-07-08.
Le connecteur n'a de sens que si le conteneur CalRS tourne sur la même machine que le processus qui lance la commande.
Limites
- Aucun outil de disponibilité par utilisateur :
list_slotstravaille sur un type de rendez-vous identifié par sonslug. - Le conteneur déployé ne contient aucun type de rendez-vous par défaut. Il faut en créer un (
create_event_type) avant de lister des créneaux. Cette remarque vient d'une mesure du 2026-08-30 consignée dans le YAML. - L'entrée du catalogue métier (
calrs, catégorie Scheduling) a le statutavailable.
Fichiers sources
Le connecteur est déclaré dans connectors/calrs.yaml et exécuté par crates/forge-mcp/src/connector/calrs_cli_client.rs.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- Déploiement Podman : plan client, réseaux et unités où tourne le conteneur CalRS
Connecteur Dolibarr
Dolibarr est un ERP/CRM open source pour petites structures. Le connecteur lit l'API REST de Dolibarr. Il est en lecture seule : il n'existe aucun outil de création, de modification ni de suppression.
Mesuré le 2026-10-03 dans connectors/dolibarr.yaml : 263 outils, tous en méthode GET (156 de type liste, 107 de type lecture d'un enregistrement).
Ce connecteur n'est pas appelable aujourd'hui : son identifiant ne figure pas dans la liste des serveurs autorisés (section Déploiement plus bas). Vous pouvez enregistrer ses identifiants, mais tools/list n'affiche pas ses outils et un appel est refusé.
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/dolibarr.yaml |
| Protocole | API REST, chemins sous /api/index.php/ |
| Authentification | clé d'API en en-tête DOLAPIKEY, lue dans DOLIBARR_API_KEY |
| Adresse de l'instance | variable DOLIBARR_URL |
| Licence déclarée | GPL-3.0 |
| Résidence déclarée | auto-hébergé |
Le fichier indique que les outils ont été vérifiés contre la documentation officielle de l'API REST de Dolibarr (consultée le 2026-06-24) et que les écritures (POST, PUT) sont exclues par choix.
Outils
Les noms suivent deux formes : list_<ressource> et get_<ressource>…. Exemples réels : list_thirdparties, get_thirdparty, list_invoices, get_invoice, list_proposals, list_orders, list_products, list_bankaccounts.
Ressources les mieux couvertes, par nombre d'outils dont un segment du nom (séparé par _) est la ressource, mesuré sur les 263 outils :
| Ressource | Outils |
|---|---|
setup (paramétrage) | 45 |
products | 25 |
thirdparties (tiers) | 17 |
members (adhérents) | 13 |
invoices, projects | 9 chacune |
users, orders, bankaccounts, tasks | 8, 7, 6 et 6 |
proposals, recruitments | 5 chacune |
Le reste couvre des ressources plus petites : contrats, interventions, tickets, notes de frais, salaires, entrepôts, mouvements de stock, factures fournisseurs.
Configuration
| Variable | Rôle |
|---|---|
DOLIBARR_URL | Adresse de l'instance Dolibarr |
DOLIBARR_API_KEY | Clé d'API, envoyée dans l'en-tête DOLAPIKEY |
Dans l'application : page Identifiants (/credentials), fiche Dolibarr, champs « URL du serveur » et « API Key ».
Déploiement
Ni podman-compose.vps2.yml ni podman-compose.yml ne déploient Dolibarr. Le connecteur vise une instance que vous fournissez. L'entrée du catalogue métier a le statut coming-soon.
L'identifiant dolibarr ne figure pas dans ALLOWED_MCP_SERVERS (liste des serveurs autorisés du code). Le fichier se charge, mais ses outils n'apparaissent pas dans tools/list et le dispatch les refuse (un test du dépôt le verrouille).
Limites
- Lecture seule. Créer un devis ou une facture n'est pas possible avec ce connecteur.
- Quatre outils portent le préfixe
dolibarr_(par exempledolibarr_get_mos,dolibarr_list_users_groups), les 259 autres non : le nommage n'est pas uniforme.
Fichier source
Le connecteur est déclaré dans connectors/dolibarr.yaml.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- Odoo : l'autre ERP/CRM du livre, avec des outils d'écriture
Connecteur Forgejo
Forgejo est une forge logicielle auto-hébergeable (dépôts Git, tickets, demandes de fusion, versions). Le connecteur appelle son API REST v1, compatible Gitea.
Mesuré le 2026-10-03 dans connectors/forgejo.yaml : 482 outils.
| Méthode HTTP | Outils |
|---|---|
| GET | 248 |
| POST | 93 |
| DELETE | 80 |
| PATCH | 32 |
| PUT | 29 |
Le connecteur lit donc 248 ressources et en modifie 234. Il peut supprimer des dépôts, des branches, des versions et des webhooks.
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/forgejo.yaml |
| Protocole | API REST, chemins sous /api/v1/ |
| Authentification | jeton Authorization: Bearer, lu dans FORGEJO_API_KEY |
| Adresse de l'instance | variable FORGEJO_URL |
| Licence déclarée | MIT |
| Résidence déclarée | auto-hébergé |
Outils
Les noms n'ont pas de préfixe de connecteur : repos_list, repos_create, issues_create, pulls_merge, branches_protect, releases_create, webhooks_create.
Répartition par préfixe de nom, mesurée sur les 482 outils (les préfixes repos et repo sont deux familles distinctes dans le fichier) :
| Préfixe | Outils | Préfixe | Outils |
|---|---|---|---|
repos | 117 | issue | 19 |
repo | 63 | issues | 11 |
user | 60 | pulls | 10 |
admin | 41 | users | 10 |
orgs | 28 | branches | 8 |
org | 28 | teams | 7 |
Les préfixes restants (get, list, releases, activitypub, webhooks, labels, milestones, tags, packages, notify, settings, commits, notifications, markdown, et quelques autres) totalisent 80 outils.
Opérations couvertes par des outils nommés : création, lecture, modification et suppression de dépôts ; tickets avec commentaires, étiquettes et assignations ; demandes de fusion avec diff, revues et fusion ; branches avec protection ; versions ; webhooks ; étiquettes et jalons ; organisations et équipes ; paquets ; administration.
Configuration
| Variable | Rôle |
|---|---|
FORGEJO_URL | Adresse de l'instance Forgejo |
FORGEJO_API_KEY | Jeton d'API (la variable FORGEJO_API_TOKEN n'est lue nulle part) |
Dans l'application : page Identifiants (/credentials), fiche Forgejo Git, champs « URL du serveur » et « Access Token » (ce dernier alimente FORGEJO_API_KEY).
Le délai d'attente déclaré est de 30 000 ms.
Déploiement
podman-compose.vps2.yml contient un service Forgejo (image officielle épinglée, base SQLite, ports liés à la boucle locale). Un commentaire de ce fichier précise qu'il est conservé pour la pile de développement du poste, et qu'il ne fait plus partie du plan client déployé depuis le 2026-09-10. Pour un usage client, le connecteur vise l'instance désignée par FORGEJO_URL.
L'entrée du catalogue métier a le statut coming-soon.
Limites
- La licence MIT est celle que déclare le fichier YAML. Vérifiez la licence de la version de Forgejo que vous installez.
- Les outils de lecture et d'écriture sont dans le même connecteur : les droits réels dépendent du jeton fourni.
Fichier source
Le connecteur est déclaré dans connectors/forgejo.yaml.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- Migration depuis d'autres outils : équivalents européens des services hors UE, forge logicielle comprise
Connecteur FreeScout
FreeScout est un outil de support client auto-hébergeable, sous licence AGPL-3.0. Le connecteur lit les conversations, clients et boîtes de réception via l'API REST de FreeScout. Il est en lecture seule.
Mesuré le 2026-10-03 dans connectors/freescout.yaml : 15 outils, tous en méthode GET.
Ce connecteur n'est pas appelable aujourd'hui : son identifiant ne figure pas dans la liste des serveurs autorisés (section Déploiement plus bas). Vous pouvez enregistrer ses identifiants, mais tools/list n'affiche pas ses outils et un appel est refusé.
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/freescout.yaml |
| Protocole | API REST, chemins sous /api/ |
| Authentification | clé d'API en en-tête X-FreeScout-API-Key, lue dans FREESCOUT_API_KEY |
| Adresse de l'instance | variable FREESCOUT_URL |
| Licence déclarée | AGPL-3.0 |
| Statut amont | a_verifier |
Le statut a_verifier est celui que porte le fichier. Dans le dépôt, il signifie qu'aucune sonde n'a encore établi qu'un amont répond (référentiel de statut amont du dépôt). Les outils sont donc vérifiés contre le contrat déclaré de l'API, pas contre une réponse réelle.
Outils
| Outil | Rôle |
|---|---|
list_conversations | Lister les conversations (filtres : boîte, statut, page) |
get_conversation | Lire une conversation avec ses échanges |
list_mailboxes | Lister les boîtes de réception |
list_mailbox_folders | Lister les dossiers d'une boîte |
list_mailbox_custom_fields | Lister les champs personnalisés d'une boîte |
list_customers | Lister les clients |
get_customer | Lire un client |
list_tags | Lister les étiquettes |
list_timelogs | Lister les temps passés |
list_conversation_timelogs | Lister les temps passés sur une conversation |
list_users | Lister les agents |
get_user | Lire un agent |
get_current_user | Lire l'utilisateur de la clé |
list_webhooks | Lister les webhooks |
get_report | Lire un rapport |
Le fichier précise que les 14 opérations d'écriture de l'API FreeScout ont été laissées de côté sur décision du titulaire, le 2026-09-04. Répondre à un ticket, changer un statut ou assigner une conversation n'est donc pas possible avec ce connecteur.
Configuration
| Variable | Rôle |
|---|---|
FREESCOUT_URL | Adresse de l'instance FreeScout |
FREESCOUT_API_KEY | Clé d'API |
Dans l'application : page Identifiants (/credentials), fiche FreeScout Helpdesk, champs « URL du serveur » et « API Key ».
Déploiement
Ni podman-compose.vps2.yml ni podman-compose.yml ne déploient FreeScout. Le connecteur vise une instance que vous fournissez. L'entrée du catalogue métier a le statut coming-soon.
L'identifiant freescout ne figure pas dans ALLOWED_MCP_SERVERS (liste des serveurs autorisés du code). Le fichier se charge, mais ses outils n'apparaissent pas dans tools/list et le dispatch les refuse (un test du dépôt le verrouille).
Cas d'usage
- Retrouver une conversation ou un client par l'agent.
- Consulter les temps passés et les rapports.
Fichier source
Le connecteur est déclaré dans connectors/freescout.yaml.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- Utiliser les connecteurs MCP : fiches de connecteurs présentes et consultation du catalogue par l'API
Connecteur Listmonk
Listmonk est un gestionnaire de lettres d'information et de listes de diffusion, sous licence AGPL-3.0. Le connecteur appelle son API REST.
Mesuré le 2026-10-03 dans connectors/listmonk.yaml : 76 outils.
| Méthode HTTP | Outils |
|---|---|
| GET | 31 |
| POST | 17 |
| PUT | 15 |
| DELETE | 13 |
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/listmonk.yaml |
| Protocole | API REST, chemins sous /api/ |
| Authentification | HTTP Basic : identifiant dans LISTMONK_API_USER, secret dans LISTMONK_API_KEY |
| Adresse de l'instance | variable LISTMONK_URL |
| Licence déclarée | AGPL-3.0 |
| Résidence déclarée | auto-hébergé |
Outils
La plupart des outils portent le préfixe listmonk_. 17 outils n'en ont pas, par exemple get_bounces ou get_campaign_analytics.
| Domaine | Exemples réels |
|---|---|
| Abonnés | listmonk_list_subscribers, listmonk_create_subscriber, listmonk_blocklist_subscriber, listmonk_search_subscribers, export_subscriber_data_by_id |
| Listes | listmonk_list_lists, listmonk_create_list, listmonk_get_list_subscribers |
| Campagnes | listmonk_list_campaigns, listmonk_create_campaign, listmonk_start_campaign, listmonk_pause_campaign, listmonk_get_campaign_stats, get_campaign_analytics |
| Modèles | listmonk_list_templates, listmonk_create_template, listmonk_preview_template |
| Transactionnel | listmonk_send_transactional |
| Rebonds | get_bounces, get_bounce_by_id, listmonk_bounces_delete |
| Médias et imports | get_media, listmonk_media_create, listmonk_import_subscribers_create |
| Réglages et maintenance | listmonk_settings_update, listmonk_maintenance_subscribers_delete |
Il n'existe pas d'outil d'annulation de campagne nommé comme tel : les outils de pilotage d'une campagne sont listmonk_start_campaign et listmonk_pause_campaign.
Des outils de suppression en masse existent (listmonk_subscribers_query_delete_create, listmonk_maintenance_subscribers_delete). Ils agissent sur des abonnés réels.
Configuration
| Variable | Rôle |
|---|---|
LISTMONK_URL | Adresse de l'instance Listmonk |
LISTMONK_API_USER | Identifiant de l'utilisateur d'API |
LISTMONK_API_KEY | Secret de l'utilisateur d'API |
Dans l'application : page Identifiants (/credentials), fiche Listmonk Newsletter, champs « URL du serveur », « Username » (qui alimente LISTMONK_API_USER) et « API Token » (qui alimente LISTMONK_API_KEY).
Les variables LISTMONK_USERNAME et LISTMONK_PASSWORD ne sont lues par aucun connecteur.
Déploiement
podman-compose.vps2.yml déploie un service Listmonk (image officielle, base Postgres partagée, volume pour les médias téléversés). L'entrée du catalogue métier a le statut coming-soon.
Fichier source
Le connecteur est déclaré dans connectors/listmonk.yaml.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- Migration depuis d'autres outils : Listmonk parmi les remplaçants d'un service de courriel marketing hors UE
Connecteur Matomo
Matomo est un outil d'analyse d'audience web, sous licence GPL-3.0, que l'on peut héberger soi-même. Le connecteur interroge son API de rapports. Il est en lecture seule.
Mesuré le 2026-10-03 dans connectors/matomo.yaml : 113 outils, tous en méthode GET.
Pourquoi seulement de la lecture
L'API de Matomo modifie des données par des requêtes GET. Une passe de correction du 2026-06-25, consignée dans le fichier, a donc retiré 29 outils de mutation (création et modification d'objectifs, de sites, d'utilisateurs, de segments, d'alertes, anonymisation, suppression de données de personnes). Il reste 113 méthodes de rapport. generate_report et export_data_subjects sont conservés : ils renvoient des données.
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/matomo.yaml |
| Protocole | API de rapports, chemin unique /index.php |
| Authentification | jeton token_auth passé en paramètre de requête, lu dans MATOMO_API_KEY |
| Adresse de l'instance | variable MATOMO_URL |
| Licence déclarée | GPL-3.0 |
| Résidence déclarée | auto-hébergé |
Le jeton voyage dans l'URL de la requête, parce que Matomo n'accepte pas d'en-tête d'authentification pour cette API (explication consignée dans le fichier). Gardez-le hors de tout journal d'accès que vous ne maîtrisez pas.
Outils
Les noms n'ont pas de préfixe de connecteur. Chaque outil prend en paramètres idSite (entier), period et date. Il n'existe pas de variable MATOMO_SITE_ID : le site se choisit à chaque appel.
Exemples réels :
| Besoin | Outils |
|---|---|
| Visites | get_visits_summary, get_visits, get_unique_visitors, get_actions, get_bounce_count |
| Pages | get_page_urls, get_page_titles, get_entry_page_urls, get_exit_page_urls |
| Sources de trafic | get_referrer_type, get_all_referrers, get_keywords, get_search_engines, get_socials |
| Objectifs et conversions | get_goals, get_goal, get_conversions |
| Audience | get_country, get_city, get_device_type, get_browsers, get_os_families |
| Détail des visites | get_last_visits_details, get_visitor_profile, get_counters |
| Données personnelles | export_data_subjects |
Il n'existe pas d'outil nommé get_live_visitors. Les visites récentes se lisent avec get_last_visits_details.
Configuration
| Variable | Rôle |
|---|---|
MATOMO_URL | Adresse de l'instance Matomo |
MATOMO_API_KEY | Jeton d'authentification de l'API |
Dans l'application : page Identifiants (/credentials), fiche Matomo Analytics, champs « URL du serveur », « Site ID » et « API Token » (ce dernier alimente MATOMO_API_KEY). Le champ « Site ID » est demandé par le formulaire, mais le connecteur ne le lit pas : indiquez le site (idSite) à chaque appel.
Les variables MATOMO_TOKEN et MATOMO_SITE_ID ne sont lues par aucun connecteur.
Déploiement
podman-compose.vps2.yml déploie Matomo (image officielle épinglée) avec une base MariaDB dédiée. L'entrée du catalogue métier a le statut available.
Exemple
Combien de visiteurs uniques sur le site 1 la semaine dernière ?
L'agent choisit get_unique_visitors avec idSite, period et date.
Fichier source
Le connecteur est déclaré dans connectors/matomo.yaml.
Voir aussi
- Vue d'ensemble : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP : forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP : ouvrir une session et appeler un outil par JSON-RPC
- Tarification : nombre de connecteurs métier inclus dans chaque offre
- RGPD : droits des personnes, en regard de l'outil d'export des données
Connecteur n8n
n8n est un outil d'automatisation de workflows. Le connecteur appelle l'API publique REST de n8n pour lister, créer, activer et supprimer des workflows, et pour lire les exécutions.
Mesuré le 2026-10-03 dans connectors/n8n.yaml : 49 outils.
| Méthode HTTP | Outils |
|---|---|
| GET | 20 |
| POST | 12 |
| DELETE | 8 |
| PUT | 7 |
| PATCH | 2 |
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/n8n.yaml |
| Protocole | API REST, chemins sous /api/v1/ |
| Authentification | clé d'API en en-tête X-N8N-API-KEY, lue dans N8N_API_KEY |
| Adresse de l'instance | variable N8N_URL |
| Licence déclarée | Sustainable-Use (fair-code, source disponible) |
Le catalogue métier la libelle « Sustainable-Use (fair-code, source-available) ».
Outils
Les noms n'ont pas de préfixe de connecteur. Répartition par ressource, mesurée sur les 49 outils :
| Ressource | Outils | Exemples réels |
|---|---|---|
workflows | 12 | workflows_list, workflows_get, workflows_create, workflows_activate, workflows_deactivate, workflows_delete |
projects | 8 | projects_list, projects_create, projects_users_create |
executions | 7 | executions_list, executions_get, executions_retry, executions_list_failed |
tags | 6 | tags_list, tags_create |
users | 5 | users_list, users_change_role |
variables | 5 | variables_list, variables_create |
credentials | 4 | credentials_create, credentials_get_schema |
sourcecontrol, audit | 1 chacune | sourcecontrol_pull, audit_create |
Il n'existe pas d'outil qui lance un workflow à la demande : ni n8n_execute_workflow, ni équivalent. Le connecteur sait activer ou désactiver un workflow, relancer une exécution (executions_retry) et lire l'historique.
Le connecteur crée et supprime aussi des utilisateurs, des identifiants et des variables d'une instance n8n. Donnez à la clé d'API les seuls droits nécessaires.
Huit chemins de confort qui n'existent pas
Un avertissement du 2026-09-05, en tête du fichier, rapporte une mesure sur une instance vivante. Huit outils de commodité (comptage des exécutions, statistiques, workflows actifs, utilisateur courant) visaient des chemins absents de la spécification que sert n8n lui-même. Vérifié le 2026-10-03 : aucun de ces huit noms ne figure parmi les 49 outils actuels. La capacité existe en passant par les chemins réels (par exemple la liste des exécutions avec un filtre de statut) ; elle est à reprendre, pas à supposer.
Configuration
| Variable | Rôle |
|---|---|
N8N_URL | Adresse de l'instance n8n |
N8N_API_KEY | Clé d'API n8n |
Dans l'application : page Identifiants (/credentials), fiche n8n Automation, champs « URL du serveur » et « API Key ».
Le connecteur envoie le User-Agent mgaas-connector/1.0. Un User-Agent contenant « bot » fait répondre n8n par un corps vide (mesure du 2026-07-03 consignée dans le fichier).
Déploiement
podman-compose.vps2.yml déploie un service n8n (image officielle, base Postgres partagée, volume qui conserve la clé de chiffrement de n8n). L'entrée du catalogue métier a le statut available.
Exemple
Active le workflow « Synchronisation clients ».
L'agent retrouve le workflow avec workflows_list, puis appelle workflows_activate.
Fichier source
connectors/n8n.yaml
Voir aussi
- Vue d'ensemble — chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP — forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP — ouvrir une session et appeler un outil par JSON-RPC
- Tarification — nombre de connecteurs métier inclus dans chaque offre
- Migration depuis d'autres outils — coexister avec une instance n8n existante pendant la migration
Connecteur Nextcloud
Nextcloud est une plateforme de fichiers et de collaboration sous licence AGPL-3.0. Le connecteur appelle ses interfaces WebDAV et OCS (REST).
Mesuré le 2026-10-03 dans connectors/nextcloud.yaml : 167 outils.
| Méthode HTTP | Outils |
|---|---|
| GET | 89 |
| POST | 40 |
| DELETE | 21 |
| PUT | 16 |
| PATCH | 1 |
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/nextcloud.yaml |
| Protocole | WebDAV (/remote.php/dav/…) et OCS (/ocs/v2.php/…) |
| Authentification | HTTP Basic : identifiant dans NEXTCLOUD_API_USER, secret dans NEXTCLOUD_API_KEY |
| Adresse de l'instance | variable NEXTCLOUD_URL |
| En-têtes fixes | OCS-APIRequest: true, Accept: application/json |
| Licence déclarée | AGPL-3.0 |
| Résidence déclarée | auto-hébergé |
L'en-tête Accept est nécessaire : sans lui, OCS répond en XML étiqueté JSON (remarque consignée dans le fichier).
Outils
Tous les noms commencent par nc_. Répartition par famille, pour les principales :
| Famille | Outils | Exemples réels |
|---|---|---|
nc_share | 15 | nc_share_create, nc_share_list, nc_share_get_shared_with_me, nc_share_accept |
nc_cloud | 15 | nc_cloud_capabilities_list |
nc_apps | 14 | (interfaces des applications Nextcloud) |
nc_core | 14 | nc_core_preview_list |
nc_user | 12 | nc_user_create, nc_user_set_quota, nc_user_add_to_group |
nc_deck | 10 | nc_deck_list_boards, nc_deck_create_card |
nc_taskprocessing | 9 | nc_taskprocessing_schedule_create |
nc_group, nc_app | 6 chacune | nc_group_create, nc_app_install |
Les 66 autres outils se répartissent en petites familles (notifications, activité, références, traduction, texte vers image, étiquettes, avatars, entre autres).
Fichiers : quatre outils seulement, nc_file_get, nc_file_upload, nc_file_download, nc_file_delete, tous sur le chemin WebDAV /remote.php/dav/files/{username}{path}. Aucun outil déclaré ne crée un dossier ni ne liste le contenu d'un dossier, parce que le fichier n'utilise que les méthodes GET, POST, PUT, PATCH et DELETE.
Contacts : trois outils (nc_contact_get, nc_contact_create, nc_contact_update) sur CardDAV. Agenda : un seul outil, nc_calendar_delete. Il n'existe pas d'outil pour lire ou créer des événements de calendrier.
Le connecteur gère aussi les comptes (nc_user_*, nc_group_*) et les applications (nc_app_install, nc_app_remove). Une identité d'administrateur lui donne ces pouvoirs ; préférez un compte restreint.
Configuration
| Variable | Rôle |
|---|---|
NEXTCLOUD_URL | Adresse de l'instance Nextcloud |
NEXTCLOUD_API_USER | Nom d'utilisateur |
NEXTCLOUD_API_KEY | Secret associé à l'identifiant (Basic) |
Dans l'application : page Identifiants (/credentials), fiche Nextcloud, champs « URL du serveur », « Username » (qui alimente NEXTCLOUD_API_USER) et « App Password (revocable) » (qui alimente NEXTCLOUD_API_KEY). Générez ce mot de passe d'application dans les réglages de sécurité de Nextcloud : ce n'est pas votre mot de passe principal.
Les variables NEXTCLOUD_USERNAME et NEXTCLOUD_PASSWORD ne sont lues par aucun connecteur.
Déploiement
Ni podman-compose.vps2.yml ni podman-compose.yml ne déploient Nextcloud. Le connecteur vise une instance que vous fournissez. L'entrée du catalogue métier a le statut available.
Fichier source
connectors/nextcloud.yaml
Voir aussi
- Vue d'ensemble — chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP — forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP — ouvrir une session et appeler un outil par JSON-RPC
- Tarification — nombre de connecteurs métier inclus dans chaque offre
- Limites — la plateforme ne stocke pas de fichiers, ils restent dans l'outil connecté
Connecteur Odoo
Le connecteur Odoo pilote une instance Odoo par le protocole XML-RPC. Parmi les douze connecteurs décrits dans ce livre, c'est celui qui expose le plus d'outils : 711 outils nommés au registre, mesurés le 2026-10-03.
Deux endroits où se compter
Le fichier connectors/odoo.yaml ne déclare que 6 outils (crm.search_leads, crm.create_lead, sale.list_orders, account.list_invoices, hr.list_employees, project.list_tasks). Les 711 outils nommés vivent dans le registre Rust crates/forge-mcp/src/connector/odoo_tools_registry.rs. Un test du dépôt affirme ce nombre. Le site public affiche le même chiffre (OUTILS_ODOO dans crates/forge-ui/src/config/chiffres_mesures.rs).
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/odoo.yaml |
| Protocole | XML-RPC (type odoo) |
| Licence déclarée | LGPL-3.0 |
| Résidence déclarée | auto-hébergé |
Il n'y a pas de bloc auth : le connecteur lit quatre valeurs de connexion.
Configuration
| Variable | Rôle |
|---|---|
ODOO_URL | Adresse de l'instance Odoo |
ODOO_DATABASE | Nom de la base de données |
ODOO_USERNAME | Identifiant de connexion |
ODOO_API_KEY | Clé d'API Odoo (obligatoire : le fichier la déclare avec :?, sans valeur par défaut) |
Les variables ODOO_DB et ODOO_PASSWORD ne sont lues par aucun connecteur.
Parcours complet, avec la fiche Odoo ERP/CRM et un premier appel : Connecter Odoo à la passerelle MCP.
Pour un locataire, les valeurs sont saisies comme identifiants de la plateforme et stockées chiffrées. Une organisation peut en plus stocker un AppRole OpenBao : l'URL, la base et la clé sont alors lues depuis OpenBao en priorité, au moment de la requête (résolution des identifiants du code, entrée odooApi).
Outils nommés
Mesure du 2026-10-03 sur les 711 entrées du registre, par opération :
| Opération | Outils |
|---|---|
search | 148 |
read | 120 |
group (agrégat en lecture) | 5 |
create | 113 |
update | 105 |
delete | 103 |
action (confirmer, valider, archiver, entre autres) | 117 |
Les lectures (search, read, group) sont donc 273. Les 438 autres modifient des données. Les 711 outils visent 140 modèles Odoo. Les noms sont de la forme <module>_<objet>_<action>.
Exemples réels, tous présents au registre :
| Domaine | Outils |
|---|---|
| Contacts | contacts_search, contacts_create, contacts_merge, contacts_export_gdpr |
| CRM | crm_lead_create, crm_lead_convert, crm_lead_won |
| Ventes | sales_order_search, sales_order_create, sales_order_confirm |
| Achats | purchase_order_confirm |
| Facturation | invoice_search, invoice_create, invoice_post |
| Stock | inventory_product_search |
| Ressources humaines | hr_employee_search (87 outils portent le préfixe hr) |
| Projets | project_task_create |
| Site et contenu | website_page_search, blog_post_create |
Les préfixes les mieux fournis sont hr (87 outils), inventory (51), sales (43), website (39), mrp (35) et crm (34).
Les anciens noms odoo_search_read, odoo_sale_order_list et odoo_invoice_validate n'existent pas au registre. Les noms informels sont rapprochés des noms canoniques à l'appel par odoo_tool_resolver.
Quatre outils génériques
Quatre outils prennent le modèle en argument : record_create, record_read, record_update, record_delete (crates/forge-mcp/src/connector/odoo_generic_crud.rs). Ils ne fonctionnent que sur une liste blanche de 402 modèles métier (odoo_metier_models.rs). Le framework, les rapports, la messagerie et la sécurité en sont exclus.
Écritures gardées
Parmi ces 402 modèles, 24 sont gardés en écriture : plan de comptes, journaux, taxes, lignes d'écriture comptable, relevés bancaires, entre autres. Une création, une modification ou une suppression sur l'un d'eux exige une approbation humaine via /actions/approvals. Elle n'est jamais exécutée seule par l'agent. La lecture de ces modèles reste libre.
Déploiement
podman-compose.vps2.yml déploie 17 services Odoo, un par secteur (thérapie, médical, juridique, immobilier, finance, entre autres). L'entrée du catalogue métier (odoo, catégorie CRM & ERP) a le statut available.
Limites techniques
- Le client HTTP du connecteur a un délai d'attente de 30 secondes.
- L'identifiant utilisateur obtenu à la connexion est gardé en mémoire 600 secondes, puis redemandé.
Exemple
Quels sont les contacts créés cette semaine dans Odoo ?
L'agent choisit un outil de recherche sur les contacts (contacts_search), construit le filtre et exécute l'appel XML-RPC.
Fichiers sources
connectors/odoo.yaml, crates/forge-mcp/src/connector/odoo_tools_registry.rs, crates/forge-mcp/src/connector/odoo_generic_crud.rs, crates/forge-mcp/src/connector/odoo_metier_models.rs
Voir aussi
- Vue d'ensemble — chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP — forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP — ouvrir une session et appeler un outil par JSON-RPC
- Tarification — nombre de connecteurs métier inclus dans chaque offre
- Connecter Odoo à la passerelle MCP — enregistrer les identifiants Odoo puis appeler un premier outil
Connecteur Rocket.Chat
Rocket.Chat est une messagerie d'équipe auto-hébergeable. Le connecteur appelle son API REST v1.
Mesuré le 2026-10-03 dans connectors/rocketchat.yaml : 338 outils.
| Méthode HTTP | Outils |
|---|---|
| GET | 279 |
| POST | 58 |
| PUT | 1 |
L'API de Rocket.Chat écrit par POST, y compris pour supprimer : rc_channel_delete et rc_message_delete sont des POST.
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/rocketchat.yaml |
| Protocole | API REST, chemins sous /api/v1/ |
| Authentification | jeton en en-tête X-Auth-Token, lu dans ROCKETCHAT_API_KEY |
| Identifiant d'utilisateur | en-tête X-User-Id, lu dans ROCKETCHAT_USER_ID |
| Adresse de l'instance | variable ROCKETCHAT_URL |
| Licence déclarée | MIT |
| Résidence déclarée | auto-hébergé |
Outils
Tous les noms commencent par rc_. Répartition par famille, pour les principales :
| Famille | Outils | Exemples réels |
|---|---|---|
rc_livechat | 83 | rc_livechat_agent_info_get |
rc_chat, rc_rooms | 14 chacune | rc_chat_getmentionedmessages_list |
rc_users | 13 | rc_users_autocomplete_list |
rc_channel | 12 | rc_channel_create, rc_channel_invite, rc_channel_archive, rc_channel_set_topic |
rc_user, rc_dm | 12 chacune | rc_user_create, rc_dm_create, rc_dm_history |
rc_message | 10 | rc_message_send, rc_message_search, rc_message_history, rc_message_pin, rc_message_react |
rc_group, rc_team, rc_channels | 10 chacune | rc_group_create, rc_team_create |
Les autres familles couvrent les intégrations et webhooks (rc_integration_*, 8 outils), les rôles (rc_role_*, 6), les abonnements, les réglages (rc_setting_*), la modération, l'omnicanal, les statistiques et l'administration. Sur les 62 familles de noms, 33 ne comptent qu'un ou deux outils.
La famille rc_livechat est la première par le nombre : elle concerne le chat en direct pour visiteurs et représente 83 outils sur 338.
Configuration
| Variable | Rôle |
|---|---|
ROCKETCHAT_URL | Adresse de l'instance Rocket.Chat |
ROCKETCHAT_API_KEY | Jeton d'authentification personnel |
ROCKETCHAT_USER_ID | Identifiant de l'utilisateur propriétaire du jeton |
La variable ROCKETCHAT_AUTH_TOKEN n'est lue par aucun connecteur. Le délai d'attente déclaré est de 30 000 ms.
Dans l'application : page Identifiants (/credentials), fiche Rocket.Chat, champs « URL du serveur », « User ID » et « Auth Token ». Le champ « Auth Token » alimente ROCKETCHAT_API_KEY.
Déploiement
Ni podman-compose.vps2.yml ni podman-compose.yml ne déploient Rocket.Chat. Le connecteur vise une instance que vous fournissez. L'entrée du catalogue métier a le statut coming-soon.
Cas d'usage
- Envoyer un message dans un canal (
rc_message_send). - Rechercher dans l'historique (
rc_message_search). - Créer un canal ou une conversation directe.
Fichier source
connectors/rocketchat.yaml
Voir aussi
- Vue d'ensemble — chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP — forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP — ouvrir une session et appeler un outil par JSON-RPC
- Tarification — nombre de connecteurs métier inclus dans chaque offre
- Migration depuis d'autres outils — Rocket.Chat parmi les messageries d'équipe européennes de remplacement
Connecteur Typesense
Typesense est un moteur de recherche en texte intégral, tolérant aux fautes de frappe, sous licence GPL-3.0. Le connecteur appelle son API REST pour chercher, gérer les collections et les documents, et administrer le cluster.
Mesuré le 2026-10-03 dans connectors/typesense.yaml : 79 outils.
| Méthode HTTP | Outils |
|---|---|
| GET | 36 |
| POST | 16 |
| DELETE | 14 |
| PUT | 10 |
| PATCH | 3 |
Ce que déclare le fichier
| Propriété | Valeur |
|---|---|
| Fichier | connectors/typesense.yaml |
| Protocole | API REST |
| Authentification | clé d'API en en-tête X-TYPESENSE-API-KEY, lue dans TYPESENSE_API_KEY |
| Adresse de l'instance | variable TYPESENSE_URL |
| Licence déclarée | GPL-3.0 |
| Résidence déclarée | auto-hébergé |
Outils
Les noms n'ont pas de préfixe de connecteur. Répartition par préfixe, mesurée sur les 79 outils :
| Préfixe | Outils | Exemples réels |
|---|---|---|
collections | 10 | collections_create, collections_delete, collections_documents_import_create |
analytics | 9 | analytics_rules_create, analytics_events_list |
curation | 8 | curation_sets_list, curation_sets_items_update |
synonym | 8 | synonym_sets_list, synonym_sets_items_update |
list, get | 5 chacun | list_collections, list_keys, list_aliases, get_health, get_stats, get_metrics, get_debug |
conversations, nl, operations | 5 chacun | nl_search_models_create, operations_snapshot_create |
aliases, keys, presets, stemming, stopwords | 3 chacun | aliases_update, keys_create |
search, documents, config, multi | 1 chacun | search, documents_export, multi_search_create |
search interroge /collections/{collection}/documents/search. Les opérations d'administration du cluster (operations_snapshot_create, operations_db_compact_create, operations_cache_clear_create) sont des outils d'écriture.
L'import en masse existe (collections_documents_import_create). Il n'existe pas d'outil de clonage de collection.
Configuration
| Variable | Rôle |
|---|---|
TYPESENSE_URL | Adresse de l'instance Typesense |
TYPESENSE_API_KEY | Clé d'API (en-tête X-TYPESENSE-API-KEY) |
Dans l'application : page Identifiants (/credentials), fiche Typesense Search, champs « URL du serveur » et « API Key ».
Le connecteur expose des outils d'écriture et de suppression (14 DELETE) : les droits effectifs sont ceux de la clé fournie.
Déploiement
podman-compose.vps2.yml déploie Typesense (image officielle épinglée, volume de données, port lié à la boucle locale). L'entrée du catalogue métier a le statut coming-soon.
Fichier source
connectors/typesense.yaml
Voir aussi
- Vue d'ensemble — chiffres mesurés, chargement et règles communes aux douze connecteurs
- Créer votre premier connecteur MCP — forme d'un fichier YAML et ajout d'un connecteur à la passerelle
- Routes MCP — ouvrir une session et appeler un outil par JSON-RPC
- Tarification — nombre de connecteurs métier inclus dans chaque offre
- Connaissances — collections et recherche vectorielle gérées par la plateforme elle-même
Architecture Chatbotaurus
Chatbotaurus est une plateforme MGaaS (MCP Gateway as a Service) européenne et souveraine, écrite en Rust. Elle combine un agent conversationnel, une passerelle MCP alimentée par des connecteurs déclarés en YAML, et une infrastructure auto-hébergeable sous Podman.
À la fin de ce chapitre, vous saurez situer chaque composant, dire dans quel plan il tourne et quelle page détaille son exploitation.
Vue d'ensemble
La plateforme tient en quatre couches :
- Interface :
forge-ui, une seule base de code Dioxus 0.7 (binairechatbotaurus). Elle se compile en wasm pour le navigateur (fonctionnalitéweb), ou en application bureau et mobile (fonctionnalitésdesktopetmobiledecrates/forge-ui/Cargo.toml). - Backend :
forge-api, un serveur Axum qui expose/api/v1/**(REST, SSE, multipart, WebSocket), adossé à SeaORM sur PostgreSQL. Authentification, jeton CSRF, limitation de débit et contrôles de conformité UE sont des middlewares de ce crate. - Passerelle MCP : le moteur
forge-mcp(connecteurs, routage, sessions, transport Streamable HTTP). Il est monté dansforge-api(route/api/v1/mcp) et empaqueté seul dansforge-gateway, le binaire du servicemcp-gatewaydu plan client. - Infrastructure : conteneurs Podman répartis en deux plans (voir la section « Deux plans, une règle de nommage »), avec PostgreSQL, Valkey, Qdrant, OpenBao, Authentik, Ollama, la chaîne vocale et l'observabilité.
Deux plans, une règle de nommage
Le déploiement est découpé en deux projets Podman, chacun avec son réseau :
| Plan | Réseau Podman | Fichier compose | Services |
|---|---|---|---|
| Backend (notre plan) | chatbotaurus-vps1 | podman-compose.yml | forge-* |
| Client | mgaas-vps2 | podman-compose.vps2.yml | mcp-* |
La règle tient au nom du service : un conteneur nommé mcp-*
appartient au plan client, tout autre nom au plan backend. PostgreSQL et
Valkey sont rattachés aux deux réseaux (alias DNS postgres et
valkey sur mgaas-vps2) pour que les outils du plan client les
joignent par leur nom.
Figure 1 : les deux plans de déploiement, leur règle de nommage et les deux services rattachés aux deux réseaux.
En production, ces plans sont décrits par des unités Quadlet
(containers/*/*.container), l'ingress du plan backend est
forge-traefik et celui du plan client mcp-caddy. Le détail est dans
Déploiement avec Podman.
Crates du workspace
Le fichier Cargo.toml à la racine déclare ces membres :
| Crate | Rôle (description de son Cargo.toml) |
|---|---|
forge-api | Serveur HTTP Axum : API REST, transport MCP, WebSocket |
forge-core | Cœur métier : agents, RAG, workflows, anti-hallucination |
forge-mcp | Moteur de la passerelle MCP : connecteurs, routage, sessions |
forge-gateway | Binaire « serveur gateway » du plan client (service mcp-gateway) |
forge-auth | Authentification, autorisation, OIDC, TOTP, politiques Cedar |
forge-db | Couche base de données : entités SeaORM, migrations |
forge-audit | Journal d'audit à altération détectable, conformité AI Act, chaîne de Merkle |
forge-common | Primitives transverses : erreurs, cache, traces |
forge-wire | Contrats de transmission partagés entre forge-api et forge-ui |
forge-ui | Interface Dioxus multiplateforme |
forge-voice | Service vocal (STT, TTS, WebRTC) avec fournisseurs européens |
| extraction documentaire | crate prévu (spec 115, T-115-50), non encore suivi dans le dépôt ; son nom est déjà déclaré dans le Cargo.toml de l'arbre de travail (mesure du 2026-10-03) |
forge-ops | Déploiement, amorçage, diagnostics, reprise (CLI) |
forge-cli | CLI de gestion du serveur, des outils MCP et des modèles |
forge-tui | Interface terminal |
forge-docs | Pipeline de documentation mdBook (ce livre) |
forge-replay | Banc de rejeu de contrats V1/V2 |
forge-oracle | Oracle différentiel exécutable V1/V2 |
forge-test-utils | Banc de test de bout en bout |
forge-pgtest | Point de vérité unique de l'image PostgreSQL des tests |
Pile technique
| Couche | Technologie |
|---|---|
| Interface | Rust + Dioxus 0.7 |
| Backend | Rust + Axum + SeaORM + PostgreSQL + Valkey |
| Client HTTP | reqwest avec rustls (pas d'OpenSSL) |
| Authentification | JWT HS256, TOTP (RFC 6238), OIDC avec Authentik |
| Chiffrement | AES-256-GCM (aes-gcm), TLS par rustls |
| Autorisation | Cedar, politiques dans le dossier policies/ |
| Vecteurs | Qdrant (RAG) |
| Secrets | OpenBao |
| Observabilité et détection | VictoriaMetrics et VictoriaLogs (plan de développement), Beszel et CrowdSec (déployés). Falco : unité écrite, retirée du déploiement le 2026-09-19 |
| Stockage objet | SeaweedFS (S3, Apache-2.0) |
Moteur MGaaS : quatre couches
Le moteur d'orchestration vit dans crates/forge-core/src/mgaas/ :
COUCHE 1 : raisonnement
ToTLite, SelfConsistency, ChainOfVerification, MCTSLite
COUCHE 2 : orchestration d'agents
routeur MoELite, TaskDecomposer, AgentMCPRegistry
COUCHE 3 : intelligence des outils
RAREngine, DynamicToolPruner, ToolPatternMemory
COUCHE 4 : exécution et validation
SpeculativeDecoder, ParallelStreamingExecutor, GroundingEngine
Sous pression de ressources, ce moteur est conçu pour désactiver ses techniques coûteuses par paliers : voir Gestion des erreurs.
État mesuré : la route GET /api/v1/mgaas/engines
(crates/forge-api/src/routes/mgaas.rs) déclare « dormants », sans appelant de
production, neuf des douze moteurs qu'elle liste. Seuls MoELiteRouter,
TaskDecomposer et StructuredOutputValidator sont appelés en production.
Transport MCP : JSON-RPC 2.0 en Streamable HTTP
Dans forge-api, la route est montée dans crates/forge-api/src/router.rs :
POST /api/v1/mcp → JSON-RPC (initialize, tools/list, tools/call)
GET /api/v1/mcp → flux SSE de notifications
DELETE /api/v1/mcp → terminer la session
- La session est portée par l'en-tête
Mcp-Session-Id. Sa durée de vie par défaut est de 30 minutes d'inactivité (crates/forge-mcp/src/session.rs). - La version de protocole annoncée à
initializeest2025-03-26(crates/forge-mcp/src/protocol.rs). - Ces routes exigent un utilisateur authentifié, et la surface MCP peut
être coupée par l'interrupteur
MCP_ENABLED. - Le binaire
forge-gatewayexpose, lui,POST /mcpetGET /healthsur le port 8811 du plan client.
Pour explorer la flotte de connecteurs depuis l'API : GET /api/v1/mcp/catalogue
(alias GET /api/v1/mcp/catalog) et GET /api/v1/mcp-gateway/servers.
Connecteurs MCP
Chaque fichier connectors/*.yaml déclare un connecteur. Au démarrage
de forge-api, le CatalogueLoader
(crates/forge-mcp/src/connector/catalogue.rs) lit ce dossier, résout
les variables d'environnement et enregistre le connecteur dans le
registre. Le nombre de connecteurs évolue avec le dépôt : il se compte
avec ls connectors/*.yaml, jamais avec un chiffre recopié dans une
page.
Un connecteur n'est accepté que s'il passe le contrôle de conformité UE du registre : voir Conception des connecteurs MCP.
Les connecteurs couvrent notamment les ERP et CRM (Odoo, ERPNext), les outils de collaboration, le support, l'analytique, les workflows (n8n), la sécurité, l'IA et un grand nombre de sources de données publiques européennes.
Modèles et chaîne vocale
- LLM : exécutés par Ollama (service
forge-ollama). Le modèle par défaut se règle par la variableOLLAMA_MODEL, etforge-cli model pulltélécharge un modèle. - Embeddings : calculés localement (crate
fastembed,crates/forge-core/src/rag/embedder.rs). La dimension des vecteurs est lue à l'exécution depuis le modèle chargé, pas fixée dans la documentation. - Voix : synthèse par
forge-kokoro-tts, transcription parforge-faster-whisper, temps réel parforge-livekit.
Les fournisseurs LLM tiers sont optionnels et désactivés par défaut.
Authentification
Les méthodes sont cumulables selon la configuration de l'organisation : mot de passe, second facteur TOTP (application d'authentification) et SSO OIDC via Authentik.
- Le jeton d'accès est un JWT signé en HS256 (l'algorithme est
épinglé côté serveur). Sa durée se règle par
JWT_EXPIRY; le défaut du code est de 7 jours (crates/forge-api/src/state.rs). - Protection CSRF par double soumission : cookie
csrf-tokenet en-têtex-csrf-tokensur les requêtesPOST,PUTetDELETE. - Les secrets de connecteurs sont chiffrés en AES-256-GCM avant stockage ; les locataires soumis à une exigence réglementaire peuvent les loger dans OpenBao.
Cloisonnement des locataires
Le filtre de locataire canonique repose sur l'organisation
(organization_id), appliqué par accessible_workspace_filter
(crates/forge-api/src/extractors/mod.rs). Un contrôle de pré-commit
sur le cloisonnement des locataires protège les handlers du backend.
Gestion des erreurs
Chaque niveau capture et traduit ses erreurs :
- Transport MCP : JSON-RPC invalide, session expirée ;
- Connecteurs : délai dépassé, authentification, limite amont atteinte ;
- Moteur IA : dégradation par paliers sous pression de ressources.
Détails : Gestion des erreurs.
Compilation et contrôles
# Workspace complet
cargo build --workspace --release
# Interface web (wasm)
cargo build -p forge-ui --target wasm32-unknown-unknown --bin chatbotaurus
# Tests
cargo test --workspace
# Lint strict
cargo clippy --workspace --all-targets -- -D warnings
Les contrôles de pré-commit refusent notamment un fichier Rust de plus de 300 lignes sans exemption motivée et l'usage des termes « parity » ou « parité » sans preuve associée.
Voir aussi
- Conception des connecteurs MCP : manifestes YAML, connecteurs natifs et contrôle de conformité UE
- Gestion des erreurs : enveloppe d'erreur, codes JSON-RPC, disjoncteur et dégradation par paliers
- Routes MCP (Streamable HTTP) : transport, sessions et catalogue exposés par la passerelle
- Connecteurs MCP : comment un connecteur est chargé, authentifié et compté
- Déploiement avec Podman : les deux plans en pratique : Compose en développement, Quadlet en production
Gestion des erreurs
Chatbotaurus gère les erreurs à plusieurs niveaux : une énumération d'erreurs commune à tout le backend, une enveloppe JSON stable côté API, des codes JSON-RPC pour le transport MCP, un disjoncteur pour les services en aval et une dégradation par paliers du moteur d'IA.
À la fin, vous saurez lire un code d'erreur renvoyé par l'API ou par le transport MCP et savoir où chercher la cause.
Erreurs de l'API REST
Les handlers de forge-api renvoient des ForgeError
(crates/forge-core/src/error.rs). Chaque variante porte un statut HTTP
et un code lisible par machine :
| Variante | Statut | Code |
|---|---|---|
InvalidInput | 400 | INVALID_INPUT |
Validation | 400 | VALIDATION_FAILED |
Unauthorized | 401 | UNAUTHORIZED |
Forbidden | 403 | FORBIDDEN |
NotFound | 404 | NOT_FOUND |
Conflict | 409 | CONFLICT |
Unprocessable | 422 | UNPROCESSABLE |
RateLimited | 429 | RATE_LIMITED |
Internal, Config, Serialization | 500 | INTERNAL_ERROR, CONFIG_ERROR, SERIALIZATION_ERROR |
Database | 500 | DATABASE_ERROR |
Vault | 500 | VAULT_ERROR |
Upstream | 502 | UPSTREAM_ERROR |
CircuitOpen, Unavailable | 503 | CIRCUIT_OPEN, SERVICE_UNAVAILABLE |
Timeout | 504 | TIMEOUT |
Vault et VAULT_ERROR sont des noms historiques du code : le coffre de
secrets du produit est OpenBao.
Les erreurs de domaine (Agent, Workflow, Rag, Embedding,
HallucinationDetected, Ollama) répondent 500 avec les codes
AGENT_ERROR, WORKFLOW_ERROR, RAG_ERROR, EMBEDDING_ERROR,
HALLUCINATION_DETECTED et OLLAMA_ERROR.
Le corps de réponse a toujours la même forme :
{
"error": {
"code": "NOT_FOUND",
"message": "resource not found: user id=42",
"status": 404
}
}
Une réponse 429 ajoute le champ retryAfterSecs dans le corps et
l'en-tête HTTP Retry-After. La conversion en réponse HTTP est faite
par crates/forge-common/src/error.rs : niveau de trace warn pour un
404, info pour les autres 4xx, error pour les 5xx.
Pour agir sur un code précis (TIMEOUT, SERVICE_UNAVAILABLE, RATE_LIMITED,
CIRCUIT_OPEN, session MCP expirée), voir Problèmes connus.
Messages sans fuite d'information
Un message d'erreur de base de données, de client HTTP ou de fichier peut
embarquer une requête SQL, une URL interne ou un chemin local. Les
handlers passent donc par safe_message
(crates/forge-api/src/safe_error.rs) : le client reçoit un texte fixe
et neutre. En développement local seulement, l'opérateur peut démarrer
le serveur avec FORGE_VERBOSE_ERRORS=1 pour obtenir le détail.
Le même module fournit error_body et error_body_with_request_id
(ajoute un champ request_id pour relier une réponse à ses traces).
Transport MCP
Le transport Streamable HTTP répond en JSON-RPC 2.0. Codes émis par
crates/forge-mcp/src/transport/ et crates/forge-api/src/routes/mcp.rs :
| Code | Cas | Exemple de message |
|---|---|---|
| -32700 | JSON invalide | invalid JSON-RPC request |
| -32600 | Requête invalide | missing Mcp-Session-Id, session expired or unknown |
| -32601 | Méthode inconnue | method '<nom>' not found |
| -32602 | Paramètres invalides | missing 'name' |
| -32603 | Erreur interne | tool call failed, session creation failed |
Les messages du code -32603 sont génériques (passés par safe_message).
Une session expire après 30 minutes d'inactivité : le client doit alors
renvoyer initialize.
Connecteurs
- Limite amont atteinte : si le service tiers répond 429, le
connecteur renvoie
RATE_LIMITEDavec leRetry-Afterde l'amont (60 secondes à défaut). Un connecteur peut aussi déclarerrate_limit_per_min: la limite est alors vérifiée avant l'appel réseau. - Délai dépassé : chaque connecteur a un
timeout_ms(30 000 par défaut). Un dépassement est renvoyé enTIMEOUT(504). - Service injoignable : une erreur de connexion devient
SERVICE_UNAVAILABLE(503). - URL interdite : une URL de base fournie par un locataire qui vise
le réseau interne est refusée avant tout appel (
Forbidden, messageSSRF_BLOCKED).
Agents : disjoncteur
Chaque agent exécuté par un AgentWorker
(crates/forge-core/src/agent/worker.rs) est protégé par un disjoncteur
à trois états (fermé, ouvert, semi-ouvert). Par défaut il s'ouvre après
quelques échecs consécutifs, reste ouvert un court délai avant de passer en
semi-ouvert, et considère un appel comme échoué au-delà d'un délai borné.
Tant qu'il est ouvert, l'appel échoue immédiatement avec CIRCUIT_OPEN
(503). Une primitive générique équivalente existe dans
crates/forge-core/src/security/circuit_breaker.rs.
Moteur d'IA : dégradation par paliers
Cette cascade est livrée mais non branchée : les moteurs de raisonnement
qu'elle coupe n'ont pas d'appelant de production (voir
Supervision). Le moniteur de ressources du moteur MGaaS
(crates/forge-core/src/mgaas/resource_monitor.rs) choisit un niveau de
dégradation à partir de la RAM utilisée, du CPU et de la latence moyenne.
Il existe cinq niveaux, par ordre décroissant de capacités :
FULL: toutes les techniques de raisonnement actives ;NO_MCTS: MCTSLite désactivé ;NO_TOT: ToTLite désactivé en plus ;NO_SELF_CONSISTENCY: l'auto-cohérence est désactivée en plus ;TEMPLATE_ONLY: réponses issues de gabarits, dernier recours.
Les seuils (mémoire, processeur, latence) sont fixés dans le code du moniteur de ressources et ne sont pas publiés ici.
Règle appliquée : si un seul seuil critique est franchi, le niveau est
TEMPLATE_ONLY. Sinon, si un seuil d'avertissement est franchi, le niveau
est NO_SELF_CONSISTENCY quand la mémoire dépasse nettement son seuil
d'avertissement, NO_TOT quand le processeur est très chargé, et NO_MCTS dans les
autres cas, latence comprise (marges fixées dans le code).
Figure 2 : les cinq niveaux de dégradation du moteur d'IA, par ordre décroissant de capacités.
Le moteur anti-hallucination (crates/forge-core/src/anti_hallucination/)
a son propre indicateur de niveau opérationnel, distinct du précédent :
Full, NoCache, NoRag, NoSemantic, TemplateOnly, Maintenance.
Il décide quelles fonctions sont annoncées au client, et ne se confond
pas avec le moniteur de ressources ci-dessus.
Observabilité
- Les journaux du backend sont écrits en JSON par défaut ;
LOG_FORMAT=prettyoucompactdonne une sortie lisible (init_tracing,crates/forge-api/src/main.rs).TRACING_JSON, fixée danspodman-compose.yml, n'est pas lue parforge-api. - Chaque requête reçoit un identifiant par la couche
RequestIdLayer. - Le plan backend embarque VictoriaMetrics (métriques) et VictoriaLogs (logs) ; la détection d'intrusion repose sur CrowdSec. L'unité Falco existe mais est retirée du déploiement depuis le 2026-09-19.
Voir aussi
- Architecture Chatbotaurus : où vivent les couches qui produisent ces erreurs
- Conception des connecteurs MCP : délai, limite amont et contrôle SSRF déclarés côté connecteur
- Problèmes connus : session expirée, connecteur en échec, disjoncteur ouvert : que faire
- Documentation Swagger : contrat OpenAPI et authentification : format des erreurs et limites de débit vus du client
- Supervision : état réel de la cascade de dégradation et des métriques exposées
Conception des connecteurs MCP
Ce chapitre décrit comment un service externe devient un ensemble
d'outils MCP dans Chatbotaurus. Le moteur est le crate forge-mcp. À la fin, vous saurez
écrire le manifeste d'un connecteur et ce que le contrôle de conformité UE en refuse.
Deux types de connecteurs
1. Connecteur déclaratif YAML (cas général)
Un fichier connectors/<nom>.yaml décrit le service et ses outils. Au
démarrage, forge-api lit le dossier désigné par la variable
CONNECTOR_CATALOGUE_DIR (par défaut ./connectors). Il enregistre
chaque connecteur dans le registre. Le fichier
connectors/TEMPLATE.yaml est un modèle à copier. Pas à pas : Créer votre premier
connecteur MCP. Le dossier n'est lu qu'au
démarrage : redémarrez forge-api après chaque modification (voir
Fichiers de configuration).
Exemple tiré de connectors/matomo.yaml, abrégé (l'URL par défaut y est remplacée par une adresse d'exemple) :
id: matomo
display_name: "Matomo Analytics"
base_url: "${MATOMO_URL:-https://matomo.exemple.eu}"
base_url_env: MATOMO_URL
auth:
type: query_token
param: token_auth
token_env: MATOMO_API_KEY
compliance:
data_residency: self-hosted
self_hosted: true
gdpr_compliant: true
license: "GPL-3.0"
gaia_x: true
timeout_ms: 30000
tools:
- name: get_visits_summary
description: "Matomo Reporting API VisitsSummary.get"
method: GET
path: "/index.php"
param_location: query
input_schema:
type: object
properties:
module: { type: string, default: "API" }
method: { type: string, default: "VisitsSummary.get" }
format: { type: string, default: "JSON" }
Champs principaux (structure HttpConnectorConfig,
crates/forge-mcp/src/connector/http.rs) :
| Champ | Rôle |
|---|---|
id, display_name | Identifiant unique et nom lisible |
base_url | URL de base ; ${VAR:-défaut} est résolu depuis l'environnement au démarrage |
base_url_env | Variable portant l'URL propre à un locataire (instance auto-hébergée par client) |
auth | Méthode d'authentification, discriminée par type |
compliance | Métadonnées de conformité UE, contrôlées à l'enregistrement |
timeout_ms | Délai de la requête (30 000 par défaut) |
cache_ttl_s | Cache de lecture des GET, désactivé à 0 (défaut) ; jamais actif dans un contexte locataire |
rate_limit_per_min | Plafond publié par l'amont, vérifié avant l'appel |
tools[] | name, description, method (GET, POST, PUT, PATCH, DELETE), path ({param} est remplacé par un argument), param_location (query, body ou path), input_schema (JSON Schema) |
Types d'authentification : none, bearer, api_key, basic,
query_token, jwt_exchange, oauth2, login_token, checksum, json_rpc_session. Les
fichiers YAML ne portent jamais de secret : ils nomment la variable
d'environnement qui le contient (token_env, key_env, entre autres).
Les outils sont exposés avec le préfixe de leur connecteur :
l'outil get_visits_summary du connecteur matomo s'appelle
matomo.get_visits_summary.
2. Connecteur natif Rust
Pour un protocole qui n'est pas du REST (par exemple l'XML-RPC d'Odoo,
crates/forge-mcp/src/connector/odoo_xmlrpc_client.rs) ou une
transformation lourde, on implémente le trait McpConnector
(crates/forge-mcp/src/connector/mod.rs) :
#[async_trait::async_trait]
pub trait McpConnector: Send + Sync + 'static {
fn id(&self) -> &str;
fn display_name(&self) -> &str;
fn compliance(&self) -> &EuCompliance;
async fn list_tools(&self) -> ForgeResult<Vec<ToolDefinition>>;
async fn execute(
&self,
tool_name: &str,
arguments: serde_json::Value,
) -> ForgeResult<Vec<ContentBlock>>;
async fn health_check(&self) -> ForgeResult<ConnectorHealth>;
// ... plus des méthodes avec valeur par défaut (voir le fichier)
}
Un connecteur natif est enregistré dans le ConnectorRegistry au même
titre qu'un connecteur YAML.
Contrôle de conformité UE
ConnectorRegistry::register appelle EuCompliance::validate. Un
connecteur dont gdpr_compliant vaut false, ou dont la résidence des
données n'est pas européenne (ou self-hosted), est rejeté au démarrage
et journalisé. La classification de la résidence est centralisée dans
crates/forge-mcp/src/connector/residence.rs. Côté exécution, chaque
appel de serveur repasse par la fonction unique
forge_core::compliance::is_server_allowed.
Cycle de vie
- Enregistrement : au démarrage, le
CatalogueLoadercharge les YAML et le registre reçoit aussi les connecteurs natifs. - Découverte : le client MCP appelle
tools/listsurPOST /api/v1/mcp. Le catalogue se consulte aussi parGET /api/v1/mcp/catalogue. - Exécution : le client appelle
tools/callsur la même route. - Résultat : le connecteur renvoie des blocs de contenu MCP
(
ContentBlock).
Figure 3 : du connecteur à l'outil MCP, avec le contrôle de conformité UE à l'enregistrement et à chaque appel.
Identifiants et secrets
- Les identifiants tiers d'un locataire sont chiffrés en AES-256-GCM
avant stockage. Au démarrage,
crates/forge-api/src/connector_credential_env.rsles déchiffre et les publie dans les variables d'environnement que lisent les connecteurs. Les locataires réglementés peuvent utiliser une couche OpenBao. - À chaque requête, les secrets du seul locataire appelant sont
installés pour la durée de l'appel. Avec
FORGE_MULTI_TENANT_STRICT=1, le chargement global au démarrage est sauté et aucun connecteur ne retombe sur les identifiants globaux du déploiement.
Sécurité
- SSRF : une URL de base fournie par un locataire (
base_url_env) est contrôlée en deux temps avant tout appel réseau. Premier temps : analyse de l'URL (schéma, adresse, hôtes internes). Second temps : résolution DNS avec refus des adresses privées. Une violation renvoieForbiddenavec le motifSSRF_BLOCKED. Ce contrôle ne s'applique qu'aux URL fournies par un locataire : l'URL du YAML ou de l'environnement de l'opérateur n'y est pas soumise. Aucune option d'exploitation ne le désactive ; seule la compilation des tests le lève. - Actions irréversibles : un outil irréversible ne s'exécute qu'après
une approbation humaine explicite, limitée au nom exact de l'outil
(
crates/forge-mcp/src/connector/human_authorization.rs). Un outil destructif n'est jamais autorisable par cette voie. - Un connecteur peut être limité à la lecture : le connecteur Matomo, par exemple, ne publie que des outils de rapport.
Bonnes pratiques
- Connexions : un seul client
reqwestréutilisé par connecteur. - Limites amont : déclarez
rate_limit_per_minquand l'API publie un plafond ; une réponse 429 est renvoyée enRATE_LIMITEDavec sonRetry-After. - Cache :
cache_ttl_sconvient aux données publiques en lecture seule ; laissez-le à 0 pour tout le reste. - Données publiques : le champ
groundedfait accompagner chaque réponse de sa source (source_url,retrieved_at).
Voir aussi
- Créer votre premier connecteur MCP : écrire, valider et tester un manifeste pas à pas
- Connecteurs MCP : ce qui est mesuré et comment un connecteur est chargé
- Routes MCP (Streamable HTTP) : découverte et appel des outils, catalogue consultable par l'API
- Gestion des erreurs : codes renvoyés par un connecteur : délai, limite amont, SSRF
- Fichiers de configuration : où vivent les manifestes et comment l'environnement y est interpolé
Documentation Swagger : contrat OpenAPI et authentification
forge-api sert son contrat OpenAPI lui-même, généré depuis le code avec la
bibliothèque utoipa. Il n'existe pas d'interface Swagger UI servie par
le backend : vous récupérez le document et l'ouvrez dans l'outil de votre choix
(Swagger Editor, Postman, Insomnia, générateur de client).
Dans les exemples de ce livre, <hote-api> désigne le nom d'hôte de l'API, sans schéma : app.<domaine> derrière le nom public (voir Diagnostics et signalement). Sur un poste de développement, écrivez http://localhost:3000 à la place de https://<hote-api>.
Où récupérer le contrat
| Route | Contenu |
|---|---|
GET /api/v1/openapi.json | Document OpenAPI en JSON |
GET /api/v1/openapi.yaml | Le même document en YAML |
GET /openapi.json | Même source, à la racine du serveur |
GET /openapi.yaml | Même source, à la racine du serveur |
Ces routes sont publiques. La variable OPENAPI_ENABLED=false les coupe : elles
répondent alors 404. Le champ servers du document vaut / parce que les
chemins documentés portent déjà le préfixe /api/v1.
curl "https://<hote-api>/api/v1/openapi.json" -o forge-openapi.json
Ce que couvre le contrat, et ce qu'il ne couvre pas
Le contrat est partiel. Il se limite aux opérations annotées avec
#[utoipa::path] dans crates/forge-api/src/openapi/. Mesures reproductibles :
| Fait | Commande | Résultat |
|---|---|---|
| Opérations annotées | git grep -hoE '#\[utoipa::path\(' -- crates/forge-api/src/openapi | wc -l | 125 |
| Chemins distincts | git grep -hoE 'path = "/api/v1[^"]*"' -- crates/forge-api/src/openapi | sort -u | wc -l | 109 |
Appels .route( actifs dans router.rs | git grep -c '^\s*\.route(' -- crates/forge-api/src/router.rs | 793 |
Familles documentées (étiquettes du contrat) : santé, facturation, authentification, OAuth/OIDC, SSO, sessions, chat, passerelle de chat, messages de gateway, prédictions, documents (RAG, document store, scraping, chunks), clés d'API, compte, rôles.
Familles absentes du contrat : le transport MCP (/api/v1/mcp), le
catalogue métier (/api/v1/mcp/catalog-business/*), la gestion des
gateways (/api/v1/gateways/*), les retours (/api/v1/feedback), les outils,
variables et identifiants. Pour ces routes, la référence est ce livre, qui les
décrit une par une d'après le routeur.
Le document déclare trois schémas de sécurité : BearerAuth (JWT dans
Authorization: Bearer), CookieAuth (cookie jwt) et ApiKeyAuth
(en-tête X-API-Key). Seuls les deux premiers sont consommés par des
routes aujourd'hui : ApiKeyAuth est déclaré sans route qui l'accepte.
Authentification
La majorité des routes exigent un jeton, donc un compte (Prise en main guidée, étape 1). Il s'obtient par la connexion, avec un second facteur (OTP e-mail ou application TOTP) lorsqu'il est exigé :
# 1. connexion
curl -X POST "https://<hote-api>/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{"email":"<email>","password":"<mot-de-passe>"}'
La réponse porte requires_2fa. Quand il vaut false et que la connexion réussit, elle contient directement token : passez à l'envoi du jeton plus bas. Un e-mail inconnu ou un mot de passe erroné répond 401 (UNAUTHORIZED), et si requires_mfa_enrollment vaut true, aucun jeton n'est rendu : enrôlez d'abord un second facteur. Quand requires_2fa vaut true, la réponse contient aussi
two_factor_token et method (email ou totp) :
# 2. validation du second facteur
curl -X POST "https://<hote-api>/api/v1/auth/2fa/verify" \
-H "Content-Type: application/json" \
-d '{"two_factor_token":"<two_factor_token>","code":"<code>"}'
La réponse est {"authenticated": true, "token": "<token>"}. Le renvoi du code
par e-mail se fait par POST /api/v1/auth/2fa/resend. La connexion par
fournisseur d'identité (OIDC) passe par GET /api/v1/auth/oidc/login.
Ensuite, joignez le jeton à chaque appel (les tutoriels le rangent dans la variable JWT) :
Authorization: Bearer <token>
Les navigateurs utilisent le cookie jwt posé par la connexion. Le jeton
vit 7 jours par défaut (variable JWT_EXPIRY). POST /api/v1/auth/refresh
(alias POST /api/v1/auth/refreshToken) renouvelle une session encore
valide et rend {"token": ...} ; il n'existe pas de jeton de
rafraîchissement séparé : un jeton expiré ne peut pas être renouvelé, il faut
se reconnecter.
Quelques routes sont publiques (santé, contrat OpenAPI, conformité publique,
prediction/{id} d'une gateway publiée, SBOM).
Provisionnement SCIM
Le provisionnement d'utilisateurs et de groupes suit SCIM 2.0 sous
/api/v1/scim/v2/ : Users, Groups, ServiceProviderConfig, Schemas
et ResourceTypes. Il s'authentifie par un jeton porteur SCIM dédié.
Format des erreurs
Une erreur est un objet {"error": {"code": "...", "message": "..."}} ;
les erreurs de l'extracteur d'authentification ajoutent status. Codes
fréquents : UNAUTHORIZED (401), FORBIDDEN (403), NOT_FOUND (404),
VALIDATION_FAILED (422), FEATURE_PENDING (503, capacité prévue non
livrée). Le dépassement de débit est différent : le limiteur répond 429
avec un corps vide et l'en-tête retry-after (en secondes). Le transport MCP répond, lui, en erreurs JSON-RPC (error.code, error.message) : voir Routes MCP.
Limites de débit
Le limiteur est par adresse IP et par préfixe de route (le préfixe de longueur maximale l'emporte) :
| Préfixe | Défaut | Réglage |
|---|---|---|
/api/v1/ | 100 requêtes par seconde | FORGE_RATE_LIMIT_PER_SEC |
/api/v1/prediction (début de chemin : couvre aussi /api/v1/predictions) | 20 requêtes par minute | FORGE_RATE_LIMIT_PREDICTION_PER_MIN |
/api/v1/stats/route-events | 30 requêtes par minute | fixe |
Les routes d'authentification ont en plus leurs propres limiteurs
(auth_rate_limiter, account_rate_limiter).
Voir aussi
- API-as-a-Service EU souverain : principe, appel d'un connecteur et garde-fous en place
- Routes MCP : transport MCP, absent du contrat, décrit route par route
- Connecter Odoo à la passerelle MCP : du jeton à un premier appel d'outil, pas à pas
- Gestion des erreurs : le détail des codes d'erreur de l'API et du transport MCP
- Routes des gateways et de la prédiction : gateways et prédiction, absentes du contrat, décrites route par route
- Routes des ressources : document stores, identifiants et variables, décrits route par route
- Sécurité : authentification, limiteurs et protection des requêtes côté plateforme
API-as-a-Service EU souverain
Ce chapitre décrit ce que la plateforme fait aujourd'hui pour exposer des
sources de données européennes sous forme d'appels JSON structurés, et ce
qui reste prévu. À la fin, vous savez ouvrir une session MCP, appeler un outil de connecteur (par session ou par appel direct) et lister le registre. Chaque route citée existe dans crates/forge-api/src/router.rs
et chaque chiffre vient d'une commande que vous pouvez relancer.
Le principe
Une source de données (API publique d'une institution, service auto-hébergé)
est décrite par un fichier YAML de connecteur dans connectors/. Au
démarrage, forge-api charge ces fichiers dans un registre ; chaque outil
déclaré devient un outil MCP nommé {id-du-connecteur}.{outil}
(exemple : data-europa.search_datasets). Le client n'a pas à connaître
l'API amont : il appelle l'outil, la plateforme exécute la requête et rend
le résultat en JSON.
Mesures reproductibles :
| Fait | Commande | Résultat au moment de l'écriture |
|---|---|---|
| Fichiers de connecteurs | ls connectors/*.yaml | wc -l | 195 |
| Entrées du catalogue business embarqué | voir catalog_embeds_full_business_catalogue dans crates/forge-api/src/routes/mcp_catalog_business.rs | 108 |
Les deux nombres sont distincts : le registre exécutable (les YAML) et le catalogue business (une liste de fiches de serveurs, voir le chapitre « Routes du catalogue métier »). Ne les confondez pas.
Appeler un connecteur
Deux chemins authentifiés mènent au même registre. Il faut un jeton (Swagger, section Authentification) et l'adresse de votre API : <hote-api> désigne le nom d'hôte de l'API, sans schéma (app.<domaine> derrière le nom public, voir Diagnostics et signalement). Sur un poste de développement, écrivez http://localhost:3000 à la place de https://<hote-api>.
1. Transport MCP (JSON-RPC, session). Ouvrez une session avec initialize,
puis appelez tools/call en passant l'en-tête Mcp-Session-Id reçu :
# 1. ouvrir la session (l'identifiant de session revient dans l'en-tête de réponse)
curl -i -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"mon-client","version":"1.0.0"}}}'
# 2. appeler un outil de connecteur
curl -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Mcp-Session-Id: <session-id>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"data-europa.search_datasets","arguments":{"q":"energie","limit":5}}}'
La forme des réponses (result.type, result.content, error.code) est décrite dans Routes MCP.
2. Appel direct, sans session. POST /api/v1/mcp/catalog-business/tools/call
prend {server, tool, args} et exécute l'outil dans le registre :
curl -X POST "https://<hote-api>/api/v1/mcp/catalog-business/tools/call" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"server":"data-europa","tool":"search_datasets","args":{"q":"energie","limit":5}}'
La réponse est {"success": true, "server": ..., "tool": ..., "result": ...}
en cas de succès, ou {"success": false, "error": ...} (statut HTTP 200) si le
connecteur est absent ou si l'exécution échoue. Un serveur absent de la liste des serveurs autorisés est refusé avant même la recherche dans le registre, par un 403
de corps {"error": {"code": "FORBIDDEN", ...}} dont le message dit « hors du plan ou non conforme EU ». Cette liste ne dépend pas du locataire (voir Connecteurs MCP).
Pour lister ce que le registre contient :
curl "https://<hote-api>/api/v1/mcp/catalogue" -H "Authorization: Bearer <token>"
La réponse est {"catalogue": [...], "total": N} ; chaque entrée porte l'id,
le display_name et le bloc compliance (résidence des données, auto-hébergé,
RGPD, licence, Gaia-X).
Sources européennes disponibles
Des connecteurs de sources publiques européennes existent dans connectors/ :
eurlex, eurostat, cordis, openaire, europeana, ecb-data,
europe-pmc, data-europa. Un méta-moteur de recherche auto-hébergé,
searxng, déclare les outils query, config et health.
Ce qui n'existe pas : il n'y a pas de connecteur dédié aux sites de l'EDPB, de la CURIA, de l'EBA ou de l'ESMA. Les sources ci-dessus sont celles que le dépôt livre ; toute autre source passe par l'ajout d'un fichier YAML de connecteur.
Garde-fous réellement en place
- Authentification : les deux chemins exigent un jeton (
Authorization: Bearerou cookiejwt). Une session MCP est liée à l'utilisateur qui l'a ouverte. - Conformité UE : chaque appel d'outil passe par un point d'étranglement de
conformité avant l'exécution (
is_server_alloweddansforge-core). - Plafond amont : le champ
rate_limit_per_mindu YAML d'un connecteur plafonne les appels sortants vers la source. - Secrets : les identifiants d'un locataire sont chiffrés au repos (AES-256-GCM) et résolus à la requête ; ils ne sont jamais renvoyés en clair.
- Inventaire logiciel : le SBOM CycloneDX du binaire servi est public sur
GET /.well-known/sbom(hors préfixe/api/v1). - Analyse d'images : l'analyse Trivy des images est exécutée en CI (workflow de CI du dépôt), pas au moment d'un appel d'API.
Ce qui est prévu, et ce qui est retiré
| Sujet | Statut | Référence |
|---|---|---|
Déploiement de conteneurs par l'API (deploy, start, stop, restart) | Prévu : ces routes répondent aujourd'hui 503 FEATURE_PENDING | spec 16, tâche P5.5 (route d'opérations de déploiement) |
| Extraction de contenu de pages web par un service d'exploration dédié | Retiré de ce chapitre : aucune tâche de spec ne le porte | aucune |
| Offres tarifaires « Standard / Premium / Enterprise » par connecteur | Retiré : aucune tâche de spec ni aucune route de facturation par connecteur | aucune |
Recherche par connecteur sous un préfixe mcp/gateways | N'existe pas : ce préfixe n'est monté nulle part ; utilisez tools/call | aucune |
Voir aussi
- Routes MCP : transport Streamable HTTP, sessions et méthodes JSON-RPC détaillées
- Routes du catalogue métier : lecture opérationnelle et cycle de vie prévu
- Documentation Swagger : contrat OpenAPI, obtention du jeton et limites de débit
- Connecter Odoo à la passerelle MCP : un connecteur qui exige les identifiants du locataire, de leur enregistrement au premier appel
- Gestion des erreurs : lire un code d'erreur de l'API ou du transport MCP
- Connecteurs MCP : connecteurs décrits dans ce livre et sources publiques de l'UE
- Créer votre premier connecteur MCP : ajouter une source par un fichier YAML de connecteur
Routes MCP (Streamable HTTP)
Le transport MCP de la plateforme suit le protocole Streamable HTTP, révision
2025-03-26 (constante MCP_PROTOCOL_VERSION dans forge-mcp). Les échanges
sont du JSON-RPC 2.0. La route est déclarée dans
crates/forge-api/src/router.rs et ses gardes d'authentification dans
crates/forge-api/src/routes/mcp.rs.
Désactivation. Le groupe
/api/v1se coupe avecAPI_ENABLED=false, et le transport MCP avecMCP_ENABLED=false(ouAPI_ENABLED=false). Une surface coupée répond un404JSON, jamais un403.
Transport principal
| Méthode | Route | Rôle |
|---|---|---|
POST | /api/v1/mcp | Requête JSON-RPC (un objet par requête) |
GET | /api/v1/mcp | Flux SSE d'une session |
DELETE | /api/v1/mcp | Fermer une session (204) |
Les trois exigent un jeton (Authorization: Bearer <token> ou cookie jwt). <hote-api> est défini dans Swagger.
Une session est liée à l'utilisateur qui l'a ouverte : l'identité passée dans
les paramètres d'initialize est écrasée par celle du jeton, et une session
qui n'appartient pas à l'appelant répond 404 avec le code JSON-RPC -32600
(« session inconnue »).
Figure 4 : une session MCP, de initialize à DELETE.
POST /api/v1/mcp
En-têtes : Content-Type: application/json, et Mcp-Session-Id: <session-id>
pour toutes les méthodes sauf initialize et ping.
Un seul objet JSON-RPC par requête. Le corps est désérialisé en une requête unique : un tableau (batch JSON-RPC) n'est pas accepté. Pour enchaîner plusieurs appels, envoyez plusieurs requêtes.
Méthodes JSON-RPC traitées (liste du match de mcp_post_handler) :
| Méthode | Rôle |
|---|---|
initialize | Ouvre une session, renvoie les capacités et l'en-tête Mcp-Session-Id |
ping | Test de vie |
tools/list | Outils disponibles (connecteurs autorisés pour la plateforme) |
tools/call | Exécute un outil |
resources/list, resources/read | Ressources MCP |
prompts/list, prompts/get | Modèles de prompts |
completion/complete | Complétion d'arguments |
logging/setLevel | Niveau de journalisation |
Toute autre méthode répond -32601 (« method not found »). Un corps qui n'est
pas une requête JSON-RPC valide répond 400 avec -32700.
initialize
curl -i -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"mon-client","version":"1.0.0"}}}'
La réponse contient protocolVersion, les capabilities (tools,
resources, prompts, completion, logging) et serverInfo
(name: "chatbotaurus-forge"). L'identifiant de session est dans l'en-tête
de réponse mcp-session-id. Copiez-le dans une variable (export SESSION=<session-id>) : les appels suivants le renvoient dans l'en-tête Mcp-Session-Id.
tools/list
curl -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Mcp-Session-Id: <session-id>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
La réponse porte result.tools, une liste d'objets name, description, inputSchema et connector_id. Les noms d'outils ont la forme {id-du-connecteur}.{outil}. Prenez les noms
exacts dans la réponse de tools/list, jamais dans un exemple de document.
tools/call
curl -X POST "https://<hote-api>/api/v1/mcp" \
-H "Authorization: Bearer <token>" \
-H "Mcp-Session-Id: <session-id>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"data-europa.search_datasets","arguments":{"q":"energie","limit":5}}}'
Réponse : statut HTTP 200 et un objet JSON-RPC. En cas de succès, result.type vaut success et result.content est une liste de blocs (type, text). Avant l'exécution, un échec est un objet error à la place de result, et error.code reprend le code HTTP de l'échec tout en gardant le statut HTTP 200 : 401 session expirée, 403 serveur absent de la liste autorisée, 404 outil inconnu. Si le connecteur lui-même échoue, result.type vaut error et result porte code et message, toujours avec le statut HTTP 200.
Sans Mcp-Session-Id, la réponse est 400 (-32600, « missing
Mcp-Session-Id »). Une session expirée ou inconnue répond 401 : en statut HTTP pour tools/list, dans error.code pour tools/call.
GET /api/v1/mcp
Ouvre un flux text/event-stream pour la session désignée par
Mcp-Session-Id. Le flux envoie un événement open ({"sessionId": ...})
puis un commentaire de maintien de connexion toutes les 30 secondes.
Capacité en sommeil. Les capacités annoncent
tools.listChanged, mais aucune notification n'est poussée aujourd'hui sur ce flux : seuls l'événementopenet les signaux de maintien sont émis (commentaire du code dansmcp_get_handler). Ne bâtissez pas de logique client sur des notifications serveur.
DELETE /api/v1/mcp
Ferme la session de Mcp-Session-Id, libère ses ressources et inscrit la
fermeture au journal d'audit. Réponse 204 No Content.
Sessions
- Chaque session est un UUID, stocké dans Valkey.
- Durée de vie par défaut : 30 minutes (
DEFAULT_SESSION_TTLdansforge-mcp/src/session.rs). Chaquetools/callrafraîchit ce délai. - La session est vérifiée à chaque requête ; si le magasin de sessions est
indisponible, la réponse est
503(-32603).
Catalogue des connecteurs
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/mcp/catalogue | Connecteurs du registre |
GET | /api/v1/mcp/catalogue/{id} | Un connecteur |
GET | /api/v1/mcp/catalog | Alias de /mcp/catalogue |
GET | /api/v1/mcp/connectors | Alias de /mcp/catalogue |
Ces routes exigent un jeton. GET /api/v1/mcp/catalogue renvoie
{"catalogue": [{"id", "display_name", "compliance": {...}}], "total": N}.
curl "https://<hote-api>/api/v1/mcp/catalogue" -H "Authorization: Bearer <token>"
La fiche descriptive des serveurs business (catégorie, fournisseur, pays,
certifications) est servie par /api/v1/mcp/catalog-business, décrit dans le
chapitre « Routes du catalogue métier ».
Documentation de l'API
Il n'existe pas de serveur de documentation séparé. Le contrat OpenAPI est
servi par forge-api lui-même (voir le chapitre « Swagger »).
Voir aussi
- API-as-a-Service EU souverain : appeler un connecteur par session ou par appel direct
- Créer votre premier connecteur MCP : ajouter un connecteur, puis le tester par ce transport
- Connecter Odoo à la passerelle MCP : une session et un premier appel d'outil, pas à pas
- Diagnostics et signalement : ouvrir une session et consulter le catalogue en dépannage
- Gestion des erreurs : codes JSON-RPC du transport et enveloppe d'erreur de l'API
- Conception des connecteurs MCP : cycle de vie des connecteurs derrière tools/list et tools/call
Routes du catalogue métier
Le catalogue business est la liste des serveurs MCP que la plateforme sait
décrire et proposer. Toutes les routes vivent sous
/api/v1/mcp/catalog-business (il n'existe aucun préfixe mcp/gateways :
d'anciennes versions de ce livre le citaient à tort). Elles sont déclarées dans crates/forge-api/src/router.rs
et implémentées dans crates/forge-api/src/routes/mcp_catalog_business.rs.
Authentification. Toutes ces routes exigent un jeton (
Authorization: Bearer <token>ou cookiejwt). Les opérations de cycle de vie sont de plus réservées aux rôlesadminetowner: un autre rôle reçoit403 FORBIDDEN.
<hote-api>est défini dans Swagger.
État réel. La lecture du catalogue est opérationnelle. Les opérations qui piloteraient des conteneurs (
deploy,start,stop,restart,secrets,security, déploiement de profil) répondent aujourd'hui503avec le codeFEATURE_PENDING: l'adaptateur Podman n'est pas branché surforge-api. C'est une capacité prévue (spec 16, tâche P5.5 ; voir la section « Cycle de vie : prévu, répond 503 » plus bas), pas une capacité livrée.
Lecture du catalogue
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/mcp/catalog-business | Liste des fiches de serveurs |
GET | /api/v1/mcp/catalog-business/{id} | Fiche d'un serveur |
GET | /api/v1/mcp/catalog-business/{id}/status | Disponibilité au registre |
GET | /api/v1/mcp/catalog-business/profiles | Profils de déploiement |
GET | /api/v1/mcp/catalog-business/deployed | Serveurs prouvés opérationnels |
GET | /api/v1/mcp/catalog-business/tools | Outils MCP exposés par la passerelle |
GET | /api/v1/mcp/catalog-business/{id}/registry-tools | Outils d'un connecteur du registre |
POST | /api/v1/mcp/catalog-business/tools/call | Exécuter un outil de connecteur |
GET | /api/v1/stats/catalog-business | Compteurs des modèles personnalisés, pas du catalogue (voir la note plus bas) |
GET /api/v1/mcp/catalog-business
Paramètre de requête : category (valeur exacte d'une catégorie, par exemple
Communication ou CRM%20%26%20ERP une fois encodé ; all ou vide = pas de
filtre). Le paramètre tier est accepté mais n'est pas appliqué : le
catalogue renvoie tous les serveurs et le client filtre.
curl "https://<hote-api>/api/v1/mcp/catalog-business?category=Communication" \
-H "Authorization: Bearer <token>"
Réponse : {"servers": [...], "total": N}. Il n'y a pas de pagination. Une
fiche porte ces champs, lus dans routes/data/catalog-business.json :
{
"id": "odoo",
"name": "Odoo",
"description": "ERP/CRM open source complet: ventes, achats, stock, comptabilite, RH et plus.",
"category": "CRM & ERP",
"iconName": "Briefcase",
"provider": "Odoo SA",
"country": "Belgique",
"endpoints": 331,
"status": "available",
"certifications": ["RGPD", "ISO27001", "SOC2", "Gaia-X"],
"license": "LGPL-3.0",
"documentation": "https://www.odoo.com/documentation",
"verified": true,
"pullCount": 1247,
"tags": ["erp", "crm", "comptabilite", "rh", "stock", "ventes"],
"version": "17.0",
"tier": "official"
}
Le catalogue embarqué contient 108 fiches (test
catalog_embeds_full_business_catalogue). GET .../{id} renvoie la fiche
seule, ou 404 NOT_FOUND si l'identifiant est inconnu.
Les champs certifications, verified et pullCount sont des valeurs écrites dans le fichier embarqué. Aucun code de la plateforme ne les calcule ni ne les vérifie : ne les lisez ni comme une certification obtenue, ni comme un compteur de téléchargements mesuré.
GET /api/v1/mcp/catalog-business/{id}/status
Rend l'état honnête d'un serveur : sa disponibilité au registre, pas celle d'un conteneur.
{
"serverId": "odoo",
"containerId": null,
"port": null,
"uptime": null,
"startedAt": null,
"status": "available",
"proven_operational": true,
"runtime": { "known": false, "reason": "podman_adapter_not_wired" }
}
status vaut available si le connecteur est dans le registre, sinon
not_registered. Un identifiant absent du catalogue rend 404.
GET /api/v1/mcp/catalog-business/profiles
Les profils sont lus dans le fichier de profils du dépôt. La réponse est {"profiles": [...]}. Il y en a
quatre :
| Profil | Serveurs |
|---|---|
Solo | 1 |
Starter | 5 |
Business | 12 |
Enterprise | tous les serveurs du fichier (37) |
Ces 37 serveurs sont ceux du fichier de profils, pas les 108 fiches du catalogue embarqué : ce sont deux inventaires différents.
GET /api/v1/mcp/catalog-business/deployed
Rend la liste des identifiants de serveurs prouvés opérationnels par un
audit en direct (OPERATIONAL_PROVEN_LIVE, dans forge-core), sous la forme d'un tableau JSON d'identifiants. Ce n'est pas
un inventaire de conteneurs Podman.
Exécuter un outil
POST /api/v1/mcp/catalog-business/tools/call prend server, tool et
args (forme de la réponse : voir API-as-a-Service EU souverain) :
curl -X POST "https://<hote-api>/api/v1/mcp/catalog-business/tools/call" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"server":"searxng","tool":"query","args":{"q":"reglement ia"}}'
GET .../{id}/registry-tools liste les outils d'un connecteur et répond
{"id": ..., "registry_tools": [...]} ; pour un identifiant absent du
registre, la réponse reste 200 avec "registry_tools": [] et un champ
error. GET .../tools répond {"tools": [...], "total": N} : les outils
des connecteurs autorisés. La route voisine GET .../{id}/tools répond
toujours {"id": ..., "tools": []} : elle est un emplacement de
compatibilité, utilisez registry-tools.
Note sur
GET /api/v1/stats/catalog-business. Cette route compte les lignes de la table des modèles personnalisés et renvoie{"total": N, "last_24h": M}. Elle ne décrit pas le catalogue de serveurs.
Cycle de vie : prévu, répond 503
| Méthode | Route | Rôle requis | Réponse aujourd'hui |
|---|---|---|---|
POST | /api/v1/mcp/catalog-business/{id}/deploy | admin, owner | 503 FEATURE_PENDING |
POST | /api/v1/mcp/catalog-business/{id}/start | admin, owner | 503 FEATURE_PENDING |
POST | /api/v1/mcp/catalog-business/{id}/stop | admin, owner | 503 FEATURE_PENDING |
POST | /api/v1/mcp/catalog-business/{id}/restart | admin, owner | 503 FEATURE_PENDING |
POST | /api/v1/mcp/catalog-business/profiles/{name}/deploy | admin, owner | 503 FEATURE_PENDING |
POST | /api/v1/mcp/catalog-business/{id}/secrets | admin, owner | 503 FEATURE_PENDING |
GET | /api/v1/mcp/catalog-business/{id}/security | tout utilisateur connecté | 503 FEATURE_PENDING |
Un appelant sans rôle admin ou owner reçoit d'abord 403 (et la tentative
est auditée) ; un administrateur reçoit le 503. La réponse porte l'en-tête
Retry-After: 86400 et ce corps :
{
"error": {
"code": "FEATURE_PENDING",
"message": "MCP catalog-business lifecycle deferred to spec 16 REQ-5 (POST <route de deploiement prevue>) + Podman socket mount for forge-api"
},
"feature_pending": "catalog_business",
"tracking": "V1: routes/mcp-streamable-http/index.ts L370-377"
}
Conséquences pour votre intégration : ne programmez pas de déploiement par
cette API aujourd'hui. Le rapport de scan Trivy et le SBOM par serveur ne sont
pas servis par .../{id}/security (503). Le SBOM CycloneDX de la plateforme
elle-même est public sur GET /.well-known/sbom. Les secrets d'un locataire se
gèrent par /api/v1/credentials (voir le chapitre « Routes des ressources »).
Voir aussi
- Routes MCP : le transport par session qui exécute les mêmes outils
- Routes des ressources : identifiants, document stores et autres ressources du locataire par l'API
- Parcourir le catalogue de services et préparer un déploiement : parcours pas à pas de ces routes, avec leurs réponses réelles
- MCP et Orchestrateur : les pages de l'application qui présentent ce catalogue
- Connecteurs MCP : connecteurs décrits dans ce livre et statuts du catalogue
Routes des gateways et de la prédiction
Une gateway est un assistant conversationnel : un graphe de workflow
(flow_data) rattaché à un espace de travail, qui peut être publié pour
un usage public. Ce chapitre décrit les routes réelles sous /api/v1/gateways,
les messages, la prédiction (envoi d'une question), les retours utilisateur,
le « warm start » et les sondes de santé.
Convention : les corps de requête et de réponse des routes de ce chapitre
sont du JSON en snake_case (sauf mention contraire). Une erreur a
la forme {"error": {"code": "...", "message": "..."}}, sauf le dépassement de débit (429, corps vide : voir Swagger). Les listes sont des
objets à clé nommée (par exemple {"gateways": [...], "total": N} pour
GET /api/v1/gateways) ; le serveur n'ajoute pas d'enveloppe générique
{data, meta}.
Gestion des gateways
Toutes ces routes exigent un jeton (Authorization: Bearer <token>) et sont
cloisonnées par organisation : un espace de travail hors de votre périmètre
est refusé. L'identifiant d'espace de travail (workspace_id) se lit par GET /api/v1/workspaces (réponse {"workspaces": [...], "total": N}, avec l'id de chaque espace). Parcours minimal pour exposer un assistant : POST /api/v1/gateways, puis POST /api/v1/gateways/{id}/publish, puis POST /api/v1/prediction/{id}. <hote-api> est défini dans Swagger.
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/gateways | Liste (filtre ?workspace_id=) |
POST | /api/v1/gateways | Créer |
GET | /api/v1/gateways/{id} | Détail, avec flow_data |
PUT | /api/v1/gateways/{id} | Mettre à jour |
DELETE | /api/v1/gateways/{id} | Supprimer (204) |
POST | /api/v1/gateways/{id}/publish | Publier (génère le jeton public) |
POST | /api/v1/gateways/{id}/unpublish | Dépublier |
POST | /api/v1/gateways/{id}/regenerate-token | Régénérer le jeton public |
POST | /api/v1/gateways/{id}/transfer | Transférer vers un autre espace de travail |
POST | /api/v1/gateways/transfer-batch | Transfert en masse |
GET | /api/v1/gateways/{id}/budget | Lire le budget mensuel de jetons |
PATCH | /api/v1/gateways/{id}/budget | Fixer le budget mensuel de jetons |
POST /api/v1/gateways
Corps (structure CreateGatewayRequest) : name et workspace_id sont
obligatoires ; flow_data est une chaîne JSON ; gateway_type,
chatbot_config et deployed sont facultatifs.
curl -X POST "https://<hote-api>/api/v1/gateways" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"Assistant comptabilite","workspace_id":"<uuid-espace>","flow_data":"{\"nodes\":[],\"edges\":[]}","deployed":false}'
Réponse 201 avec la gateway : id, name, type, deployed, is_public,
category, workspace_id, created_at, updated_at, approval_required,
et public_token / public_expires_at / flow_data / last_transfer quand
ils existent (flow_data n'est pas renvoyé dans la liste). Le plafond du plan
est appliqué à la création : au-delà du quota de gateways ou de workflows, la
réponse est un refus de quota (402, ou 503 si le quota ne peut pas être
évalué).
PUT /api/v1/gateways/{id} accepte, tous facultatifs : name, flow_data,
deployed, is_public, chatbot_config, api_config, category et
approval_required (supervision humaine par gateway).
Publication
curl -X POST "https://<hote-api>/api/v1/gateways/<gateway-id>/publish" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"expires_at":"2027-01-31T23:59:59Z"}'
Le corps JSON est attendu même sans expiration : envoyez {}. expires_at (RFC 3339) est facultatif ; une valeur mal formée est refusée
plutôt qu'ignorée (400, code VALIDATION_ERROR). Pour une gateway dont le
graphe désigne un patient (lien patient), l'expiration est obligatoire en
pratique : sans expires_at elle vaut 30 jours, au-delà de 90 jours ou dans le
passé la publication est refusée (constantes fixées dans le code). La réponse est la gateway à
jour, avec son public_token.
Transfert, budget
POST .../transfer prend to_workspace_id (obligatoire), reason et
transmission_note. POST /api/v1/gateways/transfer-batch prend
from_workspace_id, to_workspace_id et, facultativement, gateway_ids,
reason, transmission_note. PATCH .../budget prend
{"monthly_limit": <entier>} ; 0 signifie illimité.
Historique des conversations
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/gateways/{id}/chat-sessions | Conversations d'une gateway, par date décroissante |
GET | /api/v1/gateways/{id}/chat-messages | Messages d'une conversation |
GET | /api/v1/gateway-messages | Liste paginée des messages de votre organisation |
POST | /api/v1/gateway-messages | Enregistrer un message |
GET | /api/v1/gateway-messages/{id} | Un message |
DELETE | /api/v1/gateway-messages/{id} | Supprimer un message (204) |
GET .../chat-messages prend chatId (la conversation) et order
(ASC par défaut, ou DESC). GET .../chat-sessions accepte chatType
mais ne filtre pas dessus : la plateforme n'enregistre pas le canal d'une
conversation.
curl "https://<hote-api>/api/v1/gateways/<gateway-id>/chat-messages?chatId=conv-123&order=ASC" \
-H "Authorization: Bearer <token>"
GET /api/v1/gateway-messages prend limit et offset et renvoie
{"gateway_messages": [...], "total": N, "offset": ..., "limit": ...}.
POST /api/v1/gateway-messages prend role, mcp_gateway_id, content,
chat_type et chat_id (et session_id facultatif). Un message d'une
gateway d'une autre organisation répond 403.
Prédiction : poser une question
| Méthode | Route | Accès |
|---|---|---|
POST | /api/v1/prediction/{id} | Public : gateway publiée et non expirée, sinon 404 |
POST | /api/v1/predictions | Authentifié, complétion LLM directe |
POST | /api/v1/predictions/stream | Authentifié, flux SSE |
POST /api/v1/prediction/{id}
{id} est l'identifiant de la gateway. Cette route sert le widget intégrable ;
elle ne demande pas de jeton, mais la gateway doit être publiée. Corps :
question (ou message), sessionId facultatif, streaming facultatif
(accepté, mais la réponse est toujours consolidée en un seul bloc).
curl -X POST "https://<hote-api>/api/v1/prediction/<gateway-id>" \
-H "Content-Type: application/json" \
-d '{"question":"Quels sont les clients avec un chiffre d affaires superieur a 100k ?","sessionId":"conv-123"}'
Réponse (forme de la branche d'exécution d'outil) :
{
"gateway_id": "<uuid>",
"chat_id": "conv-123",
"text": "Voici les clients...",
"response": "Voici les clients...",
"generated_by": { "...": "marquage IA" },
"agent": {
"tool": "<outil utilisé>",
"module": "<module>",
"resolution_path": "<chemin de résolution>",
"confidence": 0.9
}
}
Cas particuliers : 400 MISSING_QUESTION si ni question ni message ;
403 SECURITY_BLOCKED si le garde d'injection de prompt bloque l'entrée ;
une demande de conseil clinique reçoit un refus rédigé avec
refusal_reason. POST /api/v1/prediction (sans identifiant) répond
412 ID_REQUIRED. Le quota par défaut est de 20 requêtes par minute et par
adresse IP sur le préfixe /api/v1/prediction (variable
FORGE_RATE_LIMIT_PREDICTION_PER_MIN). Le limiteur compare le début du chemin :
/api/v1/predictions et /api/v1/predictions/stream tombent dans le même seau.
POST /api/v1/predictions
Complétion directe, jeton obligatoire. Corps : prompt (obligatoire),
system, model, max_tokens, temperature, session_id. Réponse :
{"text", "model", "tokens", "latency_ms", "generated_by"}.
Retours utilisateur
| Méthode | Route | Rôle |
|---|---|---|
POST | /api/v1/feedback | Créer un retour (201) |
GET | /api/v1/feedback | Lister (filtres gateway_id, chat_id, rating) |
GET | /api/v1/feedback/{id} | Un retour |
PUT | /api/v1/feedback/{id} | Mettre à jour |
Corps de création : message_id (uuid), gateway_id (uuid), chat_id,
rating (thumbs_up, thumbs_down ou null) et content. Un autre
rating répond 422 VALIDATION_FAILED.
Warm start
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/mcp/warm-start?userId=<uuid> | Test de reconnexion |
Capacité en sommeil. Cette route répond aujourd'hui toujours
{"warmStart": false, "predictiveQuestion": null, ...}avec le drapeau"shim_pending_v2_1": true. La détection d'inactivité et la question prédictive ne sont pas livrées ; elles sont portées par la tâcheT-V1M2-ENGINES-04de la spec 23. LeuserIddoit être le vôtre (un rôleadminouownerpeut interroger un autre utilisateur) ; sinon403, et400siuserIdest absent.
Santé
| Méthode | Route | Contenu |
|---|---|---|
GET | /api/v1/health | Processus vivant : status, service, version (+ sha) |
GET | /api/v1/healthz | Alias de /health |
GET | /api/v1/readyz | PostgreSQL, Valkey, nombre de connecteurs ; 503 si dégradé |
GET | /api/v1/health/status | Page de statut : PostgreSQL, Ollama, Qdrant, Authentik, SMTP ; 503 si overall vaut down |
Ces quatre routes sont publiques (voir Supervision). readyz ne sonde que PostgreSQL et Valkey ;
l'état d'Ollama et de Qdrant se lit dans /api/v1/health/status.
curl "https://<hote-api>/api/v1/readyz"
Voir aussi
- Chat : la page qui consomme ces routes, onglets, historique et messages proactifs
- Routes des ressources : document stores, identifiants et variables rattachés aux espaces de travail
- Documentation Swagger : obtention du jeton, format des erreurs et limites de débit
- Routes MCP : transport MCP par session, pour appeler directement les outils
- Analytique : mesures de conversations et de messages dans l'application
Routes des ressources
Ce chapitre décrit les ressources que votre organisation gère par l'API :
les document stores (base de connaissances vectorielle), les outils, les
variables, les identifiants, les statistiques et la conformité. Toutes les
routes sont sous /api/v1, exigent un jeton (Authorization: Bearer <token>)
sauf mention contraire, et sont cloisonnées par organisation. <hote-api> est défini dans Swagger.
Document Store (Qdrant)
Un document store est une collection vectorielle (Qdrant) cloisonnée par organisation, utilisée pour la recherche sémantique. L'identifiant du store sert de nom de collection.
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/document-store/store | Liste des stores |
POST | /api/v1/document-store/store | Créer un store |
GET | /api/v1/document-store/store/{id} | Détail d'un store |
PUT | /api/v1/document-store/store/{id} | Mettre à jour (name, description, loaders, whereUsed) |
DELETE | /api/v1/document-store/store/{id} | Supprimer |
POST | /api/v1/document-store/upsert/{id} | Découper, vectoriser et indexer un texte |
POST | /api/v1/document-store/vectorstore/query | Recherche sémantique |
POST | /api/v1/document-store/scrape/page | Récupérer une page, indexation facultative |
POST | /api/v1/document-store/crawl | Lancer un crawl en arrière-plan (202) |
GET | /api/v1/document-store/crawl-progress/{crawl_id} | Avancement d'un crawl |
Créer un store
Corps : name et workspace_id obligatoires, description facultatif.
curl -X POST "https://<hote-api>/api/v1/document-store/store" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"Base juridique","workspace_id":"<uuid-espace>"}'
Réponse 201 : le nouveau store, avec id (c'est le <store-id> des commandes suivantes), name, description, status, workspace_id et created_date.
Indexer un texte
POST /api/v1/document-store/upsert/{id} : {id} est l'identifiant du store.
Corps : content (le texte), source_id et metadata facultatifs. La réponse
est {"store_id", "source_id", "chunks_ingested"}. L'ingestion est soumise au
quota de vecteurs du plan (refus 402, ou 503 si le décompte n'est pas
possible).
curl -X POST "https://<hote-api>/api/v1/document-store/upsert/<store-id>" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"content":"Le droit a l oubli est prevu par l article 17 du RGPD.","source_id":"rgpd-art-17"}'
Interroger
curl -X POST "https://<hote-api>/api/v1/document-store/vectorstore/query" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"query":"droit a l oubli","store_id":"<store-id>"}'
Réponse : {"query", "store_id", "results": [...], "total": N}.
Récupérer et crawler une page
POST .../scrape/page prend url et, pour indexer le résultat, store_id.
POST .../crawl prend url et store_id et répond 202 avec un crawl_id
à suivre sur GET .../crawl-progress/{crawl_id}.
Ce qui n'existe pas, ou ne fonctionne pas encore
- Il n'y a pas de route
.../store/{id}/upload(téléversement multipart), ni.../store/{id}/crawl, ni.../store/{id}/chunks. L'indexation de texte passe parupsert/{id}. Un chunk se modifie (PUT) et se supprime (DELETE) sur/api/v1/document-store/chunks/{store_id}/{loader_id}/{chunk_id}. Ses métadonnées se modifient (PATCH) sur le même chemin suivi de/metadata. Il n'y a pas de lecture (GET) sur ce chemin : les chunks se lisent parGET /api/v1/documents/{doc_id}/chunksetGET /api/v1/doc-chunks/{id}. - Trois routes de loader répondent
503 FEATURE_PENDING(capacité en sommeil, la réponse l'annonce au lieu de simuler un succès) :POST /api/v1/document-store/loader/process/{loader_id},POST /api/v1/document-store/loader/upload-urletPOST /api/v1/document-store/loader/upload-table. POST /api/v1/document-store/refreshet.../refresh/{store_id}accusent réception ("status": "queued") sans lancer de traitement.- Pour les documents bruts (fichiers), voir aussi
/api/v1/documentset/api/v1/attachments.
Outils personnalisés
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/tools | Liste |
POST | /api/v1/tools | Créer |
GET | /api/v1/tools/{id} | Détail |
PUT | /api/v1/tools/{id} | Mettre à jour |
DELETE | /api/v1/tools/{id} | Supprimer |
Corps de création, en camelCase : name, description, color, iconSrc,
schema (chaîne), func (chaîne), workspaceId.
Variables
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/variables | Liste |
POST | /api/v1/variables | Créer |
GET | /api/v1/variables/{id} | Détail |
PUT | /api/v1/variables/{id} | Mettre à jour |
DELETE | /api/v1/variables/{id} | Supprimer |
Corps de création : name, workspace_id obligatoires ; value et type
facultatifs.
Identifiants
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/credentials | Liste (valeurs masquées) |
POST | /api/v1/credentials | Créer |
GET | /api/v1/credentials/{id} | Détail (valeur masquée) |
PUT | /api/v1/credentials/{id} | Mettre à jour |
DELETE | /api/v1/credentials/{id} | Supprimer |
curl -X POST "https://<hote-api>/api/v1/credentials" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"name":"Ma cle de service","value":"<secret>"}'
Pour brancher un connecteur, envoyez credentialName et plainDataObj (un objet de champs) à la place de value, comme à l'étape 1 de Connecter Odoo à la passerelle MCP. workspaceId est facultatif (par défaut, le premier espace accessible). La réponse est 201, avec la fiche : id, name, credential_name, masked_value, workspace_id, created_at et updated_at.
La valeur est chiffrée au repos (AES-256-GCM, clé dérivée par identifiant) et
n'est jamais renvoyée en clair : les réponses portent une valeur masquée.
PUT et DELETE sur /api/v1/credentials sans identifiant sont refusés par
conception (412).
Statistiques
| Méthode | Route | Rôle |
|---|---|---|
GET | /api/v1/stats | Tableau de bord global (rôle admin ou owner) |
GET | /api/v1/stats/gateways | {"total", "last_24h"} des gateways |
GET | /api/v1/stats/tools | {"total", "last_24h"} des outils (last_24h répète total : un outil n'a pas de date de création) |
/api/v1/stats/dashboard est un autre chemin vers le même tableau de bord. La
famille /api/v1/stats/* compte plus de vingt autres routes de lecture
(leads, workflows, security, latency, ollama, entre autres). La liste complète est
dans le contrat de routes de router.rs.
Conformité et audit
| Méthode | Route | Accès |
|---|---|---|
GET | /api/v1/compliance/status | Public : statut gradué RGPD / AI Act |
GET | /api/v1/compliance/report | Public |
GET | /api/v1/compliance/privacy | Public |
GET | /api/v1/compliance/model-cards | Public |
GET | /api/v1/compliance/manifest | Public : manifeste de confiance signé |
GET | /api/v1/compliance/system-card | Public |
GET | /api/v1/admin/audit | Journal d'audit chaîné (rôles admin et owner) |
GET | /api/v1/admin/audit/head | Tête de la chaîne |
GET | /api/v1/admin/audit/stats | Statistiques du journal |
GET | /api/v1/admin/audit/export | Export de la chaîne |
/api/v1/compliance/status rend des statuts gradués (par exemple
"gdpr": {"status": "partial", ...} et "ai_act": {"status": "in_progress", ...}),
dérivés de signaux réels, jamais une affirmation figée de conformité totale.
Il n'existe pas de sous-route
rgpdniaudit-logsouscompliance(d'anciennes versions de ce livre les citaient). Le journal d'audit se lit sur/api/v1/admin/audit. La routeGET /api/v1/audit/eventsexiste mais répond501: elle n'est pas branchée sur le registre, et sa réponse nomme la route canonique.
Voir aussi
- Routes des gateways et de la prédiction : gateways, prédiction, retours utilisateur et historique des conversations
- Routes MCP : transport MCP par session, pour appeler les outils des connecteurs
- Documentation Swagger : obtention du jeton, format des erreurs et limites de débit
- OpenBao et secrets : coffre optionnel pour les secrets des connecteurs, prioritaire sur la base
- Analytique : la page Conformité EU qui affiche le rapport de l'API
Créer votre premier connecteur MCP
Ce tutoriel décrit le chemin réel pour ajouter un service HTTP à la
passerelle MCP de Chatbotaurus : un fichier YAML déclaratif, une ligne dans
la liste des serveurs autorisés, des identifiants chiffrés, puis un appel de
test. Il s'adresse à un contributeur qui travaille sur le dépôt. À la fin, l'outil de votre service figure dans tools/list et un appel tools/call en rend les données.
Prérequis
- Chatbotaurus installé et fonctionnel (voir Installation).
- Le dépôt cloné : le connecteur est un fichier du dépôt, pas un réglage de l'interface.
- Python 3 pour le validateur de connecteurs.
- Un jeton de session d'un compte du locataire, obtenu comme décrit dans Swagger (section Authentification), puis rangé dans la variable
JWT:export JWT=<token>. - De quoi reconstruire le backend : l'étape 3 modifie du code Rust, compilé dans le binaire.
- Un accès au service que vous branchez (adresse et clé), avec les seuls droits utiles.
Les commandes de ce tutoriel visent le backend local http://localhost:3000. Sur un déploiement, remplacez cette adresse par celle de votre API (https://<hote-api> dans les chapitres API).
Ce qu'est un connecteur
Un connecteur déclaratif est un fichier connectors/<id>.yaml. Au démarrage,
forge-api lit tous les fichiers de ce dossier, remplace les
${VAR:-défaut} par l'environnement, et enregistre un connecteur HTTP dans le
registre. Un fichier invalide est ignoré avec un message de journal : il ne
fait pas échouer le démarrage, il disparaît. C'est la première chose à
vérifier quand un connecteur « n'apparaît pas ».
Un connecteur n'est pas un module Rust à écrire. Pour un service HTTP, le YAML suffit. Le code Rust n'intervient que pour des protocoles qui ne sont pas du HTTP (c'est le cas d'Odoo, dispatché en XML-RPC).
Étape 1 : partir du gabarit
Copiez le gabarit, qui est la forme de référence maintenue avec le parseur :
cp connectors/TEMPLATE.yaml connectors/mon-service.yaml
Remplissez les champs obligatoires :
id: mon-service # kebab-case, identique au nom de fichier
display_name: "Mon Service"
upstream_status: a_verifier # hebergeable | a_verifier | non_http
base_url: "${MON_SERVICE_URL:-https://api.mon-service.eu}"
base_url_env: MON_SERVICE_URL
auth: { type: bearer, token_env: MON_SERVICE_API_KEY }
compliance:
data_residency: self-hosted
self_hosted: true
gdpr_compliant: true
license: "MIT"
gaia_x: true
timeout_ms: 30000
tools:
- name: mon_service_list_items
description: "Lister les éléments, avec filtres optionnels."
method: GET
path: "/items"
param_location: query
input_schema:
type: object
properties:
limit: { type: integer }
- name: mon_service_get_item
description: "Récupérer un élément par identifiant."
method: GET
path: "/items/{id}"
param_location: path
input_schema:
type: object
properties:
id: { type: string }
required: [id]
- name: mon_service_create_item
description: "Créer un élément."
method: POST
path: "/items"
param_location: body
input_schema:
type: object
properties:
title: { type: string }
required: [title]
Cinq règles qui évitent les pannes silencieuses :
- Chaque outil porte
methodetpath. Sans eux, le chargement du connecteur échoue et le catalogue avale l'erreur. - Avec
param_location: path, seuls les arguments qui correspondent à un{placeholder}du chemin sont transmis. Les autres sont abandonnés sans message : un filtre déclaré ainsi ne filtre rien. Utilisezqueryoubody. - Un outil qui écrit commence par un verbe d'écriture (
create,update,delete, entre autres). Le nom sert aux contrôles de sécurité à classer l'outil en lecture ou en écriture. - Le
data_residencydoit appartenir àeu,eu-west,eu-central,france,germany,finland,netherlands,irelandouself-hosted, etgdpr_compliantdoit être vrai : sinon le registre rejette le connecteur. - Les secrets ne sont jamais dans le YAML : seulement le nom de la variable
(
token_env). Les types d'authentification du gabarit sontnone,bearer,api_key,basicetquery_token. Le parseur en connaît d'autres (login_token,oauth2,jwt_exchange, entre autres) : voir l'énumérationAuthConfigdanscrates/forge-mcp/src/connector/http.rs.
Choisissez un base_url par défaut qui répond réellement : un défaut qui ne
résout jamais fabrique un connecteur qu'aucune mesure ne pourra rendre vert.
Étape 2 : valider le fichier
python scripts/audit/validate-connectors.py
Le validateur lit le même schéma que le parseur. Résultat attendu : la ligne
[OK] HARD checks all passed. et le code de sortie 0. Une ligne [FAIL] suivie
de la liste des fautes dit ce qu'il faut corriger : corrigez tout message de
niveau HARD avant de continuer. La licence déclarée sous
compliance.license est aussi contrôlée par une garde du dépôt, qui refuse les
licences à source disponible (SSPL, BSL, BUSL, Elastic-2.0 et assimilées).
Étape 3 : autoriser le connecteur
La passerelle refuse de dispatcher un connecteur dont l'identifiant ne figure
pas dans la liste des serveurs autorisés. C'est le point d'étranglement de
conformité européenne : sans cette ligne, le connecteur se charge, mais ses
outils n'apparaissent pas dans tools/list (outils_autorises,
crates/forge-mcp/src/gateway.rs) et l'appel est refusé. Les fiches
dolibarr et freescout sont dans ce cas.
Ajoutez "mon-service" à ALLOWED_MCP_SERVERS dans
crates/forge-core/src/compliance/allowed_servers.rs. Un test du même
fichier compte les entrées de la liste : mettez à jour ce compte avec une
justification dans le commit, c'est voulu.
Étape 4 : enregistrer les identifiants du locataire
Les identifiants d'un locataire sont chiffrés en AES-256-GCM en base. Au moment d'un appel, la passerelle déchiffre les identifiants
du locataire et les publie comme variables d'environnement, pour cette seule
requête. Tout champ de la fiche dont le nom ressemble à une variable de
connecteur (majuscules et suffixe _KEY, _TOKEN, _SECRET, _PASSWORD,
_USER, _URL, _ID, _DATABASE, entre autres) est publié tel quel : nommez donc les
champs comme les variables du YAML.
curl -X POST http://localhost:3000/api/v1/credentials \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "mon-service-prod",
"credentialName": "monServiceApi",
"plainDataObj": {
"MON_SERVICE_URL": "https://api.mon-service.eu",
"MON_SERVICE_API_KEY": "votre-clé-secrète"
}
}'
Résultat attendu : 201, avec la fiche créée (id, name, credential_name, masked_value, workspace_id, created_at, updated_at). La valeur secrète n'est jamais renvoyée. Sans workspaceId, la fiche va dans le premier espace de travail accessible ; sans espace accessible, la réponse est 400 (NO_WORKSPACE).
La page /credentials de l'application propose la même action par un
formulaire pour les fiches du catalogue de l'interface.
Étape 5 : recharger les connecteurs
Les fichiers de connectors/ ne sont lus qu'au démarrage du backend.
- En développement, le surveillant du backend reconstruit et remplace le processus ; sinon relancez le lanceur du backend.
- Sur un déploiement Podman, le dossier
connectors/et la liste de l'étape 3 sont copiés dans l'image du backend à la construction : reconstruisez l'image avec votre modification (voir Déploiement avec Podman), puis redémarrez le conteneur :
podman restart forge-api
Contrôlez ensuite le journal de démarrage : une ligne failed to load connector config ou connector rejected by registry nomme le fichier fautif.
L'absence de ces deux lignes, puis la présence de vos outils dans tools/list
(étape 6), confirment le chargement.
Étape 6 : tester par le protocole MCP
Le transport est Streamable HTTP sur un seul point d'entrée,
/api/v1/mcp. Il faut d'abord ouvrir une session ; l'identifiant revient dans
l'en-tête Mcp-Session-Id.
# 1. Ouvrir la session et lire l'en-tête de réponse Mcp-Session-Id
curl -i -X POST http://localhost:3000/api/v1/mcp \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}'
# 2. Lister les outils
curl -X POST http://localhost:3000/api/v1/mcp \
-H "Authorization: Bearer $JWT" \
-H "Mcp-Session-Id: $SESSION" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":2}'
# 3. Appeler un outil : le nom est <id du connecteur>.<nom de l'outil>
curl -X POST http://localhost:3000/api/v1/mcp \
-H "Authorization: Bearer $JWT" \
-H "Mcp-Session-Id: $SESSION" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "mon-service.mon_service_list_items",
"arguments": { "limit": 5 }
},
"id": 3
}'
Résultats attendus :
- Appel 1 :
200, un en-têtemcp-session-idet un corpsresult(protocolVersion,capabilities,serverInfo). Copiez l'identifiant dans la variableSESSION:export SESSION=<session-id>. - Appel 2 :
200etresult.tools, une liste d'objetsname,description,inputSchemaetconnector_id. Ajoutez| jq -r '.result.tools[].name | select(startswith("mon-service."))'à la commande pour ne garder que vos outils. Si votre connecteur n'y figure pas, vérifiez l'étape 3 (liste), l'étape 5 (rechargement) et le journal de démarrage. - Appel 3 :
200aussi.result.typevautsuccessetresult.contentporte les blocs de texte. Avant l'exécution, un échec est un objeterrorà la place deresult, eterror.codereprend le code HTTP de l'échec (401session expirée,403serveur hors de la liste autorisée,404outil inconnu). Si votre service amont échoue,result.typevauterroretresultportecodeetmessage.
Sans Mcp-Session-Id, tools/call répond 400. Une session expire après
30 minutes d'inactivité.
Quand le YAML ne suffit pas
Pour un protocole qui n'est pas du HTTP, un connecteur natif implémente le
trait McpConnector du crate forge-mcp
(crates/forge-mcp/src/connector/mod.rs) : id, display_name,
compliance, list_tools, execute, health_check, et
required_auth_env_vars si le connecteur consomme un secret. Le connecteur
Odoo (odoo_xmlrpc_client.rs) est l'exemple à lire. Ce cas est rare.
Bonnes pratiques
- Les lectures peuvent être mises en cache (
cache_ttl_s, désactivé par défaut). Le cache n'est jamais actif sous un contexte de locataire, pour qu'aucune réponse ne passe d'un locataire à l'autre. - Déclarez
timeout_msen fonction du service cible. - Testez le connecteur contre le service réel avant de le proposer : un connecteur qui répond 200 sur une réponse non filtrée est un faux vert.
Voir aussi
- Conception des connecteurs MCP : deux types de connecteurs, contrôle de conformité UE et cycle de vie
- Connecteurs MCP : chiffres mesurés, chargement et règles communes aux douze connecteurs
- Routes MCP : transport Streamable HTTP, sessions et appel d'un outil
- Connecter Odoo à la passerelle MCP : le même parcours pour un connecteur natif, hors HTTP
- Fichiers de configuration : manifestes de connecteurs parmi les fichiers que le code lit
Connecter Odoo à la passerelle MCP
Ce tutoriel montre comment relier votre instance Odoo à Chatbotaurus, puis appeler un premier outil. Le connecteur Odoo parle XML-RPC avec une clé d'API Odoo. Il n'y a ni module à installer côté Odoo pour les modèles standard, ni mot de passe d'utilisateur à confier à la plateforme.
Prérequis
- Une instance Odoo accessible depuis le backend Chatbotaurus : la vôtre, ou
l'une des instances de démonstration du plan client (une par secteur,
conteneurs nommés
mcp-odoo-<secteur>). - Quatre informations Odoo : l'URL du serveur, le nom de la base, le nom d'utilisateur et une clé d'API.
- Un compte Chatbotaurus et un jeton de session (section Authentification), rangé dans la variable
JWT:export JWT=<token>. - Un espace de travail accessible à ce compte : la fiche d'identifiants y est rangée.
Les exemples visent http://localhost:3000. Avec un compte hébergé, remplacez cette adresse par celle de votre API (https://<hote-api>, voir API-as-a-Service EU souverain).
La clé d'API se crée dans Odoo, depuis les préférences de l'utilisateur (onglet Sécurité du compte). Utilisez un utilisateur dédié, dont les droits Odoo sont limités à ce que l'assistant doit faire. Les droits du compte API sont la dernière barrière d'autorisation.
Ce qui est exposé
Le registre de dispatch Odoo contient 711 outils nommés, regroupés par
module (contacts, CRM, ventes, achats, stock, comptabilité, RH, projet, entre autres).
S'y ajoute un quatuor générique record_create / record_read / record_update /
record_delete, qui prend le modèle en argument pour les modèles métier sans
outil nommé. Les noms sont de la forme <module>_<objet>_<action>, par
exemple contacts_search, contacts_create, crm_lead_create,
sales_order_confirm.
Trois règles de sécurité s'appliquent, quelle que soit la configuration :
- Les outils destructifs (nom portant
drop,truncate,erase,purge,wipe, ou se terminant parunlinkoudestroy) ne sont jamais exécutés par l'agent, même approuvés. Les outils irréversibles (suppression, annulation, remboursement, paiement) ne s'exécutent qu'après une autorisation humaine explicite (crates/forge-mcp/src/connector/human_authorization.rs). - Une écriture ciblée (
update,delete, action) exige unidentier explicite ; sans cible, elle est refusée au lieu de réussir dans le vide. - Les modèles du noyau comptable sont en lecture seule pour l'agent ; une écriture y passe par l'approbation d'un humain.
Les noms odoo_search_read, odoo_create ou odoo_execute_kw n'existent pas
dans le registre : prenez les noms réels dans la réponse de tools/list.
Étape 1 : enregistrer les identifiants du locataire
Depuis l'application, ouvrez la page Identifiants (/credentials),
choisissez la fiche Odoo ERP/CRM et renseignez les quatre champs :
| Champ du formulaire | Contenu |
|---|---|
| URL du serveur | l'adresse de votre Odoo |
| Database | le nom de la base Odoo |
| Username | l'identifiant de l'utilisateur API |
| API Key | la clé d'API créée dans Odoo |
Par l'API, la même fiche s'enregistre ainsi (credentialName doit valoir
odooApi, c'est lui qui relie la fiche au connecteur) :
curl -X POST http://localhost:3000/api/v1/credentials \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "odoo-ma-societe",
"credentialName": "odooApi",
"plainDataObj": {
"odooUrl": "https://odoo.exemple.eu",
"odooDatabase": "ma_base",
"odooUsername": "api_user@exemple.eu",
"odooApiKey": "votre-clé-api"
}
}'
Résultat attendu de la commande : 201 et la fiche créée (id, name, credential_name, masked_value, workspace_id, created_at, updated_at), sans la clé d'API.
Les quatre champs sont tous nécessaires : un jeu incomplet est refusé par le connecteur au lieu d'être complété au hasard. Les données sont chiffrées au repos, et les champs secrets (la clé d'API) sont masqués quand la fiche est relue.
Étape 2 : ouvrir une session MCP
curl -i -X POST http://localhost:3000/api/v1/mcp \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}'
Résultat attendu : 200, un corps result (protocolVersion, capabilities, serverInfo) et l'en-tête mcp-session-id. Copiez sa valeur dans la variable SESSION (export SESSION=<session-id>) : elle est
obligatoire sur les appels suivants (voir Routes MCP) et expire après 30 minutes d'inactivité.
Étape 3 : appeler un premier outil
Un outil Odoo s'appelle par son nom préfixé par odoo.. Les paramètres sont
à plat : query (terme libre cherché dans les champs textuels du modèle),
limit, offset, order, fields. S'y ajoutent des filtres sur les champs du
modèle (un suffixe tel que __gte ou __lte choisit l'opérateur).
curl -X POST http://localhost:3000/api/v1/mcp \
-H "Authorization: Bearer $JWT" \
-H "Mcp-Session-Id: $SESSION" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "odoo.contacts_search",
"arguments": { "query": "dupont", "limit": 5 }
},
"id": 2
}'
Résultat attendu : 200, result.type égal à success et les lignes trouvées dans result.content. Un échec avant l'exécution (session expirée, outil inconnu) arrive sous la forme d'un objet error dont error.code reprend le code HTTP de l'échec ; un échec d'Odoo lui-même arrive dans result, avec result.type égal à error : voir Dépannage plus bas.
Sans limit, une recherche rend jusqu'à 500 lignes. Précisez toujours une
borne.
Étape 4 : utiliser le chat
Une fois la fiche enregistrée, vous n'avez plus besoin d'appeler les outils à la main. Posez la question dans le chat (« quels sont mes derniers contacts ? ») et le routeur choisit l'outil Odoo adapté. Les lectures sont exécutées directement ; une suppression, un paiement ou une écriture sur les modèles comptables gardés attend une approbation (voir Odoo, section Écritures gardées).
Champs personnalisés
Un champ Odoo personnalisé (préfixe x_) s'installe par un module d'addon
Odoo, au moment de l'installation de l'instance. Il ne se crée jamais par
XML-RPC en cours d'exploitation : une telle écriture fige le conteneur Odoo.
Une fois le champ présent, il est lisible et écrivible comme n'importe quel
champ du modèle.
Dépannage
| Symptôme | Cause probable |
|---|---|
| Refus pour jeu d'identifiants incomplet | un des quatre champs de la fiche est vide |
| Erreur d'authentification Odoo | clé d'API révoquée, ou utilisateur sans accès à la base indiquée |
| 400 « missing Mcp-Session-Id » | l'étape 2 n'a pas été faite, ou l'en-tête manque |
| Outil refusé « destructive tool » ou « irreversible tool » | comportement voulu : un outil destructif n'est jamais exécuté par l'agent, un outil irréversible (par exemple une suppression) exige une validation humaine |
Outil inconnu (error.code 404, statut HTTP 200) | un nom absent du registre, par exemple un ancien nom ; consultez les noms réels par tools/list |
error.code 401 | la session de l'étape 2 a expiré (30 minutes d'inactivité) : ouvrez-en une nouvelle |
Réponse 400 NO_WORKSPACE à l'étape 1 | aucun espace de travail n'est accessible à ce compte |
Voir aussi
- Connecteur Odoo : outils nommés, outils génériques et écritures gardées du connecteur
- Routes MCP : sessions, en-têtes et méthodes JSON-RPC utilisés par ce tutoriel
- Utiliser les connecteurs MCP : où vivent les connecteurs et comment consulter le catalogue
- Problèmes connus : pannes connues de la passerelle MCP et des conteneurs
- Gestion des erreurs : lire un code d'erreur de l'API ou du transport MCP
- Créer votre premier connecteur MCP : ajouter un connecteur HTTP déclaratif, le cas général
Parcourir le catalogue de services et préparer un déploiement
Le catalogue métier est la liste des serveurs MCP que la plateforme sait décrire, regrouper en profils et suivre. Ce tutoriel parcourt ce qui fonctionne aujourd'hui (consulter, filtrer, lire les profils, connaître l'état) et dit sans détour où s'arrête l'automatisation : le déploiement d'un service par l'API est en sommeil et répond 503.
Ce qui marche, ce qui est en sommeil
| Opération | Route (préfixe /api/v1/mcp/catalog-business) | État |
|---|---|---|
| Lister le catalogue | GET / | actif |
| Détail d'un serveur | GET /{id} | actif |
| Lister les profils | GET /profiles | actif |
| Serveurs prouvés opérationnels | GET /deployed | actif |
| État d'un serveur | GET /{id}/status | actif (disponibilité au registre) |
| Déployer un serveur | POST /{id}/deploy | 503, en sommeil |
| Déployer un profil | POST /profiles/{name}/deploy | 503, en sommeil |
| Démarrer / arrêter / redémarrer | POST /{id}/start, /stop, /restart | 503, en sommeil |
| Profil de sécurité | GET /{id}/security | 503, en sommeil |
| Enregistrer des secrets | POST /{id}/secrets | 503, en sommeil |
Les opérations en sommeil dépendent du pilotage de Podman par le backend,
pas encore branché. Tant qu'il ne l'est pas, elles répondent 503 avec
l'en-tête Retry-After et un corps FEATURE_PENDING, jamais un faux
succès. Les opérations de cycle de vie sont de plus réservées aux rôles
admin et owner : tout autre rôle reçoit 403. Seule exception, GET /{id}/security : ouverte à tout utilisateur connecté, elle répond 503.
Toutes les routes exigent un jeton de session ($JWT).
Prérequis
- Chatbotaurus installé et fonctionnel (voir Installation).
- Un jeton de session (Swagger, section Authentification), rangé dans la variable
JWT. Pour tenter un déploiement, un compte de rôleadminouowner. curletjqpour les commandes ci-dessous, lancées contre le backend localhttp://localhost:3000(sur un déploiement, remplacez cette adresse par celle de votre API).
Étape 1 : consulter le catalogue
# Tous les serveurs
curl -s -H "Authorization: Bearer $JWT" \
http://localhost:3000/api/v1/mcp/catalog-business \
| jq '.servers[] | {id, name, category, status}'
# Filtrer par catégorie
curl -s -H "Authorization: Bearer $JWT" \
"http://localhost:3000/api/v1/mcp/catalog-business?category=CRM%20%26%20ERP" | jq .total
# Le détail d'un serveur
curl -s -H "Authorization: Bearer $JWT" \
http://localhost:3000/api/v1/mcp/catalog-business/odoo | jq .
La réponse est de la forme { "servers": [...], "total": N }. Chaque entrée
porte id, name, description, category, provider, country,
license, status, tags et version. Le champ status vaut available
ou coming-soon : le catalogue décrit plus de serveurs qu'il n'en livre, et
ce champ dit lesquels sont prêts. Un identifiant inconnu rend 404.
Étape 2 : lire les profils
Un profil est un regroupement de serveurs pour un usage. La réponse est de la forme { "profiles": [...] }.
curl -s -H "Authorization: Bearer $JWT" \
http://localhost:3000/api/v1/mcp/catalog-business/profiles | jq .
Il existe quatre profils : Solo (l'ERP seul), Starter (cinq
serveurs : ERP, automatisation, analytique, fichiers, modèle local),
Business (douze serveurs, avec agenda, documents, visioconférence, GED,
supervision et voix) et Enterprise (tous les serveurs du fichier de
profils). Les identifiants de serveurs d'un profil sont ceux du fichier de
profils, tenu côté serveur : ils portent le préfixe mcp-
et le suffixe -eu, et diffèrent des id de la
liste du catalogue (par exemple odoo).
Étape 3 : savoir ce qui est réellement opérationnel
curl -s -H "Authorization: Bearer $JWT" \
http://localhost:3000/api/v1/mcp/catalog-business/deployed | jq .
Cette route ne rend pas un inventaire de conteneurs. Elle rend la liste des serveurs prouvés opérationnels, sous la forme d'un tableau JSON d'identifiants : un identifiant n'y figure que si un outil de lecture a rendu des données réelles lors d'une vérification en direct. Elle sert de source unique à l'application, qui affiche donc le même état « déployé » sur toutes ses pages.
curl -s -H "Authorization: Bearer $JWT" \
http://localhost:3000/api/v1/mcp/catalog-business/odoo/status | jq .
L'état d'un serveur dit s'il est enregistré dans le registre (available
ou not_registered), s'il est prouvé opérationnel, et que l'état d'exécution
du conteneur est inconnu tant que le pilotage Podman n'est pas branché
(runtime.known: false).
Étape 4 : tenter un déploiement
curl -i -X POST -H "Authorization: Bearer $JWT" \
http://localhost:3000/api/v1/mcp/catalog-business/odoo/deploy
Avec un compte admin ou owner, la réponse attendue aujourd'hui est :
HTTP/1.1 503 Service Unavailable
Retry-After: 86400
{ "error": { "code": "FEATURE_PENDING", ... }, "feature_pending": "catalog_business" }
Avec un autre rôle, c'est 403. Ce 503 n'est pas une panne : c'est l'état
documenté de la fonction. Arrêtez-vous là côté API.
Comment déployer un service en attendant
Les services du catalogue destinés au plan client sont décrits dans le fichier
Compose du plan client, où chaque serveur MCP est un service nommé mcp-*.
Le déploiement passe par ce plan, avec podman-compose (avec un tiret),
décrit dans Déploiement avec Podman. Les
secrets ne passent pas par l'API du catalogue : ils sont enregistrés en
identifiants du locataire (page /credentials), comme dans le tutoriel
Connecter Odoo.
Dans l'application
La page MCP > Serveurs Business (/mcp/servers/business) présente le
même catalogue, avec l'état « déployé » tiré de la route /deployed. La page
de passerelle par secteur (/mcp/gateways/business) regroupe les serveurs
par métier. Ce sont des pages de l'application, pas des routes d'API.
Voir aussi
- Routes du catalogue métier : toutes les routes du catalogue, lecture et cycle de vie, avec leurs réponses
- Déploiement avec Podman : déployer les plans avec podman-compose en attendant l'automatisation
- Architecture Chatbotaurus : deux plans, règle de nommage et crates du workspace
- MCP et Orchestrateur : les pages de l'application qui présentent ce catalogue
- Tarification et offres : offres, déploiement assisté des outils métier et quotas
Variables d'environnement
Le backend forge-api se configure par variables d'environnement. Il lit le
fichier .env au démarrage avec dotenvy, puis lit les variables du processus.
Ce chapitre liste les variables que le code lit réellement, avec leur défaut
quand il existe. Il ne liste pas les 2 992 lignes du fichier modèle .env.example
(mesure du 2026-10-03 : wc -l .env.example) : la plupart concernent des
outils tiers et des connecteurs, pas le backend.
Règle de lecture. Une variable citée ici est lue par le code ; le fichier est indiqué quand il importe. Ce chapitre n'est pas exhaustif : il omet des options réservées à un module précis. Pour savoir si une variable est lue :
grep -rn "NOM_DE_LA_VARIABLE" crates/*/src.
Priorité
- Les variables du processus (celles que pose le lanceur,
podmanou la session) priment.dotenvyne remplace jamais une variable déjà définie. - Le fichier
.envdu répertoire courant complète ce qui manque. - Les valeurs par défaut compilées dans le code s'appliquent en dernier.
Le code ne charge aucun fichier .env.staging ni .env.production. Pour un
autre environnement, posez les variables dans le processus.
Les secrets de production ne sont pas dans le dépôt. Sur chaque hôte, un script d'initialisation génère les fichiers d'environnement sur la machine cible, avec des permissions restreintes, et n'imprime jamais les valeurs (script d'initialisation des secrets de l'hôte). OpenBao peut en plus surcharger des secrets au démarrage (voir la section « Secrets externes (OpenBao) » plus bas).
Pour générer un secret : openssl rand -hex 32.
Variables exigées au démarrage
Si l'une d'elles manque, forge-api s'arrête avec le code 1
(contrôle de démarrage du code).
| Variable | Rôle | Règle |
|---|---|---|
DATABASE_URL | URL PostgreSQL | Obligatoire |
REDIS_URL | URL Valkey (compatible Redis) | Obligatoire. VALKEY_URL, si elle existe, est lue en premier pour la connexion |
JWT_SECRET | Secret de signature des jetons (HS256) | 32 caractères au moins, ni valeur par défaut connue, ni gabarit (change_me, replace_me, entre autres) |
Serveur HTTP
| Variable | Rôle | Défaut |
|---|---|---|
PORT | Port d'écoute | 3000 |
HOST | Adresse d'écoute (BIND_ADDRESS en repli) | toutes les interfaces |
APP_URL | URL publique de l'application | http://localhost:8008 (défaut de forge-core, port historique : l'API écoute sur 3000) |
CORS_ORIGINS | Origines autorisées, séparées par des virgules | http://localhost:8080, :8081, :8082 |
COOKIE_DOMAIN | Domaine des cookies de session en production | vide |
FORGE_MAX_BODY_BYTES | Taille maximale d'un corps de requête | 2 Mio |
FORGE_MAX_UPLOAD_BYTES | Taille maximale d'un envoi multipart | 25 Mio |
CSP_HEADER, HSTS_HEADER | Remplacent les en-têtes Content-Security-Policy et Strict-Transport-Security | valeurs du code |
Journalisation
| Variable | Rôle | Défaut |
|---|---|---|
RUST_LOG | Filtre tracing-subscriber | info,forge_api=debug,forge_mcp=debug quand la variable est absente ou invalide |
LOG_FORMAT | pretty ou compact : sortie lisible. Toute autre valeur : JSON | JSON |
TRACING_JSON, posée dans podman-compose.yml, n'est lue que par
forge_core::observability::init_tracing, que forge-api n'appelle pas : il
appelle sa propre fonction init_tracing (crates/forge-api/src/main.rs). Elle
ne change donc rien au format des journaux de forge-api.
Voir Journaux.
Authentification
| Variable | Rôle | Défaut |
|---|---|---|
JWT_EXPIRY | Durée du jeton d'accès : 7d, 24h, 30m, 3600s ou un nombre de secondes | 7 jours |
JWT_EXPIRY_SECS | Alias en secondes, lu si JWT_EXPIRY est absente ou illisible | 7 jours |
FORCE_2FA | Impose un second facteur à la connexion par mot de passe (true ou 1) : code TOTP si le compte l'a enrôlé, sinon code envoyé par e-mail | true |
FORGE_MFA_TOTP_REQUIRED | 1 ou true : refuse la connexion d'un compte sans TOTP enrôlé, pour tous les comptes | désactivé |
FORGE_MFA_REQUIRED_ROLES | Rôles séparés par des virgules (par exemple admin,owner) : même refus, pour ces rôles seulement | vide |
FORGE_PQC_ENABLED | 1 ajoute une signature ML-DSA-65 au jeton de session, en plus de HS256 | désactivé |
NODE_ENV, ENVIRONMENT, RUST_ENV, APP_ENV | Déclarent l'environnement. development, dev, local ou test déclarent un développement | absent = posture production |
FORGE_DEV | 1, true ou yes déclare un développement | absent |
Le silence ne relâche aucune garde : sans déclaration explicite de
développement, forge-api applique la posture production.
Les deux réglages FORGE_MFA_* sont lus par la connexion par mot de passe. Un compte créé par le SSO n'a pas de
second facteur applicatif : Authentik le porte en amont.
Le code de vérification envoyé par e-mail et le jeton intermédiaire du second facteur vivent quelques minutes dans Valkey (valeur fixe dans le code).
Clés de durcissement
| Variable | Rôle | Règle |
|---|---|---|
AT_REST_ENCRYPTION_KEY | Racine du chiffrement des secrets stockés (TOTP, identifiants de connecteurs, SSO) | Distincte de JWT_SECRET. Sans elle, le code retombe sur JWT_SECRET |
AUDIT_SIGNING_KEY | Signature de la chaîne d'audit | Sans elle, la chaîne n'est pas signée |
FORGE_STRICT_SECRETS | 1 rend les deux clés ci-dessus obligatoires | Sans cette variable, leur absence est un avertissement |
FORGE_TENANT_STRICT | 1 active le cloisonnement strict par organisation | Obligatoire hors développement déclaré, sinon arrêt au démarrage |
FORGE_MULTI_TENANT_STRICT | Désactive l'hydratation globale des identifiants de connecteurs | Posée sur les hôtes de production |
PHI_AT_REST_KEY | Clé de 64 caractères hexadécimaux pour le chiffrement des données de santé | Obligatoire en production, tolérée absente en développement déclaré |
PHI_AT_REST_KEY_PREVIOUS | Ancienne clé, lue en repli pendant une rotation | Optionnelle |
EXPORT_SEAL_KEY | Scellement des exports | Optionnelle. Absente : l'export scellé est indisponible |
Détails : Sécurité.
Limiteurs de débit (connexion)
| Variable | Rôle | Défaut |
|---|---|---|
ACCOUNT_HASH_SALT | Sel du hachage d'identité par compte | vide. Vide = limiteur par compte désactivé |
ACCOUNT_RATE_LIMIT_FAILURES_BLOCK | Échecs avant blocage du compte | défaut du code, non publié |
ACCOUNT_RATE_LIMIT_WINDOW_SECS | Fenêtre de comptage | défaut du code, non publié |
ACCOUNT_RATE_LIMIT_BLOCK_SECS | Durée du blocage | défaut du code, non publié |
AUTH_RATE_LIMIT_FAILURES_BACKOFF | Échecs par IP avant ralentissement | défaut du code, non publié |
AUTH_RATE_LIMIT_FAILURES_BLOCK | Échecs par IP avant blocage | défaut du code, non publié |
AUTH_RATE_LIMIT_BLOCK_DURATION_SECS | Durée du blocage par IP | défaut du code, non publié |
AUTH_RATE_LIMIT_WHITELIST | IP exemptées du seau par IP, séparées par des virgules | vide |
Sources : les deux limiteurs de connexion du code.
Purges planifiées
Ces purges sont actives par défaut. Une variable à 0 (ou false) suspend la
purge concernée.
| Variable | Rôle | Défaut |
|---|---|---|
RETENTION_SWEEP_ENABLED | Purge des journaux vocaux expirés | active |
RETENTION_SWEEP_HOURS | Cadence de cette purge | 24 |
RETENTION_VOICE_DAYS | Durée de conservation des journaux vocaux | 90 |
BACKUP_RETENTION_SWEEP_ENABLED | Purge des travaux de sauvegarde terminés | active |
BACKUP_RETENTION_DAYS | Durée de conservation des sauvegardes, en repli du réglage par cible de sauvegarde | 30 |
ACCOUNT_PURGE_ENABLED | Effacement définitif des comptes en attente de suppression | active |
Sources : crates/forge-api/src/routes/retention_worker.rs,
routes/backup_retention/mod.rs, routes/account_purge_worker.rs et
crates/forge-api/src/main.rs (lancement des trois planificateurs).
Messagerie (SMTP)
| Variable | Rôle | Défaut |
|---|---|---|
SMTP_HOST | Serveur SMTP | localhost |
SMTP_PORT | Port | 587 |
SMTP_USER | Compte authentifié. C'est aussi l'adresse expéditrice | aucun |
SMTP_PASSWORD | Mot de passe du compte | aucun |
SMTP_SECURE | true pour une connexion TLS directe | false |
EMAIL_FROM, EMAIL_FROM_NAME | Expéditeur de repli et nom affiché | nom : Chatbotaurus |
L'expéditeur est toujours le compte authentifié SMTP_USER : un From différent
casse l'alignement SPF et DKIM (crates/forge-core/src/email/mod.rs). Il n'existe
pas de variable SMTP_SKIP.
Authentification unique (Authentik, OIDC avec PKCE)
La route GET /api/v1/auth/oidc/login lit ces variables :
| Variable | Rôle | Défaut |
|---|---|---|
AUTHENTIK_SERVER_URL | Adresse du serveur Authentik | aucun : absente, la route répond 503 SSO_UNAVAILABLE |
AUTHENTIK_CLIENT_ID | Identifiant du client OIDC | aucun : même réponse 503 |
AUTHENTIK_CLIENT_SECRET | Secret du client OIDC | aucun : même réponse 503 |
AUTHENTIK_REDIRECT_URI | URL de retour enregistrée chez Authentik | http://localhost:8008/api/v1/auth/oidc/callback, défaut de développement : posez-la toujours |
OIDC_ALLOW_UNVERIFIED_EMAIL | 1 ou true accepte un fournisseur qui n'émet pas email_verified | refus |
La route de retour du backend est GET /api/v1/auth/oidc/callback
(crates/forge-api/src/router.rs).
ForgeConfig lit aussi SSO_AUTHENTIK_ENABLED, AUTHENTIK_SLUG,
AUTHENTIK_CALLBACK_URL, AUTHENTIK_LOGOUT_URL et AUTHENTIK_ROLE_MAPPING
(crates/forge-core/src/config.rs, bloc authentik). Mesure du 2026-10-03 :
aucun code hors de config.rs ne consomme ces champs (grep -rn "\.sso\." crates/*/src ne rend rien en dehors de ce fichier). Ils n'ont donc aucun effet
sur la connexion SSO aujourd'hui.
Modèles de langage (Ollama)
| Variable | Rôle | Défaut |
|---|---|---|
OLLAMA_BASE_URL | Adresse d'Ollama | http://localhost:11434 |
OLLAMA_MODEL | Modèle de génération | ministral-3:3b dans la configuration ; ministral-3:3b-instruct dans l'orchestrateur (OLLAMA_DEFAULT_MODEL en repli) |
OLLAMA_EMBEDDING_MODEL | Modèle d'embeddings du client Ollama. Le pipeline RAG n'en dépend pas : il vectorise en local avec fastembed (voir EMBEDDING_MODEL) | paraphrase-multilingual-MiniLM-L12-v2 |
OLLAMA_TIMEOUT_SECS | Délai d'une requête (configuration) | 120 |
OLLAMA_MAX_RETRIES | Nouvelles tentatives | 2 |
OLLAMA_TEMPERATURE | Température (orchestrateur) | 0,5 |
OLLAMA_MAX_TOKENS | Longueur maximale de réponse (orchestrateur) | 800 |
La liste des modèles souverains (crates/forge-core/src/model_governance.rs)
nomme cas/eurollm-1.7b-instruct-q8 (rôle Main, réservé à la traduction : le
code précise qu'il ne sert jamais à l'appel d'outil), ministral-3:3b (repli
de génération, et défaut de OLLAMA_MODEL) et l'embedder ci-dessus. Aucun
défaut du code ne désigne un fournisseur hors UE.
Recherche vectorielle et RAG
| Variable | Rôle | Défaut |
|---|---|---|
QDRANT_URL | Adresse gRPC de Qdrant | http://localhost:6334 |
QDRANT_HOST | Adresse REST utilisée par la sonde de santé | dérivée de QDRANT_URL |
QDRANT_API_KEY | Clé d'API | aucune |
QDRANT_COLLECTION_PREFIX | Préfixe des collections | forge |
EMBEDDING_MODEL | Modèle fastembed du pipeline RAG : multilingual (ou variable absente) donne paraphrase-multilingual-MiniLM-L12-v2, 384 dimensions (crates/forge-core/src/rag/embedder.rs) | multilingual |
QDRANT_VECTOR_SIZE | Dimension des vecteurs | 768 dans la configuration, 384 à la création des collections au démarrage |
RAG_CHUNK_SIZE, RAG_CHUNK_OVERLAP | Découpage des documents | 512 et 64 |
RAG_TOP_K, RAG_SCORE_THRESHOLD | Passages retenus et seuil | 5 et 0,7 |
ANTI_HALLUCINATION_THRESHOLD | Seuil de la garde anti-hallucination | 0,75 |
L'embedder du pipeline produit des vecteurs de 384 dimensions. Si vous
posez QDRANT_VECTOR_SIZE, posez 384 : une collection créée avec une autre
dimension refuse chaque insertion (crates/forge-api/src/main.rs).
Secrets externes (OpenBao)
OpenBao est facultatif. Si BAO_ADDR est posée, il surcharge les secrets
d'exécution au démarrage ; sinon les secrets viennent de l'environnement.
| Variable | Rôle | Défaut |
|---|---|---|
BAO_ADDR | Adresse du serveur | absente : OpenBao désactivé |
BAO_TOKEN | Jeton d'accès | aucun |
BAO_KV_MOUNT | Point de montage KV v2 | secret |
BAO_KV_PREFIX | Préfixe sous le montage | chatbotaurus |
BAO_NAMESPACE | Espace de noms | aucun |
BAO_TIMEOUT_SECS | Délai HTTP | 10 |
BAO_AUDIT_REQUIRED | Vrai : le démarrage est refusé si aucun périphérique d'audit n'est actif côté coffre | faux |
BAO_CACERT, BAO_CLIENT_CERT, BAO_CLIENT_KEY | TLS mutuel | aucun |
Voix
| Variable | Rôle | Défaut |
|---|---|---|
STT_PROVIDER | Moteur de transcription : speaches, kyutai ou mistral | speaches |
STT_ENDPOINT | Adresse du moteur de transcription | à définir (voir le paragraphe sous le tableau) |
STT_MODEL | Modèle de transcription | Systran/faster-whisper-large-v3 |
STT_LANGUAGE | Langue | fr |
STT_API_KEY | Clé d'API du moteur de transcription | aucune |
TTS_PROVIDER | Moteur de synthèse | kokoro |
TTS_ENDPOINT | Adresse du moteur de synthèse | à définir |
TTS_ENDPOINT_SPEACHES | Adresse du service qui sert l'allemand | absente : service non déployé |
Les défauts de STT_ENDPOINT et TTS_ENDPOINT dans le code sont des adresses
publiques qui ne servent rien. Définissez toujours ces deux variables. Le code
refuse un point d'accès hors UE.
Supervision
| Variable | Rôle | Défaut |
|---|---|---|
PROMETHEUS_BEARER_TOKEN | Jeton d'accès au point /metrics | absent : session plateforme élevée exigée |
FORGE_SIEM_ENABLED | 1 exporte la chaîne d'audit vers VictoriaLogs | désactivé |
FORGE_SIEM_URL | Adresse de VictoriaLogs | http://localhost:9428 |
Voir Supervision.
Connecteurs
CONNECTOR_CATALOGUE_DIR désigne le dossier des manifestes ; le défaut est
./connectors (crates/forge-api/src/main.rs).
Les fichiers connectors/*.yaml interpolent l'environnement avec
${VARIABLE:-défaut} (valeur de repli) ou ${VARIABLE:?message} (la valeur
vaut une chaîne vide si la variable est absente ; le message n'est qu'une
indication et n'arrête pas le chargement). Chaque
connecteur déclare ses propres variables ; pour Odoo : ODOO_URL,
ODOO_DATABASE, ODOO_USERNAME, ODOO_API_KEY. Voir
Fichiers de configuration.
Frontend (forge-ui)
Le frontend est une application wasm : elle ne lit aucune variable
d'environnement dans le navigateur. En web, elle appelle le chemin relatif
/api/v1 du même domaine. Sur les cibles natives, l'adresse de l'API se fixe à
la compilation avec API_URL ; le défaut est http://localhost:3000/api/v1
(crates/forge-ui/src/config/api.rs).
Voir aussi
- Fichiers de configuration — quels fichiers le code lit et dans quel ordre ils s'appliquent
- Sécurité — ce que chaque clé de durcissement protège, fichier par fichier
- Déploiement avec Podman — où les secrets de production naissent et comment les plans démarrent
- OpenBao et secrets — surcharge des secrets au démarrage et audit de lecture du coffre
- Problèmes connus — JWT invalide, CSRF refusé, configuration du frontend ignorée
Fichiers de configuration
Ce chapitre dit quels fichiers le code lit, où ils vivent et dans quel ordre ils s'appliquent. La liste des variables est dans Variables d'environnement.
Les fichiers que le code lit
| Fichier | Emplacement | Lu par | Rôle |
|---|---|---|---|
.env | Répertoire de lancement (racine du dépôt en développement) | dotenvy, au démarrage de forge-api | Variables de développement. Ignoré par git |
.env.example | Racine du dépôt | Personne : c'est un modèle à copier | Liste commentée des variables, avec des valeurs à remplacer |
connectors/*.yaml | Racine du dépôt, ou le dossier CONNECTOR_CATALOGUE_DIR | CatalogueLoader (crates/forge-mcp/src/connector/catalogue.rs) | Un manifeste par connecteur |
policies/chatbotaurus.cedarschema et policies/policies.cedar | Dossier policies/, chemin relatif au répertoire de lancement | load_cedar_policy_engine (crates/forge-api/src/main.rs) | Règles d'autorisation Cedar |
crates/forge-ui/Dioxus.toml | Crate forge-ui | dx | Réglages du serveur de développement du frontend |
crates/forge-docs/book.toml | Crate forge-docs | mdbook | Réglages de ce livre |
Le code ne lit pas de fichier .env.staging ni .env.production. Pour un
autre environnement, posez les variables dans le processus.
Si policies/ est absent ou illisible depuis le répertoire de lancement, le
comportement dépend de la posture. En développement déclaré, le moteur Cedar
n'est pas chargé, forge-api démarre sans lui et les gardes Cedar laissent
passer. En posture de production, forge-api refuse de démarrer
(décision de démarrage du moteur Cedar, dans le code). Lancez le binaire
depuis la racine du dépôt.
Fichiers de déploiement
Deux plans Podman existent, chacun avec son fichier Compose :
| Fichier | Plan | Contenu |
|---|---|---|
podman-compose.yml | Backend (services forge-*) | PostgreSQL, Valkey, Qdrant, Ollama, Authentik, OpenBao, VictoriaMetrics, VictoriaLogs, CrowdSec, voix, sauvegarde |
podman-compose.vps2.yml | Client (services mcp-*) | Passerelle MCP et serveurs d'outils métier |
Ces fichiers servent au développement local. En production, le déploiement
installe des unités Quadlet : un fichier containers/<service>/<service>.container
par service, appliqué par containers/scripts/deploy-all.sh. Voir
Déploiement avec Podman.
Tapez podman-compose avec un tiret. podman compose (avec une espace) ne
fournit pas de moteur Compose propre : il délègue à un outil externe qui peut
manquer.
Les deux réseaux et les volumes de données sont déclarés external dans les
fichiers Compose : compose ne les crée pas. Créez-les avant le premier
lancement (procédure dans Déploiement avec Podman).
Configuration du backend
forge-api construit sa configuration avec ForgeConfig::from_env
(crates/forge-core/src/config.rs). Créez .env à la racine du dépôt (cp .env.example .env, ou le fichier minimal ci-dessous) ; seules DATABASE_URL, REDIS_URL et
JWT_SECRET sont exigées, et openssl rand -hex 32 produit un JWT_SECRET valable (voir
Variables d'environnement). Exemple minimal de .env de développement,
avec des gabarits à remplacer :
DATABASE_URL=postgres://<utilisateur>:<mot-de-passe>@localhost:5432/<base>
REDIS_URL=redis://localhost:6380
JWT_SECRET=<32-caracteres-aleatoires-au-minimum>
OLLAMA_BASE_URL=http://localhost:11434
QDRANT_URL=http://localhost:6334
SMTP_HOST=<serveur-smtp>
SMTP_PORT=587
SMTP_USER=<compte-smtp>
SMTP_PASSWORD=<mot-de-passe-smtp>
RUST_LOG=info,forge_api=debug
Le Valkey de podman-compose.yml est publié sur le port 6380 de l'hôte par
défaut (variable REDIS_PORT) ; 6379 est le port interne du conteneur. Si vous
utilisez un Redis local sur 6379, adaptez l'URL. Avec le compose de développement,
l'utilisateur, le mot de passe et la base de DATABASE_URL sont ceux des variables
DATABASE_USER, DATABASE_PASSWORD et DATABASE_NAME (valeurs par défaut de
développement dans podman-compose.yml).
Au démarrage, forge-api imprime sur l'erreur standard dotenvy: loaded <chemin> si
.env a été chargé, ou dotenvy: .env NOT loaded sinon. Si le message dit
que le fichier n'a pas été chargé, le répertoire de lancement n'est pas la
racine du dépôt.
Les valeurs de production ne sont pas dans le dépôt. Un script génère sur
chaque hôte les fichiers d'environnement avec des permissions restreintes
(script d'initialisation des secrets de l'hôte). Si BAO_ADDR est posée, OpenBao
surcharge ensuite les secrets d'exécution.
Configuration du frontend
forge-ui ne lit aucun fichier à l'exécution.
- Le serveur de développement est
dx serve, lancé depuiscrates/forge-ui.Dioxus.tomlle règle pour surveiller le dossiersrc: une modification de code recharge la page sans redémarrer. - En web, le frontend appelle le chemin relatif
/api/v1du même domaine. Sur les cibles natives,API_URLfixe l'adresse à la compilation ; le défaut esthttp://localhost:3000/api/v1(crates/forge-ui/src/config/api.rs). - Les textes de marque, les liens et les offres affichés sur le site vivent
dans
crates/forge-ui/src/config/site.rs. Ce fichier ne contient pas l'adresse de l'API.
Manifestes de connecteurs (connectors/*.yaml)
Au démarrage, forge-api charge chaque .yaml du dossier. Il remplace les
${VARIABLE:-défaut} par l'environnement, puis enregistre le connecteur. Un
manifeste invalide est journalisé et ignoré, il n'arrête pas le démarrage.
Le dossier contient 195 manifestes (mesure du 2026-10-03 :
ls connectors/*.yaml | wc -l). Forme d'un connecteur HTTP (modèle commenté :
connectors/README.md) :
id: <identifiant>
display_name: "<nom affiché>"
base_url: "${<VARIABLE>:-<url-par-defaut>}"
auth:
type: bearer # none | bearer | api_key | basic | query_token | jwt_exchange | oauth2 | login_token | checksum | json_rpc_session
token_env: <VARIABLE>
compliance:
data_residency: eu
self_hosted: true
gdpr_compliant: true
license: "<licence>"
timeout_ms: 30000
tools:
- name: <outil>
description: "<description>"
method: GET
path: "/chemin/{parametre}"
param_location: path
input_schema:
type: object
properties: {}
Le manifeste d'Odoo suit une autre forme : type: odoo et les champs url,
database, username, api_key, lus dans ODOO_URL, ODOO_DATABASE,
ODOO_USERNAME et ODOO_API_KEY (connectors/odoo.yaml). La clé d'API y est
marquée obligatoire (${ODOO_API_KEY:?...}), mais le chargeur la remplace par une
chaîne vide si elle est absente : le manifeste se charge, et les appels
d'Odoo échouent faute d'identifiants.
Le registre refuse un connecteur dont gdpr_compliant vaut false ou dont la
résidence des données n'est pas dans l'UE ou auto-hébergée. Le journal le dit :
connector rejected by registry.
Les secrets ne sont jamais écrits dans les manifestes : ils viennent de l'environnement.
Appliquer un changement
- Backend : redémarrez
forge-api. Il ne relit pas la configuration à chaud. En développement sous Windows,scripts/dev/watch-forge-api.ps1reconstruit et relance le binaire après une modification de code. - Frontend : rien à faire en développement,
dx serverecharge. - Services Podman : en développement,
podman-compose -f podman-compose.yml up -dapplique la nouvelle définition ;--force-recreaterecrée les conteneurs. En production, l'hôte tire lui-même la branche principale (minuteur systemd) : voir « Déploiement tiré par l'hôte » dans Déploiement avec Podman.
Voir aussi
- Variables d'environnement — la liste des variables que ces fichiers alimentent
- Installation de Chatbotaurus — première configuration de l'environnement de développement, pas à pas
- Déploiement avec Podman — fichiers Compose, unités Quadlet et déploiement tiré par l'hôte
- Conception des connecteurs MCP — tous les champs d'un manifeste et le contrôle de conformité
- Problèmes connus — configuration du frontend ignorée, connecteur rejeté au démarrage
Déploiement avec Podman
Chatbotaurus utilise Podman, pas Docker, pour ses conteneurs. Ce guide
décrit les deux plans de déploiement, l'environnement de développement
(podman-compose) et la production (unités Quadlet).
À la fin de ce chapitre, vous aurez créé les réseaux et les volumes, démarré les deux plans en développement, et vous saurez comment la production est déployée, suivie et ramenée à l'image précédente.
Prérequis
- Podman et
podman-compose. Tapez bienpodman-composeavec un tiret :podman compose(avec un espace) n'est qu'un adaptateur qui cherche un fournisseur externe. - Pour la production : un hôte Linux avec systemd, un compte
non privilégié dédié (noté
<compte-deploiement>ci-dessous) et les unités Quadlet decontainers/. - Les fichiers
podman-compose.ymletpodman-compose.vps2.yml, le dossiercontainers/et les scripts cités dans ce chapitre font partie des sources sous licence (voie d'accès : Contribuer). Lancez les commandespodman-composedepuis la racine de ces sources. - Aucun fichier
.envn'est nécessaire pour un premier essai en développement : les fichiers compose portent des valeurs par défaut de développement. Le stockage objet fait exception : il reste fermé tant que ses variablesSEAWEEDFS_S3_*ne sont pas renseignées (voir Problèmes connus, section « Le stockage objet S3 refuse toutes les requêtes »).
Deux plans, deux réseaux
| Plan | Projet et réseau | Fichier | Nom des services |
|---|---|---|---|
| Backend (notre plan) | chatbotaurus-vps1 | podman-compose.yml | forge-* |
| Client | mgaas-vps2 | podman-compose.vps2.yml | mcp-* |
Règle : un service nommé mcp-* est dans le plan client, tout autre nom
dans le plan backend. Tout nouveau serveur MCP est un service du fichier
podman-compose.vps2.yml, jamais un podman run isolé.
Les deux réseaux sont créés avant le premier lancement (les fichiers
compose les déclarent external) :
podman network create chatbotaurus-vps1
podman network create mgaas-vps2
Les volumes de données sont external eux aussi (bloc volumes: en fin de
chaque fichier compose) : compose ne les crée pas. Créez-les avant le premier
lancement. Leurs noms portent un préfixe hérité (par exemple
<prefixe-du-projet>_forge-pgdata), choisi pour ne jamais recréer un volume
vide. Pour le plan backend :
for v in $(awk '/^volumes:/{f=1} f && /^ name:/{print $2}' podman-compose.yml); do
podman volume exists "$v" || podman volume create "$v"
done
Faites de même avec podman-compose.vps2.yml. La liste des noms se lit avec
grep -n "name:" podman-compose.yml.
La boucle ne crée que les volumes absents : vous pouvez la relancer sans risque.
Résultat attendu : podman volume ls affiche ces noms et podman network ls les
deux réseaux. Si l'un d'eux manque, le premier lancement échoue : voir
Problèmes connus, section « Un conteneur ne démarre pas ».
PostgreSQL et Valkey du plan backend sont rattachés aux deux réseaux, avec
les alias DNS postgres et valkey sur mgaas-vps2 : les outils du plan
client (Odoo, Listmonk, n8n, Grafana, Mattermost, entre autres) les joignent par
ces noms.
Développement : démarrer les plans
# Plan backend
podman-compose -p chatbotaurus-vps1 up -d
# Plan client (passerelle MCP et serveurs des offres)
podman-compose -p mgaas-vps2 -f podman-compose.vps2.yml up -d
# Vérifier
podman ps --format "table {{.Names}}\t{{.Status}}"
Résultat attendu : chaque conteneur du plan affiche l'état Up, et ceux qui
déclarent une sonde de santé passent à healthy après leur délai de démarrage.
Les services des profils container-api et backup ne démarrent pas sans leur
profil : c'est normal. Un conteneur à l'état Exited, ou absent hors profil :
lisez podman logs <conteneur> et suivez Problèmes connus,
section « Un conteneur ne démarre pas ».
En développement, le binaire forge-api tourne sur l'hôte
(scripts/dev/run-forge-api.ps1) ; le service forge-api du compose est
derrière le profil container-api et ne démarre que sur demande :
podman-compose -p chatbotaurus-vps1 --profile container-api up -d forge-api
Services du plan backend (podman-compose.yml)
| Service | Conteneur | Rôle | Port publié (hôte → conteneur) |
|---|---|---|---|
postgres | forge-postgres | Base principale (image postgres:16-alpine) | 5432 |
valkey | forge-valkey | Cache et sessions | 6380 → 6379 (par défaut) |
qdrant | forge-qdrant | Base vectorielle | 6333 et 6334 |
ollama | forge-ollama | LLM locaux (limite mémoire fixée dans le plan compose) | 11434 |
authentik | forge-authentik | SSO / IAM | 9000 et 9443 |
forge-api | forge-api | Backend Rust (profil container-api) | 3000 |
openbao | forge-openbao | Secrets | 8200 |
pgadmin | forge-pgadmin | Administration PostgreSQL | 5050 |
victoriametrics | forge-victoriametrics | Métriques | 8428 |
victorialogs | forge-victorialogs | Journaux | 9428 |
faster-whisper | forge-faster-whisper | Transcription (STT) | 10300 → 8000 |
tts-models | forge-tts-models | Téléchargement des modèles vocaux | — |
kokoro-tts | forge-kokoro-tts | Synthèse vocale | 8880 |
livekit | forge-livekit | Temps réel (WebRTC) | 7880, 7881, 7882/udp |
crowdsec | forge-crowdsec | Détection d'intrusion | — |
seaweedfs | forge-seaweedfs | Stockage objet S3 (Apache-2.0) | 8333, lié à la boucle locale |
backup-agent | forge-backup-agent | Agent de sauvegarde (profil backup) | — |
tusd | forge-tusd | Réception TUS des archives (profil backup) | — |
Les sauvegardes sont décrites dans Sauvegarde et restauration.
Plan client (podman-compose.vps2.yml)
Le service mcp-gateway (binaire forge-gateway, port 8811) est le point
d'entrée du protocole MCP du plan. Autour de lui : les instances Odoo par
offre (mcp-odoo-therapie, mcp-odoo-medical, mcp-odoo-finance et les autres),
mcp-element, mcp-cryptpad, mcp-listmonk, mcp-n8n, mcp-grafana,
mcp-plausible, mcp-moodle, mcp-calrs, mcp-forgejo, mcp-mattermost,
mcp-paperless, mcp-frappe, mcp-searxng, mcp-typesense, mcp-umami,
mcp-matomo et leurs bases. La liste exacte se lit avec :
grep container_name podman-compose.vps2.yml
Production : unités Quadlet
En production, chaque conteneur est une unité Quadlet
containers/<service>/<service>.container, gérée par systemd sous le
compte <compte-deploiement>. Côté plan backend, on y trouve par exemple forge-traefik
(ingress), forge-api, forge-ui (fichiers statiques du front servis par
nginx), forge-openbao, forge-qdrant, forge-ollama, forge-livekit,
forge-authentik-server, forge-authentik-worker, forge-crowdsec et
forge-tusd. Sur ce plan, seuls l'ingress et le service temps réel publient des ports sur
toutes les interfaces ; les autres unités n'écoutent que sur la boucle locale
de l'hôte. Dans l'unité forge-api, le port 3000 n'est publié que sur la boucle
locale de l'hôte. Le détail des ports et des règles n'est pas publié. L'ingress du plan client est
mcp-caddy. Les unités forge-falco et forge-zeek existent dans
containers/, mais deploy-all.sh les a retirées de ses niveaux le
2026-09-19 : elles ne sont pas déployées.
Orchestration depuis un poste d'opérateur
containers/scripts/deploy-all.sh pilote les deux plans par niveaux
cumulatifs de 1 (démarrage) à 5 (plateforme).
Prérequis : sur le poste, bash, ssh, tar et curl ; sur chaque hôte cible, le
compte de déploiement non privilégié avec sudo, podman, Quadlet, python3, le mode
« linger » (voir Problèmes connus, section « Les
services Quadlet ne redémarrent pas après un redémarrage de l'hôte ») et le dossier
cible. L'étape preflight vérifie ces points. Les hôtes se désignent par
--hote-backend et --hote-client (alias SSH ou utilisateur@hôte), le dossier
déployé par --app. Les niveaux 4 et 5 sont refusés tant qu'une unité qu'ils exigent
n'existe pas dans containers/. Code de sortie : 0 si chaque étape demandée est
prouvée, 1 sinon, 2 pour une erreur d'usage.
# Lister ce que le niveau 1 déploie, avec ce que le code prouve
bash containers/scripts/deploy-all.sh --liste 1
# Voir les commandes sans se connecter
bash containers/scripts/deploy-all.sh 1 --plan backend --dry-run
# Étapes, dans cet ordre : preflight, expedier, images, cible, prouver (ou tout)
bash containers/scripts/deploy-all.sh 1 --plan backend --etape prouver
Le script ne contient aucun secret : ils naissent sur la cible
(scripts d'initialisation des secrets, exécutés sur l'hôte pendant l'étape cible,
de façon idempotente : relancer l'étape est sans danger). Résultat attendu de
l'étape prouver : un accès HTTPS, certificat vérifié, à chaque nom public du niveau ;
un nom qui ne résout pas imprime l'enregistrement DNS à créer chez votre hébergeur.
Déploiement tiré par l'hôte
Le chemin courant n'est pas une poussée depuis un poste : l'hôte tire.
Un minuteur systemd utilisateur lance un script 2 minutes après la fin du
passage précédent (OnUnitInactiveSec=120). Le script regarde si la branche
principale a avancé :
| Script | Rôle |
|---|---|
scripts/deploy/vps-autodeploy-front.sh | Construit le front (dx build --release) et bascule le dossier servi par forge-ui, puis prouve par HTTPS |
scripts/deploy/vps-autodeploy-backend.sh | Construit l'image backend sur l'hôte, met à jour l'unité forge-api, redémarre et prouve par HTTPS |
scripts/deploy/vps-autodeploy-vps2.sh | Déploie le plan client : seules les unités dont un fichier source a changé sont redémarrées |
Installation et suivi, depuis le poste de l'opérateur :
bash scripts/deploy/installer-autodeploy-hote.sh --vps1 # ou --vps2, --tout
bash scripts/deploy/suivre-autodeploy.sh
Les deux commandes ci-dessus se connectent en SSH : elles lisent l'hôte cible dans la
variable HOTE (l'installateur lit aussi HOTE_VPS2 pour le plan client) et la clé
SSH dans CLE. Posez ces variables explicitement avant de les lancer. Résultat attendu
de suivre-autodeploy.sh : l'état du minuteur (active), le SHA déployé, puis la fin
du journal et de la construction du front. Il ne lit pas l'état du backend :
comparez le champ sha de /api/v1/healthz au commit attendu (voir
Supervision).
Points à connaître :
- l'image backend est étiquetée par le SHA du commit
(
localhost/forge-stack:<sha-court>) et construite parpodman build -f Containerfile .sur l'hôte ; aucune image n'est supprimée, l'étiquette précédente reste disponible ; - si la santé locale n'est pas prouvée après le redémarrage, le script revient à l'image précédente ;
- un commit qui ne touche que la documentation ne reconstruit pas l'image ;
- aucune clé ni port n'est exposé par ce mécanisme : l'hôte tire, il ne reçoit rien.
La description complète du processus est dans
docs/deploiement/PROCESSUS-PAR-PUSH.md.
Construction des images
Le Containerfile à la racine construit en plusieurs étapes les binaires
Rust (forge-api, forge-cli, forge-ops) vers une image finale
minimale ; Containerfile.production en est la variante de production.
podman build -t localhost/forge-stack:dev -f Containerfile .
Le front se construit à part :
dx build --release --platform web --package forge-ui
Modèles Ollama
Une fois forge-ollama démarré, téléchargez les modèles dont vous avez
besoin :
podman exec forge-ollama ollama pull <nom-du-modèle>
podman exec forge-ollama ollama list
Le modèle utilisé par défaut se règle par la variable OLLAMA_MODEL du
backend. Le CLI forge-cli propose aussi une sous-commande model pull.
Le service forge-api du compose (profil container-api) fixe lui-même une valeur par
défaut de OLLAMA_MODEL (lisible dans podman-compose.yml) ; le binaire lancé sur
l'hôte suit, lui, les défauts de Variables d'environnement.
Téléchargez le modèle que votre backend demande. Résultat attendu : ollama list
affiche le modèle téléchargé.
Contrôle de la chaîne d'approvisionnement
- Le dépôt tient un SBOM CycloneDX par composant dans
docs/sbom/(python scripts/audit/sbom_cyclonedx.py --checkvérifie qu'il correspond auCargo.lock). - Le workflow de CI du dépôt analyse l'image backend avec Trivy (gravité HIGH et CRITICAL). Il est dormant : aucun exécuteur n'y est rattaché, il ne tourne pas aujourd'hui. Les exceptions acceptées sont listées dans un fichier d'exceptions motivées du dépôt. Un script d'analyse des images se lance à la main.
Notes importantes
- Les unités Quadlet de production sont préférées en mode rootless ;
binder les ports 80 et 443 en rootless exige de baisser
net.ipv4.ip_unprivileged_port_start(valeur à fixer au plus à 80, avec les droits administrateur ; l'en-tête de l'unité de l'ingress, dans les sources, donne le détail). - OpenBao se re-scelle au redémarrage : voir le guide d'exploitation du coffre (hors de ce livre) pour la topologie de descellement.
- Les fichiers compose portent des valeurs par défaut de développement
pour certains mots de passe : surchargez-les par l'environnement
(fichier
.env), ne les réutilisez jamais en production. En production, les secrets sont créés sur l'hôte par les scripts d'initialisation des secrets et ne figurent pas dans le dépôt.
Voir aussi
- Gestion des conteneurs — gestes du quotidien : journaux, redémarrage, mise à jour, dépannage
- Sauvegarde et restauration — les deux chaînes de sauvegarde et la répétition de restauration
- Problèmes connus — réseaux absents, conflits de port, OpenBao scellé, déploiement en retard
- Fichiers de configuration — fichiers Compose, unités Quadlet et ce que le code lit réellement
- Architecture Chatbotaurus — pourquoi deux plans et la règle de nommage des services
Gestion des conteneurs
Ce chapitre rassemble les gestes du quotidien pour exploiter les conteneurs de Chatbotaurus. Deux contextes cohabitent :
- le développement et les essais, avec
podman-compose(podman-compose.ymletpodman-compose.vps2.yml) ; - la production, avec des unités Quadlet pilotées par systemd sous le
compte non privilégié dédié,
<compte-deploiement>(mode rootless : aucune commandesudo podmann'est nécessaire).
Le choix de déploiement est décrit dans Déploiement avec Podman.
Réseaux
| Réseau | Plan | Contenu |
|---|---|---|
chatbotaurus-vps1 | Backend | Services forge-* |
mgaas-vps2 | Client | Passerelle MCP et services mcp-* |
Les adresses de ces réseaux ne sont pas fixées par la documentation : les
conteneurs se joignent par leur nom (DNS interne Podman), et
PostgreSQL et Valkey portent les alias postgres et valkey sur les
deux réseaux.
podman network ls
podman network inspect chatbotaurus-vps1 --format '{{.Name}}'
Commandes courantes
Les commandes ci-dessous valent pour le développement comme pour la production, sauf mention contraire.
Lister les conteneurs
podman ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
Journaux d'un conteneur
podman logs -f forge-api
podman logs --tail 100 forge-postgres
Pour une unité Quadlet, le journal systemd donne aussi l'historique des démarrages :
journalctl --user -u forge-api.service -n 100
Redémarrer un service
# Développement
podman-compose -p chatbotaurus-vps1 restart postgres
# Production (unité Quadlet)
systemctl --user restart forge-api.service
systemctl --user status forge-api.service
Résultat attendu : systemctl --user status affiche active (running). Sinon, lisez
journalctl --user -u forge-api.service -n 100 et suivez Problèmes connus.
Inspecter un conteneur
podman inspect forge-valkey --format '{{.State.Status}}'
Statistiques de ressources
podman stats --no-stream
Services principaux
Noms de conteneurs du plan backend, avec leur port d'écoute interne :
| Conteneur | Port | Rôle |
|---|---|---|
forge-postgres | 5432 | Base de données principale |
forge-valkey | 6379 | Cache et sessions |
forge-qdrant | 6333 (REST), 6334 (gRPC) | Base vectorielle |
forge-ollama | 11434 | Inférence IA locale (limite mémoire fixée dans le plan compose) |
forge-authentik | 9000 | SSO / IAM (en production : forge-authentik-server et forge-authentik-worker) |
forge-openbao | 8200 | Gestion des secrets |
forge-api | 3000 | Backend Rust |
forge-victoriametrics | 8428 | Métriques |
forge-victorialogs | 9428 | Journaux |
forge-crowdsec | — | Détection d'intrusion |
forge-seaweedfs | 8333 | Stockage objet S3 |
En production, forge-traefik est l'ingress du plan backend et
mcp-caddy celui du plan client.
Les limites mémoire déclarées se lisent dans les fichiers :
grep -n "memory:" podman-compose.yml
Mise à jour d'un service
La marche diffère selon le contexte.
En production
La mise à jour est tirée par l'hôte. Un minuteur, 2 minutes après la fin du
passage précédent, reconstruit l'image backend ou le front quand la branche
principale avance. Voir la section « Déploiement tiré par l'hôte » du chapitre
Déploiement avec Podman. Pour suivre l'état du front (ce script ne lit pas celui du backend : comparez le champ
sha de /api/v1/healthz au commit attendu) :
bash scripts/deploy/suivre-autodeploy.sh
Si une image doit être rétablie à la main : l'étiquette précédente reste
sur l'hôte (podman images | grep forge-stack). Remettez-la dans l'unité
forge-api.container, puis :
systemctl --user daemon-reload
systemctl --user restart forge-api.service
En développement
Si le service porte des données (PostgreSQL, Valkey, Qdrant), sauvegardez-les d'abord : Sauvegarde et restauration.
podman-compose -p chatbotaurus-vps1 pull postgres
podman-compose -p chatbotaurus-vps1 up -d postgres
Sauvegardes
Les sauvegardes sont décrites dans
Sauvegarde et restauration. Les commandes manuelles
sont les mêmes que celles utilisées par scripts/backup/nightly.sh.
Dépannage
Quelques pannes fréquentes et le premier geste à faire.
Conteneur qui ne démarre pas
# Logs du conteneur
podman logs forge-postgres
# Ports occupés (Linux)
ss -tlnp | grep 5432
# Espace disque
df -h
Vérifiez aussi que les deux réseaux existent : podman network ls. Les
fichiers compose les déclarent externes et ne les créent pas. Les volumes de
données sont dans le même cas : podman volume ls, et la boucle de création de
Déploiement avec Podman.
Conflit de port
# Linux
ss -tlnp | grep <port>
# Windows (développement local)
netstat -ano | Select-String "5432"
Le port de Valkey publié sur l'hôte est 6380 par défaut, pour éviter une collision avec un Redis local sur le port 6379.
Ollama ne charge pas le modèle
# Mémoire disponible
free -h
# Modèles installés
podman exec forge-ollama ollama list
# Télécharger un modèle manquant
podman exec forge-ollama ollama pull <nom-du-modèle>
Un service attend un autre
Les services du compose déclarent des sondes de santé
(healthcheck) : PostgreSQL, Valkey et Qdrant doivent être sains avant le
démarrage du service forge-api. Vérifiez l'état avec :
podman ps --format "table {{.Names}}\t{{.Status}}"
Voir aussi
- Déploiement avec Podman — créer les réseaux et volumes, démarrer les plans, unités Quadlet
- Sauvegarde et restauration — sauvegarder PostgreSQL, Valkey, Qdrant et OpenBao avant toute mise à jour
- Problèmes connus — solutions détaillées aux pannes de conteneurs, ports, DNS et volumes
- Diagnostics et signalement — routes de santé, vérification manuelle des services et ressources
- Journaux — format des journaux du backend et filtres de verbosité par module
Sauvegarde et restauration
Chatbotaurus dispose de deux chaînes de sauvegarde qui coexistent :
- la chaîne par scripts (
scripts/backup/), qui exporte PostgreSQL, Valkey, Qdrant et, selon l'hôte, MariaDB vers un stockage S3 européen ; - la chaîne par agents sur l'hôte (spec 114), où un agent installé sur
chaque hôte envoie ses archives à l'orchestrateur intégré à
forge-api.
Le script de retour arrière scripts/backup/rollback.sh permet de revenir de la
seconde à la première sans migration destructive. bash scripts/backup/rollback.sh --dry-run (mode par défaut) vérifie les préconditions et imprime les commandes ;
--appliquer arrête ensuite l'agent et tusd, et --appliquer --conteneurs le fait
par podman stop sur un hôte sans unités Quadlet. Le script s'arrête avant tout arrêt
d'unité si la chaîne par scripts n'est pas présente et valide.
À la fin de ce chapitre, vous saurez sauvegarder chaque composant, restaurer depuis chacune des deux chaînes et prouver qu'une restauration fonctionne.
Figure 5 : les deux chaînes de sauvegarde et le retour arrière de la seconde vers la première.
Ce qui est sauvegardé
| Composant | Méthode | Fichier produit |
|---|---|---|
| PostgreSQL | pg_dump au format custom, compression 9 | archive horodatée |
| Valkey | BGSAVE puis copie du dump.rdb | archive horodatée |
| Qdrant | un instantané par collection (API REST, port 6333) | archive horodatée |
| MariaDB | mariadb-dump --all-databases, uniquement si MARIADB_CONTAINER est défini | archive horodatée |
| Manifeste | liste des fichiers et de l'hôte | manifeste horodaté |
Le script échoue franchement (code de sortie 1) si l'export PostgreSQL échoue ou si Qdrant ne renvoie aucune collection : une sauvegarde vide ne sort jamais « verte ».
L'étape Valkey est plus tolérante. Si BGSAVE échoue, ou si
le fichier dump.rdb de Valkey est introuvable sur l'hôte, le script écrit un
avertissement, saute l'étape et sort quand même avec le code 0
(scripts/backup/nightly.sh, étape Valkey). Lisez le journal, ne vous fiez
pas au seul code de sortie.
Sauvegarde automatisée
scripts/backup/nightly.sh est conçu pour tourner chaque nuit, à une heure creuse
sous cron, côté opérateur :
0 <heure> * * * <chemin-d-installation>/scripts/backup/nightly.sh >> <journal-de-sauvegarde> 2>&1
Il lit sa configuration dans l'environnement (variables du stockage S3
européen, PG_*, VALKEY_*, QDRANT_*). Le fichier qui les
porte (fichier d'environnement de la sauvegarde, hors du dépôt, mode 0600) ne se commite jamais.
Le détail des variables et l'installation sont dans
scripts/backup/README.md, livré avec les sources.
Prérequis de nightly.sh et de restore.sh : les outils aws (client S3), curl,
jq, pg_dump, pg_restore et redis-cli, et l'accès réseau à PostgreSQL, Valkey et
Qdrant (le port REST de Qdrant, 6333, pas le gRPC 6334). Variables à exporter : le point
d'accès, la clé d'accès, la clé secrète et le compartiment du stockage S3 ; l'hôte, le
port, l'utilisateur et la base de PostgreSQL, avec le mot de passe fourni par un fichier
désigné par PGPASSFILE ; l'hôte, le port et le mot de passe de Valkey ; l'hôte, le port
et la clé d'API de Qdrant.
- Chiffrement : TLS pendant le transfert, chiffrement SSE-S3 au repos.
- Rétention : 30 jours par défaut (
BACKUP_RETENTION_DAYS) ; le script supprime lui-même les sauvegardes plus anciennes. - Point de reprise : une sauvegarde nocturne réussie donne un point de reprise de 24 heures au plus. C'est l'objectif de point de reprise (RPO) publié sur la page SLA : moins de 24 h. Il reste une cible, pas un constat : l'exercice de restauration de production n'est pas fait (voir Conformité NIS2).
Sauvegarde par agents sur l'hôte (spec 114)
Un agent de sauvegarde tourne sur l'hôte qui porte les données. Il est décrit par :
forge-backup-agent(plan backend) etmcp-backup-agent(plan client), services des fichiers compose derrière le profilbackup, et unités Quadlet correspondantes ;forge-tusd, qui reçoit les archives par le protocole TUS et prévientforge-apipar un appel de retour ;- les routes d'orchestration de
forge-apimontées sous un préfixe interne, réservé au réseau privé, et l'API d'administration sous/api/v1/admin/backups/.
Démarrage en développement :
podman-compose -p chatbotaurus-vps1 --profile backup up -d backup-agent tusd
L'agent reçoit une clé d'enrôlement générée par l'API d'administration.
L'outil forge-ops automatise cette étape :
forge-ops backup status # état : agents, cibles, jobs, artefacts
forge-ops backup enroll --name <agent> --origin-host <hôte> --appliquer
forge-ops backup deploy-agent --vps vps1 # unité Quadlet, simulation par défaut
forge-ops backup decrypt <archive.enc> # déchiffrement hors ligne avec la clé maîtresse
Les archives sont chiffrées avant l'envoi. La rétention est appliquée côté
serveur (30 jours par défaut, réglable par cible) par une
tâche de fond de forge-api ; une passe manuelle est possible avec
POST /api/v1/admin/backups/retention/sweep.
Un stockage objet S3 local, SeaweedFS (forge-seaweedfs, licence
Apache-2.0), sert de banc de test avec un compartiment dédié.
Sauvegarde manuelle
Hors du script nocturne, chaque composant se sauvegarde à la main avec son propre outil.
Après chaque commande, vérifiez que le fichier produit n'est pas vide (ls -l) : une
redirection crée un fichier vide quand l'outil échoue ; les journaux du conteneur disent
pourquoi (voir Problèmes connus).
PostgreSQL
podman exec forge-postgres sh -c 'pg_dump -U "$POSTGRES_USER" -Fc "$POSTGRES_DB"' \
> chatbotaurus_$(date +%Y%m%d).dump
Qdrant
Une collection à la fois (si la clé API est activée, ajoutez
-H "api-key: $QDRANT_API_KEY") :
curl -fsS http://localhost:6333/collections
curl -fsS -X POST http://localhost:6333/collections/<collection>/snapshots
# Récupérer le fichier : <nom-du-snapshot> est le champ result.name de la réponse précédente
curl -fsS http://localhost:6333/collections/<collection>/snapshots/<nom-du-snapshot> \
-o qdrant-<collection>-<horodatage>.snapshot
OpenBao
En production (stockage Raft), la procédure est décrite dans le guide d'exploitation du coffre (hors de ce livre) :
bao operator raft snapshot save <dossier-de-sauvegarde>/snap-$(date +%F).snap
Restauration
La restauration suit la chaîne qui a produit l'archive.
Chaîne par scripts
# Un horodatage précis
bash scripts/backup/restore.sh 20260527-030000
# La plus récente
bash scripts/backup/restore.sh latest
Avant de lancer restore.sh : exportez les mêmes variables que pour nightly.sh (section
« Sauvegarde automatisée »), installez aws, pg_restore et redis-cli, et choisissez un
horodatage au format AAAAMMJJ-HHMMSS, nom du dossier de la sauvegarde dans le
compartiment (latest prend la plus récente). Le script lit aussi VALKEY_CONTAINER
(conteneur à redémarrer) et, pour MariaDB, MARIADB_CONTAINER et
MARIADB_ROOT_PASSWORD.
restore.sh télécharge l'archive depuis le S3, contrôle le manifeste, puis
restaure dans cet ordre : PostgreSQL (pg_restore --clean --if-exists),
Valkey (arrêt du conteneur, remplacement du dump.rdb, redémarrage),
MariaDB si un export est présent, puis chaque collection Qdrant par envoi de
l'instantané. Il écrase les données existantes : il attend 10 secondes
avant PostgreSQL et MariaDB pour laisser le temps d'annuler (Ctrl-C).
Résultat attendu : une ligne ... restore OK par composant restauré, des contrôles
finaux (nombre de tables PostgreSQL, nombre de clés Valkey), puis Restore completed successfully from backup <horodatage> et le code de sortie 0. Une ligne [WARN] No ... found ; skipping signifie que ce composant n'était pas dans l'archive ; une ligne
[FAIL] arrête le script avec le code 1. Ensuite : redémarrez forge-api (voir
Gestion des conteneurs), vérifiez GET /api/v1/healthz (voir
Diagnostics et signalement), puis qu'un
utilisateur connu peut se connecter et retrouver son espace.
Chaîne par agents
Une archive produite par un agent se restaure par une demande à l'API d'administration,
jamais par un simple appel : POST /api/v1/admin/backups/restores, avec un compte
administrateur et une organisation active. Le corps porte target_id, artifact_id
(obligatoire), confirmation: true et confirm_target, le nom exact de la cible
réécrit à la main ; reason est facultatif. La réponse est 202 : la demande crée un
travail de restauration et une approbation humaine dans la file des approbations. Tant
que l'approbation n'est pas donnée, l'agent ne restaure rien. Sans confirmation: true,
la réponse est 422 CONFIRMATION_REQUIRED ; sans artifact_id, 422 ARTIFACT_REQUIRED.
GET /api/v1/admin/backups/restores liste les demandes.
PostgreSQL à la main
podman exec -i forge-postgres sh -c \
'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists' \
< chatbotaurus_20260527.dump
Qdrant à la main
curl -fsS -X POST \
-F "snapshot=@qdrant-<collection>-<horodatage>.snapshot" \
http://localhost:6333/collections/<collection>/snapshots/upload
OpenBao
Voir le guide d'exploitation du coffre (restauration d'un instantané Raft puis descellement).
Répétition de restauration
Une sauvegarde qui n'a jamais été restaurée n'est pas une sauvegarde.
scripts/backup/drill.sh joue un cycle sauvegarde puis restauration sur
une base non critique, compare des compteurs et écrit un rapport daté :
bash scripts/backup/drill.sh --check --hote <alias-ssh>
L'option --check ne vérifie que les préconditions : rien n'est restauré. La répétition
réelle ajoute --restore-hote <alias-ssh> et exige un hôte éphémère de restauration et
l'option
--confirmation ; sans cet hôte, le script le dit au lieu d'inventer un
résultat.
Bonnes pratiques
- Conservez les sauvegardes hors de l'hôte qui porte les données.
- Ne mettez jamais les clés S3, la clé maîtresse des archives ni les clés de descellement OpenBao dans le dépôt.
- Répétez une restauration complète à intervalle régulier et consignez le résultat.
Voir aussi
- Gestion des conteneurs — redémarrer un service après une restauration et lire ses journaux
- Déploiement avec Podman — profils Compose et unités Quadlet qui portent l'agent de sauvegarde
- Problèmes connus — index Qdrant corrompu, OpenBao scellé, stockage S3 fermé par défaut
- Réponse aux incidents — restaurer depuis des sauvegardes saines pendant la phase de reprise
- Conformité NIS2 — exigence de continuité et limite assumée sur l'exercice de production
Journaux
Ce chapitre décrit où vont les journaux de Chatbotaurus, dans quel format, et comment les lire. Il distingue ce que le code fait de ce que votre hôte doit configurer.
Confidentialité. Le backend n'a, par défaut, aucune destination externe pour ses journaux : ils restent sur les hôtes que vous exploitez. Un export de la chaîne d'audit vers VictoriaLogs existe, il est désactivé par défaut et ne vise que l'adresse que vous configurez.
Où écrit le backend
forge-api écrit ses journaux sur la sortie standard, avec la bibliothèque
tracing. Le backend n'écrit pas ses journaux applicatifs dans un fichier.
| Réglage | Effet |
|---|---|
| Format par défaut | JSON, une ligne par événement |
Variable LOG_FORMAT à pretty ou compact | Sortie compacte lisible, pour le développement |
Variable RUST_LOG | Filtre par cible et niveau |
Variable TRACING_JSON | Sans effet sur forge-api : posée dans podman-compose.yml, elle n'est pas lue par ce binaire |
RUST_LOG absente ou invalide | info,forge_api=debug,forge_mcp=debug |
Chaque ligne JSON porte l'horodatage, le niveau, la cible (le module Rust) et
les champs du contexte de requête (request_id, méthode, chemin, statut,
durée). Source : init_tracing dans crates/forge-api/src/main.rs.
Filtres RUST_LOG
La syntaxe est celle de tracing-subscriber : des directives cible=niveau
séparées par des virgules. Un niveau seul fixe le défaut.
# Développement : forge-api détaillé, le reste en info
RUST_LOG=info,forge_api=debug
# Production : anomalies seules, avec la couche HTTP en info
RUST_LOG=warn,tower_http=info
# Diagnostic ponctuel, très verbeux
RUST_LOG=trace
L'unité de déploiement de forge-api fixe RUST_LOG à info.
Secrets et données personnelles
Toutes les lignes passent par un filtre de rédaction avant d'atteindre la sortie : clés d'API, jetons JWT et bearer, clés privées et adresses e-mail sont masqués (filtre de rédaction du code). C'est un filet : la règle reste de ne pas journaliser de secret.
Lire les journaux d'un conteneur
Les services tournent dans des conteneurs Podman. Lancez les commandes avec le compte qui exécute les conteneurs.
# Suivre un service en direct
podman logs -f forge-api
# Les 100 dernières lignes
podman logs --tail 100 forge-api
# Avec horodatage, sur les dernières 24 heures
podman logs -t --since 24h forge-api
Résultat attendu : des lignes JSON, une par événement. Si Podman répond que le conteneur
n'existe pas, vérifiez le nom avec podman ps -a et le compte qui lance la commande (voir
Problèmes connus).
Les noms de conteneurs du plan backend (podman-compose.yml) :
| Service | Conteneur |
|---|---|
API Chatbotaurus (profil container-api) | forge-api |
| PostgreSQL | forge-postgres |
| Valkey | forge-valkey |
| Qdrant | forge-qdrant |
| Ollama | forge-ollama |
| Authentik | forge-authentik |
| OpenBao | forge-openbao |
| VictoriaMetrics | forge-victoriametrics |
| VictoriaLogs | forge-victorialogs |
| Administration PostgreSQL (pgAdmin) | forge-pgadmin |
| Transcription (Speaches) | forge-faster-whisper |
| Téléchargement des modèles vocaux | forge-tts-models |
| Synthèse vocale (Kokoro) | forge-kokoro-tts |
| LiveKit | forge-livekit |
| CrowdSec | forge-crowdsec |
| Agent de sauvegarde | forge-backup-agent |
| Téléversement (tusd) | forge-tusd |
| Stockage objet S3 | forge-seaweedfs |
Les services du plan client portent le préfixe mcp- (podman-compose.vps2.yml).
Pour les connaître : podman ps --format "{{.Names}}" sur l'hôte client.
En développement local, forge-api ne tourne pas en conteneur : il est lancé
par scripts/dev/run-forge-api.ps1 et écrit dans le terminal qui l'a lancé.
Le frontend (dx serve) écrit la compilation et le rechargement dans son
propre terminal ; ses erreurs d'exécution apparaissent dans la console du
navigateur.
Ce que le dépôt ne règle pas
- Rotation et taille. Aucune option de taille ou de rotation des journaux de
conteneurs n'est fixée dans les fichiers Compose. Dans les unités Quadlet, une
seule (
searxng) choisit un pilote de journal (journald). Vérifiez la politique de votre hôte avant de laisser un conteneur bavard tourner. - Collecte centralisée.
forge-victorialogstourne dans le plan backend de développement. Aucun agent du dépôt n'y envoie les journaux des conteneurs. Ce qui y arrive aujourd'hui, c'est la chaîne d'audit, quand vous activez l'export (voir la section « Chaîne d'audit et export vers VictoriaLogs » plus bas).
Chaîne d'audit et export vers VictoriaLogs
Les événements d'audit (connexions, actions sensibles) forment une chaîne
chaînée par empreintes (crates/forge-audit). Un export optionnel les envoie en
plus vers VictoriaLogs au format jsonline :
| Variable | Effet | Défaut |
|---|---|---|
FORGE_SIEM_ENABLED | À 1, active l'export | désactivé |
FORGE_SIEM_URL | Base de VictoriaLogs | http://localhost:9428 |
L'export est au mieux : si VictoriaLogs est arrêté, l'écriture dans la chaîne
n'est jamais bloquée, et le nombre d'échecs est compté
(crates/forge-audit/src/victorialogs_sink.rs).
Pour vérifier que l'export fonctionne, posez les deux variables, redémarrez forge-api
(il ne relit pas la configuration à chaud), puis interrogez VictoriaLogs (section
« Interroger VictoriaLogs » de Supervision).
Voir aussi
- Supervision — métriques, points de santé et stockage des journaux en développement
- Variables d'environnement — variables de journalisation et d'export de la chaîne d'audit
- Diagnostics et signalement — retrouver une ligne de journal par son identifiant de requête
- Problèmes connus — lire les journaux d'un conteneur qui ne démarre pas
- Gestion des erreurs — niveau de trace par statut HTTP et identifiant de requête
Supervision
Ce chapitre dit ce qui est mesurable aujourd'hui, ce qui est livré mais pas déployé, et ce qui reste à faire. Chaque ligne indique son état.
| État | Sens |
|---|---|
| En service | Le code ou l'unité existe et le déploiement l'installe |
| Développement seul | Défini dans podman-compose.yml, absent du déploiement Quadlet |
| Livré, non branché | Le fichier existe, aucun service ne le charge |
| Retiré du déploiement | L'unité existe, le déploiement ne l'installe plus |
Points de santé de l'API (en service)
Ces routes sont servies par forge-api (crates/forge-api/src/router.rs).
| Route | Rôle | Réponse |
|---|---|---|
GET /api/v1/healthz (alias /api/v1/health) | Le processus répond | 200 avec status, service, version, et sha du binaire quand il est connu |
GET /api/v1/readyz | Le backend est prêt | 200 si PostgreSQL et Valkey répondent, sinon 503 ; indique aussi le nombre de connecteurs chargés |
GET /api/v1/health/status | Page d'état publique | Sonde PostgreSQL, Ollama, Qdrant, Authentik et SMTP ; overall vaut operational, degraded ou down ; 503 si down |
Le champ sha de healthz permet de vérifier de l'extérieur quelle version
tourne après un déploiement.
curl -fsS https://<votre-domaine-api>/api/v1/healthz
curl -fsS https://<votre-domaine-api>/api/v1/readyz
Résultat attendu : healthz répond 200 avec le champ status ; readyz répond 200, ou
503 quand PostgreSQL ou Valkey ne répondent pas (voir
Diagnostics et signalement). En
production, <votre-domaine-api> est l'adresse publique de l'application, notée
app.<domaine> dans les autres chapitres.
Métriques de l'API (en service)
GET /metrics (à la racine, hors /api/v1) rend le format texte Prometheus.
L'accès est protégé :
- avec
PROMETHEUS_BEARER_TOKENposée, le collecteur envoieAuthorization: Bearer <jeton>; un jeton faux reçoit 401 ; - sans cette variable, seule une session de plateforme avec élévation est acceptée.
Quatre séries sont émises :
| Série | Étiquettes |
|---|---|
forge_http_requests_total | méthode, chemin normalisé, statut |
forge_http_request_duration_seconds | méthode, chemin normalisé |
forge_http_errors_total | méthode, chemin normalisé, statut (4xx et 5xx) |
forge_http_active_connections | aucune |
Il n'existe pas de série tool_call_duration_ms, resolve_ms, credentials_ms
ni cache_hit_rate dans le code. Les temps par appel d'outil n'ont pas de
métrique exportée.
Stockage des métriques et des journaux (développement seul)
podman-compose.yml définit deux services :
| Service | Conteneur | Port | Réglage |
|---|---|---|---|
| VictoriaMetrics | forge-victoriametrics | 8428 | rétention de 12 mois (--retentionPeriod=12) |
| VictoriaLogs | forge-victorialogs | 9428 | rétention par défaut de l'outil |
Aucune unité Quadlet ne déploie ces deux services, et ils ne figurent pas dans
les niveaux de containers/scripts/deploy-all.sh. Le fichier de collecte
prévu pour VictoriaMetrics n'est pas monté dans le conteneur :
VictoriaMetrics ne collecte donc rien tant que vous ne l'alimentez pas
(collecte configurée par vos soins, ou envoi depuis un autre collecteur).
Les valeurs VICTORIAMETRICS_RETENTION et VICTORIALOGS_RETENTION du fichier
.env.example ne sont lues par aucun code.
Règles d'alerte (livré, non branché)
Un fichier de règles d'alerte du dépôt contient 24 règles : disque, mémoire, processeur, charge, conteneur arrêté ou
en boucle de redémarrage, sauvegarde ancienne, certificat proche de
l'expiration, force brute SSH, pic de décisions CrowdSec, coffre scellé,
intégrité du système de fichiers. Elles supposent node_exporter sur l'hôte.
Aucun service vmalert n'existe dans les fichiers Compose ni dans les unités
Quadlet. Ces règles ne s'évaluent donc nulle part aujourd'hui. Plusieurs règles ciblent des conteneurs nommés chatbotaurus-*, alors que
les conteneurs du plan backend s'appellent forge-* : elles ne
correspondraient à rien en l'état. Les brancher est
un travail à faire : démarrer vmalert, y monter ce fichier, installer
node_exporter et choisir un destinataire des alertes.
Supervision de l'hôte (en service)
Le déploiement du plan backend installe Beszel (hub et agent), un outil de supervision de serveurs : charge, mémoire, disque, conteneurs. Le hub écoute sur la boucle locale de l'hôte et n'est pas publié : la route d'ingress qui le placerait derrière Authentik est périmée et n'est câblée par aucun script. Accédez-y par un tunnel SSH.
Détection d'intrusion
| Outil | État | Rôle |
|---|---|---|
| CrowdSec | En service (forge-crowdsec, niveau 2 du déploiement) | Analyse les journaux du proxy inverse et de SSH ; un scénario cible les abus de l'API MCP (seuils et durée de blocage fixés dans un scénario du dépôt, non publiés) |
| Falco | Retiré du déploiement le 2026-09-19 | L'unité existe ; le chargement du pilote noyau échoue sur l'hôte cible, une version eBPF reste à concevoir |
| Zeek | Retiré du déploiement le 2026-09-19 | Fichier de site que la préparation d'hôte n'installe pas |
Les outils SIEM et IDS retirés (spec 98), comme les tableaux de bord du plan client, ne font pas partie du plan backend.
Grafana existe côté client sous la forme d'un service mcp-grafana de tableaux
de bord, accessible par le connecteur du même nom.
Niveaux de dégradation (livré, non branché)
Le code définit une cascade de dégradation selon la charge
(DegradationManager, crates/forge-core/src/mgaas/resource_monitor.rs) :
Full, puis NoMcts, NoTot, NoSelfConsistency, TemplateOnly. Les seuils
de mémoire, de processeur et de latence sont fixés dans le code et ne sont
pas publiés ici.
Deux réserves :
- Les moteurs de raisonnement que cette cascade coupe (arbre de pensées,
auto-cohérence, Monte Carlo) n'ont aucun appelant de production : la route
GET /api/v1/mgaas/enginesles déclare « dormants ». GET /api/v1/mgaas/monitor(réservé aux administrateurs avec élévation) crée un moniteur neuf à chaque appel, et aucun appelant de production n'y écrit de mesure. D'après la lecture du code, le niveau rendu estFull.
Ne bâtissez pas d'alerte sur ce point.
Interroger VictoriaLogs
Quand l'export d'audit est activé (voir Journaux), VictoriaLogs répond
sur son API LogsQL, par exemple /select/logsql/query (chemins utilisés par le
connecteur connectors/victorialogs.yaml). Le connecteur du catalogue permet de
poser ces requêtes depuis le chat.
Bonnes pratiques
- Sondez
readyzdepuis votre supervision externe, pashealthz:healthzrépond même quand la base est arrêtée. - Posez
PROMETHEUS_BEARER_TOKENsur un jeton aléatoire et donnez-le au seul collecteur. - Branchez vos propres alertes avant de compter sur le fichier de règles.
Voir aussi
- Journaux — où écrit le backend et comment activer l'export d'audit
- Sécurité — protection du point de métriques et détection d'intrusion en bordure
- Gestion des conteneurs — statistiques de ressources par conteneur et redémarrage d'un service
- Diagnostics et signalement — vérifier à la main chaque service quand une sonde rougit
- Réponse aux incidents — la procédure d'un incident de sécurité, de la détection à la notification
- Gestion des erreurs — seuils et niveaux de la dégradation par paliers
Diagnostics et signalement
Ce chapitre rassemble les outils intégrés pour diagnostiquer un problème, signaler une anomalie et demander une fonctionnalité.
| Besoin | Outil | Résultat |
|---|---|---|
| L'API répond-elle ? | Routes de santé de forge-api | JSON d'état |
| Quel conteneur est tombé ? | podman ps, podman logs | État et journaux |
| Quelle version tourne ? | Champ sha de /api/v1/healthz | SHA du commit déployé |
| Où en est le déploiement ? | scripts/deploy/suivre-autodeploy.sh | Dernier SHA, journal |
| Signaler une anomalie | Courriel au support | Échange tracé |
Santé de la plateforme
forge-api expose trois routes de santé, sans authentification :
# Vivacité : répond 200 tant que le processus tourne (et indique la version)
curl -s http://localhost:3000/api/v1/healthz | jq .
# Disponibilité : vérifie PostgreSQL et Valkey
curl -s http://localhost:3000/api/v1/readyz | jq .
# Page d'état : une entrée par service (up, down ou degraded) avec sa latence
curl -s http://localhost:3000/api/v1/health/status | jq .
La réponse de healthz porte status, service, version et, quand
l'environnement du processus la fournit (FORGE_GIT_SHA), le champ sha.
Comparer ce sha au dernier commit est une façon simple de
savoir si un déploiement est arrivé.
Résultat attendu : readyz répond 200 quand PostgreSQL et Valkey répondent, 503 sinon ;
health/status répond 503 quand l'état global (overall) vaut down. En cas de 503,
passez à la vérification manuelle des services ci-dessous.
Derrière le nom public, remplacez localhost:3000 par
https://app.<domaine>.
Vérification manuelle des services
# État de tous les conteneurs
podman ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# PostgreSQL
podman exec forge-postgres sh -c 'pg_isready -U "$POSTGRES_USER"'
# Valkey
podman exec forge-valkey valkey-cli ping
# Qdrant (liste des collections)
curl -s http://localhost:6333/collections | jq .
# Ollama : modèles disponibles
podman exec forge-ollama ollama list
# OpenBao : état de scellement (code de sortie 2 = scellé)
podman exec forge-openbao bao status
# Passerelle MCP du plan client (port 8811)
curl -s http://localhost:8811/health
Résultat attendu : pg_isready répond « accepting connections » ; valkey-cli ping
répond PONG ; la requête Qdrant liste les collections ; ollama list liste les modèles ;
bao status rend le code de sortie 2 quand le coffre est scellé ; la passerelle répond à
/health. Un échec renvoie à la section correspondante de
Problèmes connus.
Les noms des conteneurs sont ceux des fichiers compose. En production, les services d'une unité Quadlet se pilotent avec systemd :
systemctl --user status forge-api.service
Ressources
# Mémoire et CPU par conteneur
podman stats --no-stream --format "table {{.Name}}\t{{.MemUsage}}\t{{.CPUPerc}}"
# Espace utilisé par Podman (images, conteneurs, volumes)
podman system df
# Espace disque de l'hôte
df -h
Journaux du backend
# Temps réel
podman logs -f forge-api
# 100 dernières lignes
podman logs --tail 100 forge-api
# Pour une unité Quadlet : journal systemd
journalctl --user -u forge-api.service -n 100
Les journaux de forge-api sont écrits en JSON par défaut, une ligne par
événement, avec les champs du contexte de requête courant (LOG_FORMAT=pretty donne une
sortie lisible ; TRACING_JSON n'est pas lue par ce binaire). Chaque requête porte un en-tête
X-Request-ID (généré s'il manque) que la réponse renvoie : quand un
utilisateur signale une erreur, demandez-lui cet identifiant pour retrouver
la ligne.
Voir aussi Journaux.
Diagnostic de la passerelle MCP
Les routes MCP de forge-api exigent un utilisateur authentifié
(en-tête Authorization: Bearer <jeton>, ou cookie de session) ; $TOKEN est le jeton
rendu par la connexion, décrite dans Documentation Swagger :
# Ouvrir une session (la réponse porte l'en-tête Mcp-Session-Id)
curl -i -X POST http://localhost:3000/api/v1/mcp \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{}},"id":1}'
# Consulter le catalogue des connecteurs
curl -s http://localhost:3000/api/v1/mcp/catalogue \
-H "Authorization: Bearer $TOKEN" | jq .
Pour les erreurs renvoyées, voir Gestion des erreurs.
Suivre un déploiement
Le déploiement est tiré par l'hôte (minuteur toutes les 2 minutes). Depuis le poste d'un opérateur :
bash scripts/deploy/suivre-autodeploy.sh
Il affiche l'état du minuteur, le dernier SHA déployé et la fin du journal
et de la construction, tous relatifs au front. Il ne lit pas l'état du backend :
comparez le champ sha de /api/v1/healthz au commit attendu.
Signaler une anomalie
Écrivez à support@chatbotaurus.com en indiquant :
- la description du problème ;
- les étapes pour le reproduire ;
- le comportement attendu et le comportement observé ;
- les journaux pertinents, anonymisés ;
- la version (
shade/api/v1/healthz) et l'environnement (production, plan client ou développement local) ; - l'identifiant
X-Request-IDde la requête en cause, s'il est connu.
Attention : confidentialité
Avant de partager des journaux, retirez toute information sensible : clés d'API, jetons, mots de passe, adresses IP, données personnelles. Ne partagez jamais les clés de descellement OpenBao.
Une faille de sécurité se signale à security@chatbotaurus.com, pas par le canal ordinaire.
Demander une fonctionnalité
Écrivez à support@chatbotaurus.com avec le préfixe [Feature] dans
l'objet et décrivez :
- le cas d'usage ;
- la solution proposée ;
- les alternatives envisagées ;
- l'impact sur la conformité UE, si applicable.
Voir aussi
- Problèmes connus — solutions pas à pas aux erreurs courantes, symptôme par symptôme
- Journaux — format des journaux, filtres et export de la chaîne d'audit
- Architecture Chatbotaurus — interactions entre composants, deux plans et transport MCP
- Supervision — ce que chaque route de santé vérifie réellement
- Gestion des conteneurs — redémarrer, inspecter et mettre à jour un service
Problèmes connus
Chatbotaurus, comme tout système complexe, peut rencontrer des problèmes
occasionnels. Ce guide fournit des solutions pour les cas courants.
Les noms de conteneurs sont ceux des fichiers podman-compose.yml (plan
backend, services forge-*) et podman-compose.vps2.yml (plan client,
services mcp-*).
Astuce : un problème qui n'est pas listé ici ?
Écrivez à support@chatbotaurus.com en suivant la marche décrite dans Diagnostics et signalement.
Par symptôme
| Vous constatez | Section |
|---|---|
| Un conteneur ne démarre pas, un réseau ou un volume est introuvable | Un conteneur ne démarre pas |
| Les services ne repartent pas après un redémarrage de l'hôte | Les services Quadlet ne redémarrent pas après un redémarrage de l'hôte |
| Un port est déjà utilisé | Conflit de port |
| Les conteneurs ne se joignent pas par leur nom | Résolution DNS entre conteneurs |
| Des données disparaissent après un redémarrage | Volumes et persistance des données |
| Une modification n'apparaît pas en production | Ma modification n'apparaît pas en production |
| Ollama est tué ou ne répond plus | Ollama à court de mémoire (OOM) |
| Ollama répond « model not found » | Modèle introuvable |
| Les réponses du modèle sont lentes | Latence élevée des réponses |
| Erreur 503 sur la lecture d'un secret | OpenBao scellé |
| Un service ne reçoit pas ses secrets | Un service ne reçoit pas ses secrets |
| « session expired or unknown » ou « missing Mcp-Session-Id » | Erreur de session Streamable HTTP |
| Un connecteur ne répond pas (TIMEOUT, SERVICE_UNAVAILABLE, RATE_LIMITED, SSRF_BLOCKED) | Un connecteur échoue |
connector rejected by registry au démarrage | Un connecteur est rejeté au démarrage |
Erreur CIRCUIT_OPEN (503) | Erreur CIRCUIT_OPEN (503) |
| PostgreSQL refuse la connexion | PostgreSQL : connexion refusée |
| Qdrant renvoie des erreurs de lecture | Qdrant : index corrompu |
| Le stockage objet répond 403 à tout | Le stockage objet S3 refuse toutes les requêtes |
| Le wasm ne compile pas | Erreur de compilation du wasm |
dx serve ne recharge plus | dx serve ne recharge plus |
| Un réglage du frontend est sans effet | La configuration du frontend est ignorée |
| 403 sur les POST, PUT ou DELETE | Le CSRF rejette les requêtes |
| Tous les utilisateurs sont déconnectés après un redémarrage du backend | Le JWT est invalide après un redémarrage du backend |
| La connexion SSO échoue | Connexion impossible |
Infrastructure Podman
Un conteneur ne démarre pas
- Lisez les journaux du conteneur :
podman logs forge-postgres - Vérifiez que les deux réseaux existent (les fichiers compose les
déclarent externes et ne les créent pas) :
podman network ls | grep -E "chatbotaurus-vps1|mgaas-vps2" - S'ils manquent, créez-les :
podman network create chatbotaurus-vps1 podman network create mgaas-vps2 - Pour un service sous Quadlet, regardez l'unité systemd :
systemctl --user status forge-api.service journalctl --user -u forge-api.service -n 100
Les services Quadlet ne redémarrent pas après un redémarrage de l'hôte
Les unités Quadlet tournent sous un compte de déploiement non privilégié (rootless). Sans le
mode « linger » de systemd, elles s'arrêtent à la déconnexion et ne
repartent pas au démarrage. Le script containers/scripts/enable-linger.sh
l'active, une fois, par hôte. Il se lance en root, après la création du compte de
déploiement, en lui passant le nom de ce compte : bash containers/scripts/enable-linger.sh <compte-deploiement> (le compte doit exister, sinon le script s'arrête et dit de le
créer). Résultat attendu : des lignes [OK], dont lingering enabled, puis la
vérification du répertoire d'exécution et du socket Podman de ce compte.
Conflit de port
Si un port est déjà utilisé :
ss -tlnp | grep <port>
Sous Windows (développement local) :
netstat -ano | Select-String "5432"
Ports publiés par défaut en développement : 5432 (PostgreSQL), 6380 (Valkey, pour ne pas entrer en collision avec un Redis local sur 6379), 6333 (Qdrant), 11434 (Ollama), 9000 (Authentik), 8200 (OpenBao).
Résolution DNS entre conteneurs
Si les conteneurs ne se résolvent pas entre eux par leur nom :
- Vérifiez qu'ils sont sur le même réseau :
podman inspect forge-api --format '{{json .NetworkSettings.Networks}}' - Vérifiez le moteur réseau de Podman (netavark attendu) :
podman info | grep -i networkBackend - Rechargez les réseaux :
podman network reload --all - En dernier recours, recréez les conteneurs (les volumes sont conservés).
Rappel : PostgreSQL et Valkey portent les alias postgres et valkey sur
mgaas-vps2. Un service du plan client doit utiliser ces alias, pas
forge-postgres.
Volumes et persistance des données
Si des données disparaissent après un redémarrage :
- Vérifiez les volumes montés :
podman inspect forge-postgres --format '{{json .Mounts}}' podman volume ls - Utilisez les volumes nommés des fichiers compose (noms logiques
forge-pgdata,forge-valkey-data,forge-qdrant-data, entre autres) plutôt que des montages temporaires. Ces volumes sontexternal: leur nom réel est la cléname:du blocvolumes:(grep -n "name:" podman-compose.yml) et compose ne crée pas un volume externe absent. La création est décrite dans Déploiement avec Podman.
Déploiement
Ma modification n'apparaît pas en production
Le déploiement est tiré par l'hôte, toutes les 2 minutes, et seulement si la branche principale a avancé. Vérifiez dans l'ordre :
- le champ
shade/api/v1/healthzcorrespond-il à votre commit ?curl -s https://app.<domaine>/api/v1/healthz | jq . - où en est le déploiement du front (ce script ne lit pas l'état du backend : l'étape 1
le prouve) ?
bash scripts/deploy/suivre-autodeploy.sh - un commit qui ne touche que la documentation ne reconstruit pas l'image backend : c'est normal ;
- si le service ne répond pas après un redémarrage, le script du backend revient à l'image précédente et l'indique dans son état.
Après un déploiement du front, rechargez la page en vidant le cache du navigateur : l'ancien wasm peut rester en cache.
Ollama et modèles IA
Ollama à court de mémoire (OOM)
Si Ollama est tué par le noyau :
- Vérifiez la mémoire disponible :
free -h - Vérifiez les limites du conteneur (fixées dans le plan compose) :
podman inspect forge-ollama | grep -i memory - Solutions :
- augmentez la limite mémoire si l'hôte le permet ;
- réduisez le nombre de modèles chargés simultanément ;
- choisissez un modèle plus petit (variable
OLLAMA_MODEL).
Modèle introuvable
Si Ollama répond « model not found » :
# Modèles disponibles
podman exec forge-ollama ollama list
# Télécharger le modèle manquant
podman exec forge-ollama ollama pull <nom-du-modèle>
Le nom doit correspondre à celui que le backend demande
(OLLAMA_MODEL).
Latence élevée des réponses
Si les réponses du LLM sont lentes :
- Vérifiez l'utilisation CPU (
podman stats --no-stream). - Vérifiez qu'un seul modèle est chargé : passer d'un modèle à l'autre est coûteux.
- Le code prévoit une dégradation par paliers au-delà de 10 s de latence moyenne (voir Gestion des erreurs), mais les moteurs qu'elle coupe n'ont pas d'appelant de production : ne comptez pas dessus pour réduire la latence (voir Supervision).
OpenBao (gestion des secrets)
OpenBao scellé
OpenBao se scelle au redémarrage. Symptôme : erreur 503 sur les appels qui lisent un secret.
- Vérifiez l'état (code de sortie 2 = scellé) :
podman exec forge-openbao bao status - Descellez avec le seuil de clés défini à l'initialisation. La commande
demande la clé à la saisie :
Répétez avec des clés distinctes jusqu'àpodman exec -it forge-openbao bao operator unsealSealed: false.
Attention
Les clés de descellement se conservent séparément et en lieu sûr. Ne les commitez jamais dans le dépôt. La topologie de descellement est décrite dans le guide d'exploitation du coffre, hors de ce livre.
Un service ne reçoit pas ses secrets
- Vérifiez qu'OpenBao est descellé (voir la section « OpenBao scellé » ci-dessus).
- Vérifiez les permissions du jeton utilisé par le backend.
- Consultez les journaux du backend :
podman logs --tail 100 forge-api
Passerelle MCP
Erreur de session Streamable HTTP
Si vous recevez une erreur « session expired or unknown » (code JSON-RPC -32600) ou « missing Mcp-Session-Id » :
- Vérifiez que l'en-tête
Mcp-Session-Idest présent dans la requête ; - les sessions expirent après 30 minutes d'inactivité ;
- ouvrez une nouvelle session par une requête
initializesurPOST /api/v1/mcp.
Un connecteur échoue
Si un connecteur (Odoo, n8n, Matomo, entre autres) ne répond pas :
- Identifiez le code d'erreur renvoyé :
TIMEOUT(504) : le service tiers est trop lent (voirtimeout_msdu connecteur) ;SERVICE_UNAVAILABLE(503) : connexion impossible ;RATE_LIMITED(429) : limite de l'amont atteinte, respectezRetry-After;ForbiddenavecSSRF_BLOCKED: l'URL de base fournie par le locataire vise le réseau interne, elle est refusée.
- Vérifiez que le conteneur du service tourne :
podman ps --filter name=mcp- - Vérifiez les identifiants du connecteur (variable
token_envoukey_envdu YAML, ou identifiants du locataire). - Lisez les logs du service concerné (
podman logs mcp-n8n, par exemple).
Un connecteur est rejeté au démarrage
Au démarrage, forge-api journalise connector rejected by registry (EU compliance?) pour un connecteur dont gdpr_compliant vaut false ou dont
la résidence des données n'est pas européenne. Corrigez le bloc
compliance du YAML : voir
Conception des connecteurs MCP.
Erreur CIRCUIT_OPEN (503)
Le disjoncteur d'un agent s'est ouvert après plusieurs échecs consécutifs. Il
laisse repasser un essai après un court délai. Cherchez la cause des échecs
dans les journaux de forge-api (modèle indisponible, connecteur en erreur),
puis attendez le délai ou corrigez la cause.
Base de données et stockage
PostgreSQL : connexion refusée
- Vérifiez que le conteneur tourne :
podman ps | grep forge-postgres - Vérifiez les journaux :
podman logs forge-postgres - Vérifiez que le port 5432 n'est pas pris par une autre instance PostgreSQL locale.
Qdrant : index corrompu
Si Qdrant renvoie des erreurs de lecture :
- Lisez les journaux :
podman logs forge-qdrant - Restaurez d'abord l'instantané de la collection (voir Sauvegarde et restauration).
- En dernier recours, supprimez la collection (les embeddings devront
être régénérés) :
curl -X DELETE http://localhost:6333/collections/<collection>
Le stockage objet S3 refuse toutes les requêtes
Le service forge-seaweedfs est fermé par défaut : si les variables
SEAWEEDFS_S3_* référencées par son fichier d'identités sont absentes ou vides, toute requête est
refusée (403). Renseignez ces variables dans l'environnement du compose
puis recréez le service : podman-compose -p chatbotaurus-vps1 up -d --force-recreate seaweedfs. Résultat attendu : une requête signée avec ces clés aboutit, une requête
anonyme reçoit toujours 403.
Interface (Dioxus wasm)
Erreur de compilation du wasm
La commande de référence est :
cargo build -p forge-ui --target wasm32-unknown-unknown --bin chatbotaurus
Quatre causes reviennent souvent :
La cible wasm peut ne pas être installée. Installez-la :
rustup target add wasm32-unknown-unknown
Un cache cargo corrompu après une interruption brutale peut laisser des artefacts incohérents :
cargo clean -p forge-ui
cargo build -p forge-ui --target wasm32-unknown-unknown --bin chatbotaurus
Les erreurs de compilation Rust se diagnostiquent plus vite avec
cargo check, qui s'arrête avant l'édition de liens :
cargo check -p forge-ui --target wasm32-unknown-unknown
Enfin, une Dioxus CLI obsolète se manifeste par des erreurs opaques à l'édition de liens ou à l'empaquetage. Réinstallez la dernière version 0.7 :
cargo install dioxus-cli --force
Le paquet de production se construit avec :
dx build --release --platform web --package forge-ui
Sous Windows, l'optimiseur wasm-opt peut planter et dx rend pourtant
un code de sortie 0 : une ligne ERROR dans sa sortie suffit à refuser le
paquet. La construction de production se fait sous Linux.
dx serve ne recharge plus
Il arrive que l'observateur de fichiers se désynchronise (montage croisé
Windows/WSL). Arrêtez dx serve, puis relancez-le :
dx serve --package forge-ui --bin chatbotaurus --port 8080
La configuration du frontend est ignorée
Le frontend wasm ne lit pas les variables d'environnement système à l'exécution (il s'exécute dans le navigateur). Sa configuration est compilée :
- la marque, les liens et les offres affichés viennent de
crates/forge-ui/src/config/site.rs; - l'adresse de l'API vient de
crates/forge-ui/src/config/api.rs: en web, le chemin relatif/api/v1du même domaine ; sur les cibles natives, la valeur deAPI_URLfixée à la compilation (défauthttp://localhost:3000/api/v1).
Pour appliquer un changement : éditez le fichier, reconstruisez le wasm ;
dx serve recharge automatiquement.
Le CSRF rejette les requêtes
Symptôme : 403 sur les POST, PUT ou DELETE.
Vérifiez :
- que le cookie
csrf-tokenest présent (outils du navigateur, onglet Application, Cookies) ; - que l'en-tête
x-csrf-tokenest envoyé avec la même valeur que le cookie ; - que l'origine du frontend figure dans
CORS_ORIGINScôté backend.
Le JWT est invalide après un redémarrage du backend
La valeur de JWT_SECRET doit rester stable d'un démarrage à l'autre. Si
elle change (par exemple générée au hasard à chaque lancement), tous les
jetons émis avant deviennent invalides. Fixez JWT_SECRET dans votre
fichier d'environnement et chargez-le à chaque démarrage.
Authentik (authentification)
Connexion impossible
- Vérifiez qu'Authentik répond (port 9000 en développement) :
podman ps --filter name=authentik - Lisez les journaux (en développement
forge-authentik, en productionforge-authentik-serveretforge-authentik-worker) :podman logs forge-authentik - Vérifiez l'application et le fournisseur OIDC dans la console d'administration.
Performance et surveillance
Seuils de dégradation
Le code prévoit de réduire les techniques d'IA quand l'un de ces seuils est
franchi (crates/forge-core/src/mgaas/types.rs). Cette cascade est livrée mais
non branchée (voir Supervision).
Les seuils (mémoire, processeur, latence) sont fixés dans le code et ne sont pas publiés ici.
VictoriaMetrics (forge-victoriametrics, port 8428) et VictoriaLogs
(forge-victorialogs, port 9428) existent dans le compose de développement.
Rien ne les alimente par défaut et aucune unité Quadlet ne les déploie : voir
Supervision.
Besoin d'aide supplémentaire ?
- Consultez les diagnostics intégrés pour rassembler les informations utiles.
- Écrivez à support@chatbotaurus.com.
Voir aussi
- Diagnostics et signalement — rassembler santé, journaux et identifiant de requête avant d'écrire au support
- Gestion des conteneurs — commandes du quotidien : journaux, redémarrage, inspection, ressources
- Déploiement avec Podman — créer réseaux et volumes, suivre le déploiement tiré par l'hôte
- Variables d'environnement — chaque variable citée dans ces solutions, avec son défaut
- Gestion des erreurs — signification de chaque code d'erreur renvoyé par l'API
Conformité RGPD
Chatbotaurus est conçu pour appliquer le règlement (UE) 2016/679 (RGPD) dans le code. Le statut précis est « prêt par conception » : les contrôles sont câblés et une preuve exécutable existe pour chacun. Ce n'est pas une certification. Aucun organisme tiers n'a délivré de certificat RGPD.
Ce chapitre cite chaque obligation avec son article, le mécanisme qui l'applique, et ce qui reste ouvert. Les numéros d'article sont ceux du texte officiel du règlement ; vérifiez-les sur ce texte avant de les opposer à un tiers.
Obligations et mécanismes
| Obligation | Mécanisme dans le produit |
|---|---|
| Minimisation (art. 5, par. 1, point c) | Les secrets d'un client ne sont pas chargés au démarrage : ils sont résolus à la requête, par organisation, et n'existent en mémoire que le temps de l'appel. |
| Consentement (art. 7) | Formulaire de consentement avant conversation, configurable et persisté. Les consentements du domaine de santé se donnent en deux étapes, par finalité, avec un jeton dédié par flux, portés par organisation. |
| Accès et portabilité (art. 15 et 20) | Export du compte livré dans le produit. |
| Effacement (art. 17) | Suppression et purge des données personnelles côté serveur (balayages : Variables d'environnement, section « Purges planifiées ») ; effacement d'un dossier patient sur les surfaces de santé. |
| Protection dès la conception (art. 25) | Le cloisonnement par organisation est appliqué dans chaque requête, pas par un réglage. Les traces d'exécution ne traversent pas les organisations, même pour un administrateur. |
| Registre des traitements (art. 30) | Un registre est tenu dans le dépôt, versionné avec le code. Il est à l'état de brouillon : la confirmation par le délégué à la protection des données et le conseil est en attente. |
| Sécurité du traitement (art. 32) | Second facteur (TOTP, WebAuthn) et cookies durcis avec protection CSRF. Mots de passe hachés en Argon2id. Identifiants de services externes chiffrés en AES-256-GCM. Journal des connexions. |
| Responsabilité (art. 5, par. 2) | Journal d'audit chaîné ; sa vérification à la demande par un administrateur est disponible. |
| Transferts (chapitre V) | Mesure d'audience auto-hébergée, aucun script ni cookie tiers. Les domaines de cloud hors UE sont refusés par une couche du serveur. |
Données de santé
Les données de santé relèvent de l'article 9. Le produit les traite en qualité de sous-traitant pour le compte de professionnels, avec une autorisation dédiée du module santé. La condition de l'article 9, par. 2, applicable est à confirmer par le conseil juridique : le registre le dit explicitement.
L'analyse d'impact (AIPD) existe dans le dépôt, aux formats auto-évaluation et complet.
Hébergement et sous-traitants
- L'inférence de l'IA est locale : modèles auto-hébergés et recherche documentaire sur le même plan.
- Les sous-traitants de l'attestation de résidence sont européens ou suisses (décision d'adéquation de la Commission pour la Suisse, à vérifier sur le texte officiel).
- L'attestation de résidence des données est un projet, en attente de validation par le conseil.
- Les prestataires de paiement et de courriel transactionnel sont nommés dans Comparatifs, critère par critère ; le prestataire de paiement l'est aussi dans Tarification, section Paiement et facturation.
- Un prestataire de paiement américain existe comme voie de secours seulement. Son activation pour des personnes concernées européennes exige une évaluation de transfert et des clauses contractuelles types. Les prestataires européens sont le choix par défaut.
Conservation
La conservation est définie par type de donnée et détaillée dans la politique de confidentialité. Elle est appliquée par des balayages qui échouent en sécurité :
- les sauvegardes : 30 jours par défaut, purge limitée aux travaux terminés ;
- la voix : balayage de rétention dédié ;
- l'observabilité : durée à confirmer. L'accord de sous-traitance (DPA) annonce 90 jours (
docs/legal/dpa.md, section des journaux) ; le compose de développement fixe 12 mois pour VictoriaMetrics ; - le dossier clinique garde sa rétention légale, par exception.
Exercer ses droits
- Contact du délégué à la protection des données :
dpo@chatbotaurus.com. - Délai de réponse : 30 jours calendaires (art. 12, par. 3).
- Réclamation possible auprès de l'autorité de contrôle de votre pays : la CNIL en France ; la CNPD au Luxembourg (à vérifier sur le texte officiel).
- Au 27 mai 2026, la fonction de délégué est portée par l'opérateur. Son externalisation vers un cabinet certifié est prévue.
Ce qui reste ouvert
- Registre des traitements : à formaliser et à signer.
- Base de l'article 9, par. 2 : à confirmer.
- Attestation de résidence des données : en attente.
- Le chiffrement applicatif des données de santé au repos est actif en production (
PHI_AT_REST_KEYest obligatoire au démarrage). Son étendue sur toutes les données de santé reste à établir. Le chiffrement du disque est documenté. - Le droit d'effacement est câblé sur les surfaces de santé et d'apprentissage. Son étendue sur le reste est à vérifier surface par surface.
Voir aussi
- Réponse aux incidents — notification des violations (articles 33 et 34) et calendrier de réponse
- Modèle de menaces — où vit le risque sur les données de santé et les secrets
- Architecture de confiance zéro — classification des données et chiffrement au repos, contrôle par contrôle
- Conformité NIS2 — mesures de sécurité et de continuité exigées par les clients régulés
- SLA, support et niveaux de service — engagements de disponibilité, de support et de reprise après incident
- Routes des ressources — routes publiques de conformité (statut gradué, manifeste signé) et journal d'audit chaîné
- API-as-a-Service EU souverain — le registre des connecteurs et le bloc de conformité (résidence des données) de chaque entrée
- Dans le dépôt :
docs/legal/(registre, AIPD, accord de sous-traitance, politique de confidentialité)
Conformité NIS2
La directive (UE) 2022/2555 (NIS2) fixe des mesures de gestion des risques de cybersécurité, et des délais de notification des incidents, pour les entités essentielles et importantes. Les articles cités ci-dessous (21 et 23) sont ceux de ce texte officiel ; vérifiez-les sur lui avant de les opposer à un tiers.
Notre position, exactement
- Statut : partiellement prêt. Une partie des contrôles est câblée ; le reste est identifié et non livré.
- Par sa taille, Chatbotaurus n'est pas parmi les entités essentielles ou importantes. Il applique l'article 21 parce que ses clients régulés doivent sécuriser leur chaîne d'approvisionnement (article 21, par. 2, point d). Leur exigence devient la sienne.
- Aucune certification ni audit de conformité NIS2 n'est délivré à ce jour. La page publique de sécurité place l'auto-évaluation et l'audit à l'horizon 2026-2027.
Mesures en place
Les mesures sont groupées par famille ; chaque ligne dit ce qui est câblé et ce qui manque.
Gestion des risques
- Un modèle de menaces STRIDE est tenu dans le dépôt, avec ses lacunes : voir le chapitre Modèle de menaces.
- Des gardes exécutables mesurent le câblage des contrôles de sécurité avant chaque livraison.
Chaîne d'approvisionnement (article 21, par. 2, point d)
- Analyse Trivy (gravité haute et critique) de l'image du backend et signature de l'image par un workflow dormant : aucun exécuteur n'y est rattaché, il ne tourne pas aujourd'hui.
- Inventaire logiciel (SBOM) au format CycloneDX pour les artefacts publiés, dans le dépôt.
- Avis de vulnérabilités au format CSAF, avec justifications VEX.
- Images épinglées, et image de l'agent de sauvegarde servie par un miroir européen. Les registres hors UE sont interdits par une garde.
- Une couche du serveur refuse les domaines de cloud hors UE.
Gestion des incidents (article 23, à vérifier sur le texte officiel)
- Procédure interne documentée : sévérité, confinement, éradication, notification. Voir le chapitre Réponse aux incidents.
- Calendrier suivi : alerte précoce sous 24 heures, notification sous 72 heures, rapport final sous un mois.
- Limite : la notification aux autorités dans les délais est un processus encore à formaliser. Il n'y a ni supervision 24/7 ni SIEM temps réel.
Contrôle d'accès
- Authentification fédérée via Authentik, ou mot de passe avec second facteur.
- Second facteur : TOTP, WebAuthn et codes de secours. Par défaut,
FORCE_2FAimpose un second facteur à la connexion par mot de passe (TOTP, sinon code par courriel). L'obligation d'enrôler le TOTP par rôle est un réglage de déploiement (FORGE_MFA_REQUIRED_ROLES,FORGE_MFA_TOTP_REQUIRED). Un compte créé par le SSO s'appuie sur le second facteur d'Authentik. - Rôles et politiques Cedar ; journal d'audit chaîné.
- Gouvernance des canaux de messagerie : tout canal passant par un fournisseur soumis au Cloud Act (WhatsApp, Telegram, Messenger) est inactif par défaut. Son activation par client exige une décision d'architecture documentée et un audit du flux.
Cryptographie
- TLS en bordure : Traefik sur le plan de la plateforme, Caddy sur le plan du client, avec renouvellement automatique des certificats. Traefik impose TLS 1.3 au minimum par défaut ; une option distincte, hors défaut, autorise TLS 1.2 pour des clients anciens. Les clients HTTP du backend utilisent rustls, sans OpenSSL.
- Mots de passe en Argon2id, identifiants en AES-256-GCM, journal d'audit en XChaCha20-Poly1305.
- Secrets : sops + age, puis OpenBao pour le profil régulé. Voir le chapitre OpenBao et secrets.
- Post-quantique : ML-DSA-65 (FIPS 204) sur le jeton et ML-KEM-768 (FIPS 203) sur le canal de la passerelle MCP, sur activation. Une anticipation, pas une exigence de la directive.
Continuité et sauvegarde
- Sauvegarde par agent installé sur l'hôte qui porte les données : un agent par hôte, en tirage seul, chiffré, avec rétention de 30 jours.
- Restauration protégée : URL signée à durée courte et approbation humaine.
- Des procédures de restauration sont exercées par moteur de base, avec rapports datés dans le dépôt.
- Limite : l'exercice de restauration de production n'est pas fait. Il est bloqué sur une ressource du titulaire. Aucun objectif de temps de reprise n'est promis par ce chapitre.
Le règlement d'exécution
Le règlement d'exécution (UE) 2024/2690 fixe au niveau européen les exigences techniques de l'article 21, par. 2 pour certains fournisseurs de services numériques. Le guide technique de l'ENISA qui l'accompagne décline des familles de mesures avec des exemples de preuves. Selon l'analyse interne, les gardes couvrent déjà la majorité des familles ; les familles encore nues sont la continuité et les sauvegardes exercées, la formation et la remédiation automatisée.
Ce qui reste ouvert
- Formaliser la notification aux autorités.
- Exercice de restauration de production.
- Test d'intrusion indépendant.
- Formation à la cybersécurité.
Voir aussi
- Réponse aux incidents — phases, sévérités et calendrier de notification suivis par la procédure interne
- Architecture de confiance zéro — statut câblé, optionnel ou prévu de chaque contrôle de sécurité
- OpenBao et secrets — les deux paliers de gestion des secrets et l'audit du coffre
- Conformité RGPD — obligations de protection des données et mécanismes qui les appliquent
- Sauvegarde et restauration — chaînes de sauvegarde, rétention et répétition de restauration exercée
Gaia-X
Gaia-X est un cadre européen de confiance et de souveraineté pour les services cloud. Ce chapitre dit ce que Chatbotaurus a fait, et ce qu'il n'a pas fait.
Statut
- Prêt par conception. La souveraineté des dépendances est câblée, et une preuve exécutable existe.
- Aucun label Gaia-X n'a été obtenu. Aucune auto-évaluation formelle n'a été déposée.
- La page publique de sécurité place le label Gaia-X à l'horizon 2026-2027. C'est une cible, pas un acquis.
Une ancienne version de ce chapitre portait un badge « score 9/10 » et parlait d'une Self-Description publiée. Aucun auteur ni méthode ne soutenait ce score. Il est retiré.
Ce qui est câblé
| Principe | Mécanisme |
|---|---|
| Souveraineté des dépendances | Liste blanche de serveurs : un serveur MCP n'est utilisable que s'il est autorisé. Les serveurs de fournisseurs américains sont refusés. |
| Refus des points de terminaison non souverains | Une couche du serveur refuse les domaines de cloud hors UE. |
| Résidence | Exécution locale de l'inférence et de la recherche documentaire ; mesure d'audience auto-hébergée ; aucun script tiers. |
| Transparence | Le code, les gardes et les registres de conformité sont dans le dépôt. Les statuts affichés sur le site ne peuvent pas dépasser ceux du registre interne, ce qu'une garde vérifie. |
| Chaîne d'approvisionnement | Inventaire logiciel CycloneDX, analyse Trivy, avis CSAF et VEX, images épinglées. |
| Portabilité | Export du compte via l'API, au format JSON. Voir la limite ci-dessous. |
| Interopérabilité | Protocole MCP standard pour les connecteurs. |
Ce qui n'est pas fait
- Pas de label. Pas d'auto-évaluation déposée.
- Self-Description. Un brouillon existe dans le dépôt au format JSON-LD. Son numéro d'enregistrement est marqué en attente. Il n'est pas publié. Plusieurs de ses déclarations techniques doivent être réalignées sur le code avant toute publication, notamment la section chiffrement homomorphe : le produit n'en fournit pas aujourd'hui.
- Réversibilité. Un script rejouable qui restitue la base d'un client sur une instance vierge n'existe pas encore. Le règlement (UE) 2023/2854 (Data Act), articles 23 à 31 (à vérifier sur le texte officiel), en fait une obligation directe : c'est le premier chantier ouvert sur ce point.
- Fédération. Participer à une fédération Gaia-X (catalogue fédéré, identité décentralisée) n'est pas livré. Ce chapitre ne la présente pas comme un acquis.
Souveraineté et licence
La souveraineté se lit aussi sur les licences. La plateforme n'embarque que des composants à licence permissive. Les outils du client, chez lui, peuvent être sous une licence plus restrictive, parce que la frontière est une API et non une œuvre dérivée.
Voir aussi
- Conformité RGPD — obligations de protection des données, hébergement et sous-traitants européens
- Conformité NIS2 — chaîne d'approvisionnement, cryptographie et continuité exigées par les clients régulés
- Conception des connecteurs MCP — contrôle de conformité UE appliqué à chaque connecteur au démarrage
- Sauvegarde et restauration — ce que la plateforme sauvegarde et restaure aujourd'hui, et ses limites
- SLA, support et niveaux de service — engagements de disponibilité et de reprise, et ce qu'ils ne couvrent pas
- Dans le dépôt : le registre des référentiels (
docs/compliance/referentiels-360.yaml)
Sécurité
Ce chapitre décrit les protections que le code applique, avec le fichier qui les porte. Il sépare ce qui est en place de ce qui reste à faire. Il ne revendique aucune certification. À la fin, vous saurez quelles clés poser avant de passer en production et quelles protections reposent sur votre exploitation.
Principes
- Démarrage fermé. Sans déclaration explicite de développement
(
FORGE_DEV, ouNODE_ENV,ENVIRONMENT,RUST_ENV,APP_ENVvalantdevelopment,dev,localoutest),forge-apiapplique la posture production. Le silence n'est jamais une autorisation. - Cloisonnement par organisation. Les listes sont filtrées par organisation.
Hors développement déclaré,
forge-apirefuse de démarrer sansFORGE_TENANT_STRICTà1. - Données hébergées dans l'UE. Le registre des connecteurs refuse un
connecteur dont la résidence des données n'est pas dans l'UE ou
auto-hébergée (
connectors/README.md).
Secrets
- Dans le dépôt : aucun. Les fichiers
.envsont ignorés par git. Le modèle.env.examplene porte que des gabarits. - En production, un script génère les fichiers d'environnement sur la machine cible, avec des permissions restreintes, et n'imprime jamais les valeurs (script d'initialisation des secrets de l'hôte).
- OpenBao est facultatif. Si
BAO_ADDRest posée, il surcharge les secrets d'exécution. Le service du fichier Compose tourne en mode développement ; la configuration de production est portée par l'unité de production du coffre. - Journaux. Un filtre masque les clés d'API, jetons, clés privées et adresses e-mail avant l'écriture (filtre de rédaction du code).
Au démarrage de production, forge-api vérifie :
| Contrôle | Règle |
|---|---|
JWT_SECRET | 32 caractères au moins, ni valeur connue ni gabarit |
FORGE_STRICT_SECRETS à 1 | AT_REST_ENCRYPTION_KEY et AUDIT_SIGNING_KEY deviennent obligatoires ; sinon leur absence est un avertissement |
PHI_AT_REST_KEY | Obligatoire en production, 64 caractères hexadécimaux : sinon forge-api refuse de démarrer |
| Cloisonnement | FORGE_TENANT_STRICT à 1, obligatoire |
Le dépôt ne planifie pas de rotation automatique de l'ensemble des secrets : elle
reste à organiser côté exploitation. Deux rotations manuelles existent : celle de
la clé des données de santé (l'ancienne clé se pose dans
PHI_AT_REST_KEY_PREVIOUS, lue en repli) et
celle de la clé de l'agent de sauvegarde (route d'administration de la
sauvegarde).
Authentification
| Mécanisme | Détail | Composant |
|---|---|---|
| Mots de passe | Argon2id, paramètres de coût fixés dans le code | hachage des mots de passe |
| Jeton d'accès | JWT signé HS256, algorithme verrouillé à la vérification ; durée 7 jours par défaut | extracteur d'authentification |
| Cookie de session | jwt, attribut HttpOnly ; en production SameSite=Strict, Secure et domaine fixé par COOKIE_DOMAIN | couche cookie |
| Second facteur | Application TOTP, ou code envoyé par e-mail à durée de vie courte ; imposé par défaut (FORCE_2FA) | connexion par mot de passe |
| Codes de secours | Codes à usage unique pour qui perd son authentificateur | codes de secours |
| SSO | Authentik, OIDC avec PKCE (code_challenge_method=S256) | client OIDC |
| Autorisation fine | Moteur Cedar, chargé depuis policies/. Absent ou invalide en posture de production : forge-api refuse de démarrer. En développement déclaré : Cedar désactivé, les gardes Cedar laissent passer | démarrage du serveur |
| Post-quantique | Option FORGE_PQC_ENABLED : le jeton porte une signature ML-DSA-65 en plus de HS256, pour les clients qui la vérifient | couche cookie, signature des jetons |
Le second facteur n'est pas réservé aux administrateurs : il s'applique à tous
les comptes tant que FORCE_2FA n'est pas désactivée.
Protection des requêtes
| Protection | Détail | Composant |
|---|---|---|
| CSRF | Double soumission : cookie csrf-token lisible par le frontend, copié dans l'en-tête x-csrf-token sur les écritures. Le jeton est aussi conservé 2 heures dans Valkey. Les routes d'avant connexion, /mcp et /webhooks en sont exemptées | couche CSRF |
| Débit général | Par IP : 100 requêtes par seconde sur /api/v1, 30 par minute pour les événements de route, 20 par minute pour le chat public, 1 000 par minute ailleurs. Réponse 429 avec Retry-After | limiteur de débit |
| Connexion, par compte | Au-delà d'un nombre d'échecs dans une fenêtre glissante, le compte est bloqué pour une durée fixée dans le code. L'identité est un hachage salé : l'e-mail en clair n'atteint pas Valkey. Sans ACCOUNT_HASH_SALT, ce limiteur est désactivé | limiteur par compte |
| Connexion, par IP | Seau large, secondaire. Une liste d'exemption existe pour lui seul | limiteur par adresse |
| Taille des corps | 2 Mio par défaut, 25 Mio pour l'envoi de fichiers ; 413 au-delà | limite de taille |
| En-têtes HTTP | X-Content-Type-Options, X-Frame-Options: DENY, Referrer-Policy, Permissions-Policy, Cross-Origin-Opener-Policy, Content-Security-Policy, et Strict-Transport-Security quand la requête est en HTTPS | en-têtes de sécurité |
| Métriques | /metrics refuse l'accès anonyme | métriques |
Chaque ligne nomme le composant du serveur qui porte la protection.
Chiffrement
En transit. Le proxy inverse du plan backend (Traefik) impose TLS 1.3
au minimum dans son option par défaut ; une option distincte, hors défaut,
autorise TLS 1.2 pour les clients anciens. En posture
production, la connexion de forge-api à PostgreSQL applique les paramètres
TLS de la configuration.
Au repos. Ce que le code chiffre :
- les secrets TOTP, les identifiants de connecteurs et les secrets SSO, en
AES-256-GCM, avec une clé dérivée par enregistrement depuis
AT_REST_ENCRYPTION_KEY; - les colonnes de données de santé, avec
PHI_AT_REST_KEY(crates/forge-db) ; - la chaîne d'audit, chaînée par empreintes et signée avec
AUDIT_SIGNING_KEY(crates/forge-audit).
Le dépôt n'établit pas de chiffrement transparent de PostgreSQL, de Qdrant ou de Valkey. Protégez le disque de l'hôte.
Intrusion et conteneurs
- Les services tournent sous Podman, sans Docker, avec des unités Quadlet utilisables sans droits administrateur.
- CrowdSec détecte les adresses abusives et prend des décisions de blocage. Le déploiement du plan backend l'installe.
- Falco (comportement à l'exécution) a une unité, retirée du déploiement depuis le 2026-09-19 en attendant une version compatible avec le noyau de l'hôte.
- Le contrôle mutuel par certificat (
ZERO_TRUST_ENABLED) est décrit comme une ébauche dans le code, prête pour une intégration mTLS complète. Ne le comptez pas comme une protection.
Chaîne d'approvisionnement
- Un workflow construit l'image backend, l'analyse avec Trivy (gravité HIGH et CRITICAL, correctifs disponibles seulement) et la signe avec Cosign par clé (workflow de CI du dépôt). Il est dormant : aucun exécuteur n'y est encore rattaché, il ne tourne pas aujourd'hui.
- Un script analyse les images référencées par les fichiers Compose, et un autre génère un SBOM
(
scripts/ops/generate-sbom.sh). Ils se lancent à la main.
Bonnes pratiques d'exploitation
- N'exposez jamais PostgreSQL, Qdrant, Valkey ni OpenBao sur Internet.
- Posez
ACCOUNT_HASH_SALT,AT_REST_ENCRYPTION_KEY,AUDIT_SIGNING_KEY,PHI_AT_REST_KEYetFORGE_STRICT_SECRETS(à1) en production. - Protégez
/metricsparPROMETHEUS_BEARER_TOKEN. - Gardez des permissions restreintes sur les fichiers d'environnement.
- Relisez les gabarits avant de coller une valeur réelle dans un ticket, un journal ou un message : ne publiez jamais de secret.
Signaler une vulnérabilité
Le serveur publie /.well-known/security.txt (crates/forge-api/src/router.rs). Écrivez à
security@chatbotaurus.com ; la divulgation coordonnée est décrite dans
Réponse aux incidents.
Documents juridiques
Le dossier docs/legal/ du dépôt contient les textes de référence : politique
de confidentialité, conditions d'utilisation, accord de traitement des données,
analyses d'impact, registre des traitements et attestation de résidence des
données.
Voir aussi
- Variables d'environnement — défauts et règles de chaque variable citée dans ce chapitre
- Architecture de confiance zéro — statut de chaque contrôle selon les sept principes NIST
- SSO Authentik — parcours OIDC, refus de connexion et second facteur
- Réponse aux incidents — divulgation coordonnée, sévérités et phases quand une protection cède
- Conformité RGPD — obligations que ces mécanismes techniques mettent en œuvre
Architecture de confiance zéro
Le zero trust tient en une phrase : aucune requête n'est crue sur sa seule provenance réseau. Ce chapitre décrit les principes retenus et les composants qui les portent. Il ne décrit pas la topologie réelle de l'hébergement : elle ne se publie pas. À la fin, vous saurez lire le statut de chaque contrôle (câblé, optionnel, prévu) et ce qui reste à votre charge.
Ce que ce chapitre affirme, et ce qu'il n'affirme pas
La grille de lecture est celle de la norme NIST SP 800-207, qui pose sept principes pour une architecture zero trust. C'est une grille, pas une certification : aucun organisme tiers n'a évalué Chatbotaurus contre ce référentiel.
Chaque ligne ci-dessous porte un statut :
- Câblé : le code existe et s'exécute par défaut.
- Optionnel : le code existe, un réglage de l'opérateur l'active.
- Prévu : une décision ou un chantier est tracé, rien n'est livré.
Identité : qui parle
| Contrôle | Statut | Détail |
|---|---|---|
| Jeton de session signé, algorithme épinglé | Câblé | Le serveur refuse un jeton dont l'algorithme n'est pas celui attendu. |
| Signature post-quantique du jeton (ML-DSA-65, FIPS 204) | Optionnel | Une seconde signature est ajoutée au jeton classique quand FORGE_PQC_ENABLED=1. Sans ce réglage, le jeton reste classique. |
| Canal hybride X25519 + ML-KEM-768 (FIPS 203) vers la passerelle MCP | Optionnel | Activé par FORGE_PQC_CHANNEL_ENABLED côté passerelle. |
| Second facteur (TOTP, WebAuthn, codes de secours) | Câblé | Par défaut (FORCE_2FA vaut true), la connexion par mot de passe exige un second facteur : TOTP si enrôlé, sinon code par courriel. L'obligation d'enrôler le TOTP par rôle est un réglage de déploiement : FORGE_MFA_REQUIRED_ROLES ou FORGE_MFA_TOTP_REQUIRED. Un compte créé par le SSO n'a pas de second facteur applicatif : Authentik le porte en amont. |
| Authentification fédérée (OIDC) | Câblé, avec repli | Voir le chapitre SSO Authentik. |
L'état réel des primitives cryptographiques se lit sur le point d'entrée GET /api/v1/crypto/status. Il répond selon l'environnement, jamais selon une affirmation figée.
Réseau : segmentation en deux plans
Le déploiement sépare deux plans, chacun dans son propre réseau de conteneurs :
- le plan de la plateforme (backend, base, coffre de secrets, observabilité) ;
- le plan des outils du client (passerelle et serveurs MCP).
Le principe : un compromis d'un plan ne donne pas un accès direct à l'autre. Le pont entre les deux peut être coupé pendant un incident. Les ports internes sont liés à la boucle locale de l'hôte ; sur le plan de la plateforme, seuls l'ingress et le service temps réel publient sur toutes les interfaces. Le détail des adresses, des ports et des règles n'est pas publié.
Un fichier de règles nftables existe pour le plan client. Son application effective sur chaque hôte relève de l'opérateur.
Application : ce que chaque requête traverse
La pile de couches du serveur API est documentée dans le code et verrouillée par un test. Dans l'ordre d'entrée :
- identifiant de requête ;
- en-têtes de sécurité ;
- détection d'énumération (blocage automatique de l'adresse) ;
- limiteur par compte, puis limiteur par adresse sur les chemins d'authentification ;
- vérification mTLS / SPIFFE, optionnelle ;
- refus des domaines de cloud hors UE (huit domaines) ;
- cloisonnement par organisation au niveau de la base (RLS PostgreSQL) ;
- limiteur de débit, jeton anti-CSRF, délai maximal par requête.
Figure 6 : les huit couches que traverse chaque requête avant le handler.
La couche mTLS est désactivée par défaut (ZERO_TRUST_ENABLED). Quand elle est active, elle n'accepte l'identité du client que si un proxy de confiance l'a posée (ZERO_TRUST_TRUST_PROXY) : sans cette précaution, un en-tête forgé suffirait. Elle est donc à ranger en Optionnel, pas en défense par défaut.
L'autorisation combine des rôles (RBAC) et des politiques Cedar. Les politiques sont lues dans policies/. En posture de production, l'absence ou l'invalidité de ces fichiers refuse le démarrage. Seule une posture de développement explicite tolère un moteur absent, et dans ce cas les gardes Cedar laissent passer. Les gardes Cedar sont appelées par handler : toutes les routes ne passent pas par elles.
Appareil : le conteneur
Un « appareil » est ici un conteneur Podman sans privilège.
- Le conteneur du backend s'exécute sans nouveaux privilèges, avec toutes les capacités retirées sauf celle de lier un port, une limite de processus et de mémoire, et un
/tmpen mémoire sans exécution. - Les images sont épinglées (tag, parfois empreinte).
- Un workflow analyse l'image du backend avec Trivy (gravité haute et critique) et la signe avec Cosign. Il est dormant : aucun exécuteur n'y est rattaché, il ne tourne pas aujourd'hui.
- Des profils seccomp et AppArmor sont maintenus dans le dépôt. Leur application sur chaque service n'est pas établie par le dépôt : ne pas la tenir pour acquise.
Données : classer et chiffrer
Le classificateur de données distingue cinq niveaux : public, interne, personnel, sensible (article 9 du RGPD) et restreint.
| Donnée | Protection |
|---|---|
| Identifiants de services externes | AES-256-GCM au repos, valeur jamais renvoyée (masquée en lecture) |
| Mots de passe | Argon2id |
| Secret TOTP | chiffré au repos |
| Journal d'audit | XChaCha20-Poly1305 sur le puits chiffré |
| Secrets de déploiement | sops + age, puis OpenBao à l'exécution (chapitre OpenBao et secrets) |
Le mode « compute » de la surface FHE est une enveloppe AES-256-GCM. Ce n'est pas du chiffrement homomorphe. Le chiffrement homomorphe est sur la feuille de route, pas dans le produit.
Visibilité : voir ce qui se passe
- Journal d'audit chaîné (SHA-256), vérifiable à la demande par un administrateur (
/audit/verify: 200 vérifiée, 409 rompue, 503 indéterminée). - Métriques de l'API au format Prometheus (
/metrics, accès protégé). VictoriaMetrics et VictoriaLogs existent dans le plan de développement ; aucune unité de production ne les déploie et rien ne les alimente par défaut. L'export de la chaîne d'audit vers VictoriaLogs est optionnel (FORGE_SIEM_ENABLED=1). - Beszel (supervision de l'hôte) et CrowdSec (blocage des adresses malveillantes en bordure) sont déployés par le plan de la plateforme.
- Falco (sécurité d'exécution) a une unité Quadlet, retirée du déploiement le 2026-09-19 : il n'est pas déployé. Les outils SIEM et IDS retirés (spec 98) ne font plus partie du plan.
- Il n'y a ni SIEM temps réel ni centre de supervision 24/7. L'émetteur SIEM du code est dormant.
Automatisation
- La rotation des secrets se fait par OpenBao, sur procédure opérateur. Il n'y a pas de rotation automatique des certificats mTLS livrée.
- Le révoquement d'un jeton compromis passe par une liste de refus des jetons.
- Les gardes du dépôt (gates) s'exécutent avant chaque commit : elles font échouer la livraison quand une exigence n'est plus tenue.
Lacunes assumées
- Pas de test d'intrusion indépendant à ce jour. Le modèle de menaces est un modèle de bureau, écrit par l'équipe qui a écrit le code.
- mTLS entre services : optionnel, désactivé par défaut.
- Application des profils seccomp / AppArmor : non démontrée par le dépôt.
- Pas de supervision humaine 24/7.
Voir aussi
- Modèle de menaces — actifs, frontières de confiance et menaces que ces contrôles doivent couvrir
- Réponse aux incidents — comment ces contrôles servent à détecter, confiner et notifier un incident
- OpenBao et secrets — les deux paliers de gestion des secrets et leur rotation
- SSO Authentik — authentification fédérée OIDC, repli par mot de passe et second facteur
- Conformité NIS2 — exigences de gestion des risques que cette architecture doit satisfaire
Modèle de menaces
Le modèle de menaces de Chatbotaurus part des menaces, pas des contrôles. La première version du programme de sécurité était partie d'un inventaire de ce qui existait. Le modèle STRIDE actuel part des actifs et des flux, puis note ce qui manque. À la fin, vous saurez quelles menaces sont couvertes, lesquelles ne le sont pas, et dans quel ordre se classent les risques résiduels.
Une honnêteté d'abord
Ce modèle a été écrit par l'équipe qui a écrit le code. Il ne peut pas se valider lui-même. C'est une hypothèse structurée sur l'emplacement du risque, à confirmer ou réfuter par un test d'intrusion indépendant. Ce test n'a pas eu lieu à ce jour.
Actifs, par ordre de criticité décroissante
| Actif | Pourquoi il compte |
|---|---|
| Données de santé et dossiers | catégorie particulière (article 9 du RGPD) |
| Secrets (connecteurs, base, clés de signature, clés d'API de modèles) | une fuite ouvre tout le reste |
| Données des clients et frontière entre organisations | l'isolation est le cœur du produit |
| Matériel d'authentification (jetons, TOTP, WebAuthn, clés d'API) | prise de compte |
| Intégrité du journal d'audit | preuve en cas d'incident |
| Entrées et sorties du modèle de langage | injection, fuite |
| Facturation et crédits | fraude |
| Sauvegardes et restauration | une fuite donne un dossier complet |
Frontières de confiance
Les flux traversent neuf frontières : Internet, bordure TLS, pile du serveur API, cerveau de l'agent, modèle de langage, connecteurs, recherche documentaire (RAG), stockage, et enfin les agents de sauvegarde. STRIDE est appliqué à chaque passage de frontière.
STRIDE sur les passages critiques
| Passage | Menace | Contrôle | État |
|---|---|---|---|
| Bordure vers API | Force brute sur les comptes | limiteur par compte et par adresse | câblé |
| Bordure vers API | Usurpation d'adresse par en-tête | l'en-tête du proxy n'est lu que si l'opérateur l'autorise | câblé |
| Bordure vers API | Clickjacking, XSS | en-têtes de sécurité | câblé |
| Bordure vers API | CSRF sur cookie | jeton anti-CSRF à double soumission | câblé |
| Bordure vers API | Requête lente | délai maximal par requête | câblé |
| Bordure vers API | Inondation distribuée, épuisement de connexions | traitement en bordure | lacune (opérateur) |
| Authentification | Jeton forgé | algorithme épinglé | câblé |
| Authentification | Attaque sur mot de passe | Argon2id | câblé |
| Autorisation | Escalade de privilèges | rôles et politiques Cedar | câblé |
| Autorisation | IDOR / BOLA (accès à la ressource d'une autre organisation) | gardes de handler et RLS PostgreSQL | partiel : non prouvé de façon adverse |
| Agent | Injection directe (anglais, français, unicode, base64) | filtre d'injection, heuristique | câblé |
| Agent | Action destructive lancée par le modèle | porte d'agence excessive : suppression et paiement exigent une approbation humaine | câblé |
| Agent | Injection indirecte (texte malveillant dans un document ou une sortie d'outil) | neutralisation du contenu non fiable avant retour dans l'invite | partiel (heuristique) |
| Agent | Paraphrase, multi-tours, homoglyphes | le filtre est une heuristique, pas un classificateur | lacune |
| Connecteurs | SSRF, y compris rebond DNS | vérification de l'adresse résolue, adresse épinglée | câblé |
| Connecteurs | Fuite de secret entre organisations | secrets résolus à la requête, par organisation | câblé |
| Retour du modèle | Fuite de l'invite système ou de données personnelles | analyse de sortie | câblé sur /prediction, lacune sur le flux du chat |
| Stockage | Injection SQL | requêtes paramétrées | câblé |
| Stockage | Altération du journal | chaîne de hachage, vérification à la demande | câblé |
| Stockage | Chiffrement des données de santé au repos | chiffrement applicatif des colonnes de santé (actif en production : PHI_AT_REST_KEY est obligatoire au démarrage), chiffrement de disque documenté | partiel : l'étendue sur toutes les données de santé n'est pas établie |
| Sauvegardes | Restauration forgée | URL signée à durée courte et approbation humaine | câblé |
| Sauvegardes | Image d'agent hors UE | image servie par un miroir UE, registres hors UE interdits par une garde | câblé |
Plusieurs connecteurs parlent en http:// à l'intérieur d'un même plan : c'est une décision documentée et acceptée. Elle est à rouvrir si un connecteur traverse un jour une frontière d'hôte.
Risques résiduels, par ordre
- Journal de lecture des données de santé incomplet : les lectures de l'agent sur l'ERP ne sont pas toutes tracées.
- Sortie du chat non analysée pour les données personnelles.
- IDOR non prouvé de façon adverse.
- Contrôles RGPD de santé à étendre : l'effacement et la rétention sont actifs par défaut pour les journaux vocaux et les comptes en attente de suppression, mais leur étendue sur le reste des données de santé reste à vérifier surface par surface.
- Déni de service au niveau applicatif, hors bordure.
- Aucune validation indépendante : test d'intrusion, certification d'hébergement de données de santé, supervision des incidents.
Menaces propres à l'IA
| Menace | Mitigation présente | Limite |
|---|---|---|
| Injection d'invite | filtre d'entrée, neutralisation du contenu récupéré | heuristique |
| Exfiltration par le modèle | analyse de sortie | partielle (voir ci-dessus) |
| Empoisonnement de modèle | somme SHA-256 des modèles comparée à une base épinglée | la signature du manifeste est réservée, jamais vérifiée |
| Usage non autorisé du modèle | authentification, limitation de débit | |
| Hallucination | mise en règle sur sources (grounding) | une réponse sans source est signalée, pas supprimée |
Acteurs
Opportunistes, concurrents, acteurs étatiques, personnel interne, militants : le modèle les considère tous, avec des capacités croissantes. Aucune de ces catégories n'est exclue de l'analyse.
Exercices
Des scénarios d'exercice sont prévus (fuite de données, menace interne, rançongiciel, chaîne d'approvisionnement). Le dépôt n'établit pas qu'ils ont été joués. La page publique du plan d'incident annonce un exercice sur table trimestriel : c'est un engagement, pas un historique.
Revue du modèle
Le modèle est repris après chaque incident (étape de retour d'expérience du plan d'incident). Une revue adverse du modèle lui-même a été faite en interne et a relevé des frontières omises, notamment les webhooks entrants.
Voir aussi
- Réponse aux incidents — la procédure déclenchée quand une de ces menaces se réalise
- Architecture de confiance zéro — statut câblé, optionnel ou prévu de chaque contrôle cité ici
- OpenBao et secrets — protection des secrets, second actif par ordre de criticité après les données de santé
- Sécurité — fichiers du code qui portent limiteurs, en-têtes et chiffrements
- Conformité RGPD — obligations sur les données de santé et les droits des personnes
Réponse aux incidents
Ce chapitre résume la procédure interne de réponse aux incidents de sécurité. Elle orchestre des mécanismes qui existent dans le code. Elle ne décrit pas une équipe de sécurité dédiée : il n'y en a pas. À la fin, vous saurez classer un incident, dans quel ordre agir et qui prévenir dans quels délais.
Portée et limites, dites d'abord
- Le projet est mené par une seule personne, appuyée par un délégué à la protection des données et un conseil juridique externes.
- Il n'y a pas de centre de supervision 24/7.
- Il n'y a pas de SIEM temps réel : l'émetteur SIEM du code est dormant.
- Falco (sécurité d'exécution) a une unité Quadlet, retirée du déploiement le 2026-09-19 : il n'est pas déployé. Les outils SIEM et IDS retirés (spec 98) ne font plus partie du plan.
- La détection repose donc sur la revue du journal d'audit, sur CrowdSec en bordure, sur les métriques de l'API (
/metrics), sur l'export optionnel de la chaîne d'audit vers VictoriaLogs, et sur la disponibilité humaine. Aucun agent du dépôt n'envoie les journaux des conteneurs vers un stockage central.
Le délai de détection est borné par cette disponibilité. C'est une limite assumée, pas une promesse.
Niveaux de sévérité
| Niveau | Définition | Exemple |
|---|---|---|
| SEV-1 critique | données de santé exposées ou exfiltrées, ou compromission d'un secret racine | fuite d'un dossier entre organisations, vol de clé |
| SEV-2 élevé | accès non autorisé sans exfiltration prouvée, ou indisponibilité d'un service de données de santé | accès à un contenu d'une autre organisation, déni de service |
| SEV-3 modéré | tentative bloquée par un contrôle, anomalie à instruire | injection refusée, limiteur déclenché |
| SEV-4 faible | bruit ou faux positif | balayage opportuniste bloqué |
Une violation touchant des données de santé (article 9 du RGPD) est classée SEV-1 jusqu'à preuve du contraire.
Les délais de réponse que l'entreprise s'engage à tenir envers ses clients sont publiés sur la page publique du plan de réponse aux incidents. Ce chapitre ne les reprend pas : une seule source évite qu'ils divergent.
Phases
La procédure suit cinq phases, de la préparation au retour d'expérience.
Figure 7 : les cinq phases de la réponse à incident.
1. Préparation
Ce qui est en place et à maintenir :
- journal d'audit chaîné par empreintes : toute altération est détectable, et l'intégrité se vérifie à la demande ;
- journal des lectures de dossiers patients ;
- gel des opérations irréversibles : suppression et paiement exigent une approbation humaine ;
- contrôle des rôles dans le chat ;
- gardes d'injection d'invite et de sortie ;
- secrets : sops + age au socle, OpenBao à l'exécution quand
BAO_ADDRest défini, avec une procédure de rotation ; - deux plans réseau séparés et isolables ;
- modèle de menaces tenu à jour.
Garder aussi sous la main : les contacts du délégué à la protection des données et de l'autorité nationale, et un canal de communication hors de l'infrastructure potentiellement compromise.
2. Détection et analyse
Sources : le journal d'audit (échecs de validation de jeton, jetons révoqués rejetés, refus de rôles, opérations destructives bloquées), la réputation d'adresses, les compteurs du limiteur d'authentification dans Valkey, les alertes de CrowdSec, les signalements de réponses non sourcées.
Triage, dans l'ordre :
- confirmer que ce n'est pas un faux positif ;
- classer la sévérité ;
- horodater le début : cette heure déclenche les délais légaux ;
- préserver les preuves ;
- délimiter le périmètre : quelle organisation, quelles données sensibles, quel secret.
Pendant un incident, ne pas purger le journal d'audit. Suspendre les balayages de rétention tant que l'enquête est ouverte : RETENTION_SWEEP_ENABLED=0 (journaux vocaux) et BACKUP_RETENTION_SWEEP_ENABLED=0 (travaux de sauvegarde terminés). ACCOUNT_PURGE_ENABLED=0 suspend l'effacement définitif des comptes en attente ; il suspend une obligation d'effacement, donc la décision se prend avec le délégué à la protection des données.
3. Confinement
L'objectif est d'arrêter la propagation sans détruire les preuves.
- Jeton compromis : l'inscrire sur la liste de refus, forcer une nouvelle authentification, désactiver le compte si besoin.
- Secret compromis : le révoquer et le renouveler dans OpenBao. Pour la clé de chiffrement des données de santé au repos, une procédure de rotation sans interruption existe.
- Service compromis ou déni de service : isoler le plan concerné en coupant le pont entre les deux plans ; s'appuyer sur les limiteurs et les délais déjà en place.
- Abus de l'agent : les opérations irréversibles sont déjà bloquées. En incident, passer la passerelle concernée en lecture seule ou suspendre l'organisation.
- Adresse hostile : la bloquer en bordure.
À ne pas faire : effacer les journaux, « nettoyer » la base, redéployer par-dessus les preuves.
4. Éradication et reprise
- Retirer l'accès de l'attaquant : clés renouvelées, sessions fermées, comptes compromis désactivés.
- Corriger la cause racine, avec un test de non-régression.
- Vérifier l'intégrité de l'image des conteneurs et des modèles (sommes de contrôle épinglées).
- Restaurer depuis des sauvegardes saines. Vérifier que la chaîne d'audit n'est pas rompue.
- Si des données personnelles sont touchées, déclencher l'effacement ou la rectification requis.
- Surveillance renforcée temporaire, puis réactivation des balayages de rétention suspendus.
La restauration depuis les sauvegardes a des procédures exercées par moteur de base. Un exercice de restauration de production n'a pas encore été fait : il est bloqué sur une ressource (voir le chapitre NIS2).
5. Notification et retour d'expérience
| Destinataire | Délai | Base |
|---|---|---|
| Autorité de protection des données | 72 heures après la prise de connaissance | RGPD, article 33 (à vérifier sur le texte officiel) |
| Personnes concernées | sans retard injustifié, si risque élevé | RGPD, article 34 (à vérifier sur le texte officiel) |
| Autorité nationale de cybersécurité | alerte précoce 24 heures, notification 72 heures, rapport final un mois | NIS2, article 23 (à vérifier sur le texte officiel) |
Les textes officiels sont liés dans Conformité RGPD et Conformité NIS2. Le calendrier NIS2 s'applique aux entités essentielles et importantes. Selon son propre dossier de conformité, Chatbotaurus n'est pas, par sa taille, dans ce champ. Il suit ce calendrier parce que ses clients régulés l'exigent de leur chaîne d'approvisionnement.
La décision de notifier revient au délégué à la protection des données et au conseil. La procédure fournit les faits, pas la qualification juridique. Le référentiel interne classe d'ailleurs la notification aux autorités dans les délais comme un processus encore à formaliser.
Après chaque incident : compte rendu écrit (cause racine, chronologie, ce qui a marché et manqué), mise à jour du modèle de menaces, test adverse ajouté pour verrouiller la régression.
Signaler une vulnérabilité
Une politique de divulgation coordonnée est publiée :
- adresse de signalement :
security@chatbotaurus.com; - fichier
/.well-known/security.txt(RFC 9116), valable jusqu'au 17 août 2027 ; - avis de sécurité au format CSAF, et inventaire logiciel (SBOM, CycloneDX).
Exercices
Des scénarios sont prévus : fuite de données, menace interne, rançongiciel, chaîne d'approvisionnement. La page publique annonce des exercices réguliers. Le dépôt ne contient pas de compte rendu d'exercice joué : c'est un engagement, pas un historique.
Voir aussi
- Modèle de menaces — les actifs et menaces que cette procédure est faite pour couvrir
- OpenBao et secrets — révocation et rotation des secrets pendant la phase de confinement
- Conformité NIS2 — calendrier de notification et limites assumées du dossier NIS2
- Conformité RGPD — notification des violations aux autorités et aux personnes concernées
- SLA, support et niveaux de service — communication des incidents et reprise, du côté des engagements clients
SSO Authentik
Authentik (licence permissive, auto-hébergé) est le fournisseur d'identité de l'opérateur. L'application s'y connecte en OpenID Connect avec le flux à code d'autorisation et PKCE. Un mot de passe avec second facteur reste le repli quand le SSO n'est pas configuré.
Ce qui est en place
| Élément | Détail |
|---|---|
| Fournisseur | Authentik, service du plan de la plateforme |
| Protocole | OIDC, flux à code d'autorisation, PKCE, state et nonce |
| État de session de connexion | stocké dans Valkey, 10 minutes |
| Jeton de session applicatif | émis par l'application après la connexion, en cookie |
| Repli | si la configuration SSO est absente, la route répond 503 SSO_UNAVAILABLE et l'interface retombe sur mot de passe plus second facteur |
| IdP national luxembourgeois | un second fournisseur est prévu sur le même callback, comme point d'entrée pour l'espace européen de données de santé. C'est un échafaudage, qui exige une configuration et un client enregistré |
Parcours de connexion
GET /api/v1/auth/oidc/login: l'application génèrestate, vérifieur PKCE etnonce, les place dans Valkey, puis redirige vers Authentik.- L'utilisateur s'authentifie chez Authentik.
GET /api/v1/auth/oidc/callback: l'application relit l'état, échange le code, et refuse la connexion dans les cas suivants :- état expiré ou inconnu ;
noncedu jeton d'identité absent ou différent (protection contre le rejeu) ;- adresse courriel non vérifiée par le fournisseur (
email_verified), sauf option explicite de l'opérateur (OIDC_ALLOW_UNVERIFIED_EMAIL=1) ; - adresse déjà utilisée par un compte local créé avec un mot de passe. Un compte fédéré ne s'attache jamais en silence à un compte local : c'est la parade contre la prise de compte par SSO.
- Sinon, l'application trouve ou crée l'utilisateur local, émet son jeton et redirige vers le tableau de bord.
Chaque échec est écrit au journal d'audit, avec un code d'erreur.
Figure 8 : le parcours de connexion SSO par OpenID Connect, avec ses quatre cas de refus.
Configuration de l'application
Le SSO est actif quand ces variables d'environnement sont définies :
AUTHENTIK_SERVER_URLAUTHENTIK_CLIENT_IDAUTHENTIK_CLIENT_SECRETAUTHENTIK_REDIRECT_URI(le défaut est une adresse de développement : posez-la en production)
Avant de poser ces variables, créez dans Authentik un fournisseur OAuth2/OIDC et
l'application qui l'utilise : l'identifiant et le secret du client alimentent
AUTHENTIK_CLIENT_ID et AUTHENTIK_CLIENT_SECRET, AUTHENTIK_SERVER_URL est l'adresse du
serveur Authentik, et l'URL de retour enregistrée chez Authentik doit être exactement la
valeur de AUTHENTIK_REDIRECT_URI, qui se termine par la route de retour
/api/v1/auth/oidc/callback. Le serveur demande les portées openid, profile et email :
le fournisseur doit les accorder. Les écrans d'Authentik dépendent de sa version et ne sont
pas décrits ici.
Résultat attendu : GET /api/v1/auth/oidc/login répond par une redirection vers Authentik.
Une réponse 503 SSO_UNAVAILABLE signifie que AUTHENTIK_SERVER_URL, AUTHENTIK_CLIENT_ID
ou AUTHENTIK_CLIENT_SECRET manque ; l'interface retombe alors sur le mot de passe et le
second facteur.
Les valeurs de secrets ne se placent pas dans le dépôt. Elles suivent la chaîne décrite dans le chapitre OpenBao et secrets.
Second facteur
Par défaut, FORCE_2FA vaut true : la connexion par mot de passe exige un second facteur, code TOTP si le compte l'a enrôlé, sinon code envoyé par courriel. L'obligation d'enrôler le TOTP est, elle, un réglage de déploiement :
FORGE_MFA_REQUIRED_ROLESexige l'enrôlement TOTP pour les rôles listés (par exempleadmin,owner) ;FORGE_MFA_TOTP_REQUIREDl'exige pour tous les comptes.
Un compte soumis à l'obligation et sans TOTP actif se voit refuser la connexion jusqu'à son enrôlement. Les mécanismes disponibles sont TOTP, WebAuthn et des codes de secours. Si l'opérateur n'a posé aucun des deux réglages, rien n'oblige un rôle particulier au TOTP, et le code par courriel reste exigé tant que FORCE_2FA n'est pas désactivée. Un compte créé par le parcours SSO ci-dessus n'a pas de second facteur applicatif (commentaire du code : « Authentik handles MFA upstream ») : l'authentification multifacteur de ces comptes relève de la configuration d'Authentik.
Autres services du plan client
Plusieurs outils du plan client (par exemple Grafana, Forgejo, Mattermost) peuvent être reliés à Authentik. Chaque outil se configure selon ses propres capacités :
- OIDC natif quand l'outil le supporte : application et fournisseur OAuth2/OIDC dans Authentik, URI de redirection côté outil.
- Proxy d'authentification quand il ne le supporte pas : Authentik fournit un point d'entrée de type outpost. Une unité Quadlet
authentik-proxyexiste dans le dépôt.
Le dépôt ne recense pas, service par service, lequel est relié à Authentik en production. Cette liste relève de l'opérateur du plan.
Points d'attention
- Le SSO de l'application ne dépend pas du proxy frontal : la redirection OIDC est gérée par le serveur API lui-même. La configuration du proxy d'entrée (Caddy et Traefik ont chacun des fichiers dans le dépôt) ne change pas ce parcours.
- Si l'IdP n'émet pas
email_verified, ne pas contourner la vérification sans en mesurer le risque. - Le jeton de session est classique par défaut. Une signature post-quantique ML-DSA-65 s'y ajoute quand
FORGE_PQC_ENABLED=1.
Voir aussi
- Architecture de confiance zéro — place de l'identité fédérée parmi les sept principes retenus
- OpenBao et secrets — où vivent le secret du client OIDC et les autres secrets
- Connecteur Authentik — piloter Authentik par le protocole MCP depuis la passerelle
- Variables d'environnement — toutes les variables d'authentification lues par le backend
- Paramètres — où l'utilisateur active son second facteur et le SSO
OpenBao et secrets
Aucun secret n'est enregistré en clair dans le dépôt, ne se loge dans une réponse d'API ni dans un journal. La gestion des secrets suit deux paliers. Le premier est le socle, le second est le coffre du profil régulé. À la fin, vous saurez où vit chaque secret, quand OpenBao s'applique et ce qui reste à votre charge (initialisation du coffre, rotation).
Pourquoi OpenBao
Le coffre de secrets précédent était sous licence BSL, incompatible avec le plan de la plateforme, qui exige des licences permissives. Il a été retiré (décision DEC-34-008). Son remplaçant est OpenBao (MPL-2.0, Linux Foundation). Les variables de configuration portent le préfixe natif BAO_*. OpenBao est le coffre actuel du palier régulé.
Deux paliers
| Palier | Mécanisme | Quand |
|---|---|---|
| 1. Socle | sops + age : secrets chiffrés, versionnés, déchiffrés vers l'environnement au déploiement | toujours ; fonctionne sans serveur, y compris hors ligne |
| 2. Coffre à l'exécution | OpenBao : lecture des secrets au démarrage et à la demande | dès que BAO_ADDR est défini |
Quand OpenBao est configuré, chaque secret présent dans le coffre remplace la valeur issue de l'environnement. Un secret absent garde sa valeur d'environnement. Une erreur réelle du coffre (injoignable, authentification refusée) arrête le démarrage : un déploiement régulé ne doit pas démarrer en silence sur des valeurs périmées.
Si BAO_AUDIT_REQUIRED est vrai et qu'aucun journal d'audit n'est actif côté coffre, le démarrage est refusé. L'audit de lecture des secrets est une exigence NIS2 et DORA pour le profil régulé.
Le coffre
OpenBao est défini aux deux niveaux du dépôt : service du plan de la plateforme et unité Quadlet de production (stockage Raft persistant, TLS, journal d'audit déclaratif, conteneur sans privilège, publication sur l'interface locale seulement).
Le coffre ne s'amorce pas lui-même. Son initialisation, la répartition des clés de descellement et l'ensemencement suivent un guide d'exploitation exécuté par le titulaire. Cette cérémonie est une procédure humaine.
Secrets de base gérés par le recouvrement : clé de signature des jetons, mot de passe de la base, URL de connexion à la base, mot de passe SMTP, clé d'API de la base vectorielle, mot de passe de Valkey.
Secrets des clients et des connecteurs
- Les identifiants de services externes saisis par un client sont chiffrés au repos en AES-256-GCM. La valeur n'est jamais renvoyée : l'API ne retourne qu'une valeur masquée.
- Les secrets d'un connecteur sont résolus à la requête, par organisation, et n'existent en mémoire que le temps de l'appel. Il n'y a pas de cache de secrets à auditer.
- Pour le domaine de santé, la résolution passe par OpenBao.
Rotation
- Les secrets du coffre se renouvellent selon le guide d'exploitation. Pour la clé de chiffrement des données de santé au repos, une procédure sans interruption existe : l'ancienne clé reste disponible en lecture le temps du changement.
- Après une rotation, le serveur relit ses secrets au redémarrage.
- Un identifiant client se remplace par l'API des identifiants, par l'utilisateur concerné.
Bonnes pratiques
- Aucun secret dans le code source, les images, les journaux ni les réponses d'API.
- Des journaux caviardés pour les valeurs sensibles.
- Un secret par usage et par organisation.
- Activer l'audit de lecture du coffre en profil régulé.
- Ne jamais coller une valeur de secret dans un ticket, un message ou un document.
Lacunes assumées
- Le recouvrement par OpenBao concerne les six secrets de base listés plus haut. Il n'est pas un coffre pour tout.
- La clé maître des agents de sauvegarde est protégée par une enveloppe AES-256-GCM adossée à la racine des jetons. Sa migration vers sops + age ou OpenBao est tracée, pas finie.
- Le chiffrement applicatif des données de santé au repos est actif en production :
PHI_AT_REST_KEYdoit être fournie, sinon le démarrage est refusé. Il couvre les colonnes qui passent parphi_crypto; l'étendue sur toutes les données de santé n'est pas établie par le dépôt. Le chiffrement du disque reste documenté comme palier de fond.
Voir aussi
- Architecture de confiance zéro — classification des données et protections au repos, contrôle par contrôle
- Réponse aux incidents — révoquer et renouveler un secret compromis pendant le confinement
- Sécurité — clés de durcissement, chiffrement et contrôles au démarrage, fichier par fichier
- Variables d'environnement — variables du coffre et clés de durcissement lues par le backend
- Conformité NIS2 — exigences de cryptographie et d'audit du profil régulé
Contribuer
Ce guide s'adresse à l'équipe interne et aux partenaires qui développent sur la base de code avec l'accord du titulaire.
À la fin de ce chapitre, vous aurez construit le workspace, lancé le backend et le frontend en local, et vous saurez quelles règles les hooks appliquent avant un commit.
Cadre
Chatbotaurus est un logiciel propriétaire. Le fichier LICENSE (identifiant
SPDX LicenseRef-Chatbotaurus-Proprietary) n'accorde aucun droit d'usage, de
copie, de modification ou de distribution sans accord écrit. Les dépendances
tierces gardent leur propre licence. Une contribution suppose donc un accord
écrit préalable ; la voie de soumission (patch, demande de fusion) est convenue
avec le titulaire.
Le code est en Rust : aucune dépendance à Node.js ni à pnpm.
Prérequis
| Outil | Version | Source |
|---|---|---|
| Rust | 1.91 au minimum (rust-version du workspace), édition 2021 | Cargo.toml |
dioxus-cli (dx) | 0.7.x | cargo install dioxus-cli --locked |
Cible wasm32-unknown-unknown | pour le frontend web | rustup target add wasm32-unknown-unknown |
| Git | récent | |
| Python 3 | exigé par les hooks pre-commit | |
| Un shell POSIX | exigé par les hooks | Git Bash ou WSL sous Windows |
| Podman | pour l'infrastructure locale | podman-compose, avec un tiret |
Le pre-commit lance de nombreux contrôles (.githooks/pre-commit). Sous Windows, vérifiez que python
répond dans le shell du hook avant le premier commit.
Obtenir les sources et activer les hooks
git clone <url-du-depot-communiquee-par-le-titulaire>
cd <dossier-du-depot>
git config core.hooksPath .githooks
Les hooks sont versionnés avec le code (.githooks/). Le chemin ci-dessus les
active ; sans lui, aucune règle n'est appliquée localement. Ne contournez jamais
un hook avec --no-verify : si un hook échoue, corrigez la cause.
Construire et lancer
cargo build --workspace
La première construction est longue ; les suivantes sont incrémentales.
Le backend a besoin au minimum de DATABASE_URL, REDIS_URL et JWT_SECRET
(voir Variables d'environnement). PostgreSQL et Valkey
doivent tourner d'abord : créez les réseaux et les volumes, puis lancez
podman-compose -p chatbotaurus-vps1 up -d postgres valkey (voir
Déploiement avec Podman). Lancez ensuite le backend depuis
la racine du dépôt, pour qu'il retrouve .env, connectors/ et policies/ :
cargo run -p forge-api
Résultat attendu : forge-api écoute sur le port 3000 par défaut (variable PORT) et
curl -s http://localhost:3000/api/v1/healthz répond 200. Sinon, relisez la sortie du
processus et suivez Problèmes connus.
Le frontend Dioxus se sert avec rechargement à chaud :
cd crates/forge-ui
dx serve --platform web --port 8080
Résultat attendu : l'application répond sur http://localhost:8080.
Vérifier
cargo check --workspace
cargo clippy --workspace
cargo fmt --all
cargo test -p <crate>
Le dépôt fige le style de rustfmt dans rustfmt.toml. Le workflow de CI
(workflow de CI du dépôt) épingle un nightly daté pour cargo check et
pour cargo fmt --check. Comme les autres workflows de CI du dépôt, il est
dormant : aucun exécuteur n'y est rattaché. Les contrôles qui tournent
aujourd'hui sont les hooks locaux.
Branche, commit et push
Le développement se fait sur la seule branche main. Le hook pre-push
refuse tout push d'une autre branche, refuse un push dont cargo check --workspace échoue, et laisse passer les étiquettes.
Un message de commit suit le modèle type(portée): résumé, par exemple
fix(forge-api): corriger un délai. Les types courants sont feat, fix,
docs, refactor, test, chore. Le hook ne l'impose pas : c'est la
convention du dépôt. Faites un commit par sujet, avec des chemins explicites
(git add <fichier>), jamais git add ..
Les règles que les hooks appliquent
| Règle | Ce qu'elle refuse | Où |
|---|---|---|
| L1 | Le mot « parity » (ou « parité ») dans un message sans pied de page Parity-Test: #<identifiant> | commit-msg |
| L2 | Un fichier .rs de plus de 300 lignes significatives (les lignes vides, les accolades seules et les commentaires seuls ne comptent pas). Une exception demande une entrée justifiée dans scripts/pre-commit/loc-exemptions.txt | pre-commit |
| L3 | Une valeur métier écrite en dur dans crates/forge-ui/src/pages/*.rs | pre-commit |
| L6 | Une branche qui touche des fichiers hors de son domaine (par exemple docs/* ne touche que la documentation) | pre-commit |
| L8 | Un fichier neuf de forge-ui absent de docs/parity/PARITY_REGISTRY.yaml | pre-commit |
Le pre-commit applique aussi, entre autres : aucun emoji dans les fichiers
texte, cloisonnement par organisation des handlers de liste (une exception
s'annote // TENANT-AUDIT: <raison>), aucun fichier .env ajouté hors le
modèle, aucun secret en clair (analyse avant chaque commit), et la règle d'auteur
unique du message (commit-msg). La liste complète et les raisons sont dans
docs/parity/HOOKS.md du dépôt.
Règles de code
- Pas de refactorisation dans un commit de portage : un refactor est un commit séparé.
- Pas de donnée factice inventée dans une page : les pages lisent l'API.
- Composez avec les crates existantes avant d'en créer une.
- Les composants
forge-uiutilisent#[component]de Dioxus 0.7. - Une route de liste filtre par organisation, ou porte une exception annotée et justifiée.
Règles de sécurité
- Aucun secret dans le dépôt, dans un message de commit ni dans une
documentation. Utilisez des gabarits
<...>. Aucune adresse IP ni nom d'hôte interne dans ce livre. - TLS par
rustls: le workspace évite OpenSSL. - Chiffrement symétrique :
aes-gcm. Mots de passe : Argon2id. - Podman, pas Docker, pour toute infrastructure locale.
- Un connecteur doit déclarer une résidence des données dans l'UE ou auto-hébergée, sinon le registre le rejette.
- Transport MCP : HTTP « streamable » par
rmcp.
Structure du dépôt
Le workspace compte 19 crates suivis par git au 2026-10-03 (git show HEAD:Cargo.toml, bloc members) ; crates/docsite est exclu.
| Crate | Rôle |
|---|---|
forge-core | Logique métier : agents, RAG, workflows, garde anti-hallucination |
forge-api | Serveur HTTP Axum : REST, transport MCP, WebSocket |
forge-ui | Interface Dioxus 0.7 : web, bureau, mobile |
forge-auth | Authentification, OIDC, TOTP, politiques Cedar |
forge-db | Entités SeaORM, migrations, requêtes |
forge-mcp | Cœur de la passerelle MCP : connecteurs, routage, sessions |
forge-gateway | Serveur passerelle MCP conteneurisable (JSON-RPC en HTTP « streamable ») |
forge-audit | Journal d'audit à altération détectable, chaîne de Merkle |
forge-voice | Voix : transcription, synthèse, WebRTC, fournisseurs de l'UE |
forge-cli, forge-tui, forge-ops | Outils en ligne de commande et terminal |
forge-docs | Pipeline mdBook de ce livre |
forge-wire, forge-common | Contrats et primitives partagés |
forge-replay, forge-test-utils, forge-pgtest | Rejeu de contrats et outils de test |
forge-oracle | Banc de comparaison différentielle V1/V2 |
| extraction documentaire | crate prévu (spec 115, T-115-50), non encore suivi dans le dépôt |
Autres dossiers utiles : connectors/ (manifestes des connecteurs),
containers/ (unités Quadlet), podman-compose.yml et
podman-compose.vps2.yml (plans locaux), policies/ (règles Cedar),
scripts/pre-commit/ et scripts/audit/ (les gates), .kiro/specs/ (les
spécifications), docs/ (notes du dépôt).
Les chiffres du projet (crates, lignes, connecteurs) changent : mesurez-les avec
python scripts/audit/launch_readiness.py plutôt que de les recopier.
Documentation
Les pages de ce livre vivent dans crates/forge-docs/docs/. Pour insérer une
image ou une vidéo, voir
Rédaction des pages et médias. Reconstruction :
cargo run -p forge-docs.
Contact
Pour proposer une contribution, écrivez à admin@chatbotaurus.com avant de commencer.
Voir aussi
- Fichiers de configuration — les fichiers que le backend attend à la racine du dépôt
- Sécurité — protections du code que chaque contribution doit préserver
- Rédaction des pages et médias — insérer une image, une animation ou une vidéo dans ce livre
- Architecture Chatbotaurus — rôle de chaque crate et pile technique du workspace
- Déploiement avec Podman — démarrer l'infrastructure locale avec les deux plans Compose
Rédaction des pages et médias
Ce guide s'adresse à qui écrit ou relit une page de ce livre. Il décrit comment insérer une image vectorielle, une animation SVG ou une vidéo, avec les classes CSS que le livre fournit. Lisez d'abord le guide de contribution.
Le livre est produit par mdBook. mdBook laisse passer le HTML brut du Markdown
sans l'échapper : les balises <figure>, <svg>, <video> et <iframe> ne
demandent aucun plugin.
Où vivent les fichiers
| Dossier | Contenu |
|---|---|
crates/forge-docs/docs/static/img/ | Images des pages : SVG, PNG. Servi sous /docs/static/img/ |
crates/forge-docs/docs/assets/ | Feuilles de style et scripts du livre : media.css, charte.css, theme-icon.js, fr.js (francisation des libellés que mdBook écrit depuis ses scripts), recherche-fr.js (accents repliés et mots vides français dans la recherche) |
crates/forge-docs/docs/<rubrique>/ | Les pages Markdown |
book.toml charge media.css et charte.css (clé additional-css) et
theme-icon.js, fr.js et recherche-fr.js (clé additional-js). mdBook copie dans le livre tous les
fichiers non Markdown du dossier docs/.
Les chemins s'écrivent relativement à la page. Depuis une page de
docs/guides/, une image de docs/static/img/ s'écrit
../static/img/<fichier>. Depuis docs/quickstart.md, elle s'écrit
./static/img/<fichier>.
Le livre n'impose pas d'image d'en-tête : aucune page n'en porte aujourd'hui (aucun
fichier page-* dans static/img/).
Pour reconstruire et relire le livre :
cargo run -p forge-docs
Résultat attendu : la commande se termine sans erreur mdBook, et le livre construit se
lit ensuite sous /docs/ du serveur de développement du frontend (dx serve, port 8080).
Images SVG statiques
Exportez le schéma depuis votre outil vectoriel et retirez les métadonnées
inutiles (par exemple avec SVGO). Insérez-le dans
un <figure> de classe media-svg : media.css borne la largeur à 720 px,
centre la figure et style la légende.
<figure class="media-svg">
<img
src="../static/img/<nom-du-schema>.svg"
alt="<description du contenu du schéma pour un lecteur d'écran>"
loading="lazy"
/>
<figcaption>Légende courte.</figcaption>
</figure>
L'attribut alt est obligatoire et décrit le contenu : « schéma » ou « image »
ne décrivent rien. loading="lazy" diffère le chargement jusqu'à ce que
l'image approche du cadre visible.
Animations SVG inline
Une animation SVG s'écrit dans le Markdown, entre deux lignes vides, à
l'intérieur d'un <figure class="media-svg">. Deux techniques existent :
- CSS (
@keyframes) : portable, et la seule quemedia.cssneutralise. Quand le lecteur demande moins de mouvement (prefers-reduced-motion: reduce), la feuille met en pause les animations et les transitions des SVG de la classemedia-svg. - SMIL (
<animate>,<animateTransform>) : autonome, maismedia.cssne l'arrête pas. Si vous l'utilisez, ajoutez votre propre règle@media (prefers-reduced-motion: reduce)dans le SVG.
Une animation longue ou coûteuse se range dans un fichier .svg séparé de
static/img/, inséré comme image statique.
Vidéos
Le livre vise à ne charger aucune ressource tierce : c'est un objectif en cours. Une vidéo hébergée chez un tiers l'enfreint. Choisissez dans cet ordre.
1. Vidéo courte hébergée avec le livre
Pour une vidéo de moins de 30 secondes, déposez un fichier WebM (VP9) dans
static/img/ ou un sous-dossier, et lisez-le avec la balise <video>. Aucun
tiers n'est contacté. Le prix : la taille du dépôt augmente. N'y mettez pas de
vidéo longue.
<div class="media-video">
<video controls preload="metadata" poster="../static/img/<affiche>.png">
<source src="../static/img/<video>.webm" type="video/webm" />
<track kind="captions" src="../static/img/<video>.fr.vtt"
srclang="fr" label="Français" default />
Votre navigateur ne sait pas lire les vidéos HTML5 :
<a href="../static/img/<video>.webm">téléchargez la vidéo</a>.
</video>
</div>
Aucune vidéo n'est aujourd'hui stockée dans le dépôt (mesure du 2026-10-03 :
git ls-files crates/forge-docs/docs | grep -Ei '\.(webm|mp4)$' ne rend
rien).
2. Instance PeerTube européenne
PeerTube, plateforme fédérée, expose un lecteur à l'adresse
https://<instance>/videos/embed/<identifiant>. Choisissez une instance dont
vous maîtrisez l'hébergement et la juridiction.
3. Plateformes hors UE
YouTube et Vimeo sont des services hors UE. Réservez-les aux cas où aucune
alternative n'existe, et dites-le dans la revue. Pour YouTube, utilisez le
domaine youtube-nocookie.com, qui limite le dépôt de cookies avant la lecture ;
cela réduit le suivi, ce n'est pas une garantie juridique, à valider avec votre
délégué à la protection des données.
<div class="media-video">
<iframe
src="https://www.youtube-nocookie.com/embed/<identifiant-video>"
title="<titre descriptif de la vidéo>"
loading="lazy"
allowfullscreen
referrerpolicy="strict-origin-when-cross-origin"
></iframe>
</div>
media.css donne au conteneur media-video un ratio 16:9 et une largeur
maximale de 860 px. L'attribut title est obligatoire : il donne un nom à
l'iframe pour les lecteurs d'écran. N'ajoutez jamais autoplay=1 : la feuille
entoure d'un liseré orange les vidéos qui démarrent seules pour que la revue
l'attrape.
Liste de contrôle avant revue
- Chaque image a un
altnon vide et descriptif. - Chaque
<iframe>a untitle. - Les chemins sont relatifs à la page et le livre se construit sans erreur
(
cargo run -p forge-docs). - Une animation respecte
prefers-reduced-motion. - Une vidéo avec parole a des sous-titres WebVTT en français. Le référentiel d'accessibilité des services numériques est la norme européenne EN 301 549.
- Aucune vidéo n'utilise
autoplay. - Aucun secret, aucune adresse IP, aucun nom d'hôte interne n'apparaît dans une image, une légende ou un sous-titre : le livre est public.
Aucun script de lint Markdown n'est livré avec le dépôt pour le moment : la vérification est la revue humaine.
Voir aussi
- Contribuer — cadre, hooks et règles de sécurité appliqués à toute contribution
- Fichiers de configuration — le fichier de réglages lu par mdBook pour ce livre
- Conformité RGPD — absence de script ou cookie tiers, mesure d'audience auto-hébergée
- Gaia-X — résidence des contenus et refus des ressources hors UE
- Sécurité — pourquoi aucun secret ni nom d'hôte interne ne doit paraître
Questions fréquentes
Cette page répond aux questions courantes. Chaque chiffre porte sa date de mesure : le 3 octobre 2026. Ce qui est prévu est dit « prévu ».
Questions générales
Ce que la plateforme est, ce qu'elle coûte et ce qu'elle protège.
Qu'est-ce que Chatbotaurus ?
Chatbotaurus est une plateforme de passerelle MCP hébergée (MGaaS, « MCP Gateway as a Service », voir Glossaire). Elle relie un assistant conversationnel à vos outils métier, par exemple un ERP, un CRM ou un outil d'analyse. Les modèles d'IA tournent sur l'infrastructure de la plateforme, dans l'Union européenne.
Pour un dirigeant, c'est un assistant qui agit dans vos logiciels. Pour un développeur, c'est une passerelle qui parle le protocole MCP (version 2025-03-26), avec une API REST (voir Documentation Swagger).
Au 3 octobre 2026 :
- 195 fiches de connecteurs YAML ;
- 175 cartes de serveurs dans l'application, dont 30 prouvées opérationnelles ; le catalogue public compte 108 entrées, dont 15 disponibles ;
- 711 outils au registre Odoo ;
- 16 secteurs métier couverts (voir Cas d'usage par secteur).
Est-ce gratuit ?
Un essai gratuit de 14 jours est prévu aux conditions générales de vente. Il est sans engagement et sans carte bancaire. Il donne accès à l'ensemble des fonctionnalités de l'offre Pro. À ce jour le code ne l'applique pas : une inscription reçoit le plan « free », puis le niveau « essentiel » à la fin de l'assistant d'accueil (voir Tarification).
Les offres payantes sont facturées hors taxes, par mois :
| Offre | Prix | Public visé |
|---|---|---|
| Starter | 9 EUR | TPE, indépendants |
| Pro | 29,90 EUR | PME |
| Enterprise | 99,90 EUR | ETI, institutions |
| Souverain | Sur devis | Banques, État |
Le détail est dans la page Tarification.
Les données sont-elles protégées ?
La plateforme est conçue pour répondre au RGPD, à la directive NIS2, à l'AI Act et au cadre Gaia-X. Elle ne détient aucune certification à ce jour. Le détail et l'état de chaque démarche sont dans la section Conformité UE.
Côté technique :
- les secrets et mots de passe sont chiffrés (AES-256-GCM au repos, Argon2id pour les mots de passe) ;
- le transport utilise TLS 1.3 ;
- les secrets des déploiements régulés sont gérés par OpenBao.
Pour aller plus loin, lisez Zero Trust et OpenBao et secrets.
Quelles langues sont prises en charge ?
| Élément | Langues |
|---|---|
| Interface | français et anglais (jeux complets) |
| Voix (reconnaissance) | français, anglais, allemand, espagnol, italien, néerlandais, portugais (7 langues) |
| Traduction | EuroLLM, qui couvre les 24 langues de l'Union européenne |
D'autres langues d'interface (allemand, espagnol, italien, luxembourgeois, néerlandais) n'ont qu'un squelette de 26 clés. Elles ne sont pas complètes. Seuls le français, l'anglais, le néerlandais et l'allemand sont proposés dans l'assistant d'accueil et dans la page Compte (voir Paramètres et Limites).
Questions techniques
Connexion, workflows, protocole et données : les questions d'un intégrateur.
Comment me connecter ?
Pas encore de compte ? Créez-le sur /auth/signup (voir Prise en main guidée). Sinon, ouvrez la page de connexion, saisissez votre adresse et votre mot de passe. L'authentification en deux étapes (TOTP et courriel) est disponible (voir Paramètres). Le SSO passe par Authentik en OIDC ; l'ajout de fournisseurs SAML ou LDAP est en cours d'intégration. Voir SSO Authentik.
Comment ajouter un collègue ?
Ouvrez la page Utilisateurs (/users, section Gestion du menu, à partir du plan Business) et utilisez « Ajouter un utilisateur » : courriel, nom, rôle, statut. Les rôles sont décrits dans Paramètres.
Comment appeler l'API ?
Joignez le jeton obtenu par la connexion. Une clé API créée dans la page /api-keys n'est acceptée par aucune route aujourd'hui. Voir Authentification et Sécurité et identifiants.
Mon workflow ne fonctionne pas
Vérifiez dans cet ordre :
- Le workflow est-il enregistré et publié ?
- Les identifiants du connecteur sont-ils saisis et valides (voir Sécurité et identifiants) ?
- Le serveur ou le service connecté répond-il ?
- Que disent les journaux d'exécution (page Exécutions) ?
Si une action répond 429, vous avez atteint une limite de débit : attendez et réessayez (voir Limites). Si elle répond 402, le quota de votre offre est atteint. Si elle répond 503, la plateforme n'a pas pu mesurer votre quota ou la fonction n'est pas encore câblée. Le format des erreurs est expliqué dans Gestion des erreurs. Le reste est dans Problèmes connus.
Qu'est-ce que MCP ?
MCP signifie Model Context Protocol. C'est un protocole ouvert qui permet à un modèle d'IA d'appeler des outils externes. Chatbotaurus implémente la spécification 2025-03-26, avec le transport Streamable HTTP et JSON-RPC 2.0. L'ancien transport SSE n'est plus utilisé. Le transport est décrit dans Routes MCP.
Qu'est-ce qu'un workflow ?
Un workflow est un graphe de nœuds que vous assemblez dans l'éditeur visuel : un point de départ, des appels à des serveurs MCP, des conditions, des boucles, une fin. Dans l'API, on l'appelle aussi une « gateway ». Voir Workflows.
Où sont mes données ?
| Donnée | Stockage |
|---|---|
| Base relationnelle | PostgreSQL |
| Vecteurs (recherche sémantique) | Qdrant |
| Cache | Valkey |
| Secrets des déploiements régulés | OpenBao |
| Modèles d'IA | exécutés par la plateforme (Ollama), dans l'UE |
Aucun appel n'est fait vers un fournisseur extra-européen sans votre consentement explicite. Les services sont décrits dans Déploiement avec Podman. Le cadre juridique est dans Conformité RGPD.
Quels modèles d'IA sont utilisés ?
Le modèle principal est EuroLLM 1,7B. Le repli est ministral-3:3b, de Mistral AI (France). Les vecteurs viennent de paraphrase-multilingual-MiniLM-L12-v2 (384 dimensions). Ces trois modèles (Fournisseurs de modèles) sont la liste fermée de la plateforme (mesure du 3 octobre 2026).
Le choix du connecteur, lui, ne dépend pas du modèle : le routage du chat est déterministe (EntityRouter).
Comment connecter Odoo ?
- Ouvrez la page Identifiants (
/credentials) de votre espace de travail ; elle est dans le menu à partir du plan Business. - Ajoutez un identifiant Odoo : URL de l'instance et clé API.
- Enregistrez-le.
- Posez une question métier dans le chat, par exemple « Combien de contacts dans le CRM ? » (même exemple que dans la prise en main guidée).
- Utilisez cet identifiant dans vos workflows.
Le connecteur expose 711 outils au registre Odoo. Tutoriel : Connecter Odoo à la passerelle MCP.
Puis-je déployer un serveur du catalogue en un clic ?
Pas encore. Les routes de déploiement, de démarrage, d'arrêt et de configuration des secrets sont montées, mais elles répondent 503 FEATURE_PENDING. Elles attendent le câblage du socket Podman (spec 16, tâche P5.5, non cochée). Voir Parcourir le catalogue de services et préparer un déploiement.
Questions sur le positionnement
Pourquoi cette plateforme plutôt qu'une autre famille d'offres.
Pourquoi pas une offre SaaS d'IA hors UE ?
Une offre SaaS hébergée hors de l'Union relève d'une autre juridiction pour vos données. Chatbotaurus héberge et exécute ses modèles dans l'UE. À l'exécution, la plateforme refuse en outre les identifiants de serveur de 25 services hors UE (liste de refus) et ne route que vers les serveurs de sa liste autorisée (voir Conception des connecteurs MCP).
Ce n'est pas un chatbot généraliste : c'est une passerelle vers vos outils métier. La comparaison point par point est dans Comparatifs.
Puis-je migrer depuis un autre outil d'automatisation ?
Oui, à la main. Il n'existe pas d'import automatique. La page Migration donne les équivalences de concepts.
Questions hors sujet
Le chat de support répond aux questions sur la plateforme. Il ne tient pas de conversation libre sans contexte métier. Pour une question générale, utilisez un assistant généraliste. Le périmètre complet est dans Limites.
Voir aussi
- Glossaire — chaque terme employé ici, défini en une ligne.
- Problèmes connus — les pannes recensées et leur contournement.
- Limites et ce que la plateforme ne fait pas — débit, quotas, langues, limites de l'IA.
- Prise en main guidée — le parcours complet, du compte au premier workflow.
- SLA, support et niveaux de service — à qui écrire, et dans quel délai on vous répond.
Glossaire
Ce glossaire définit les termes employés par la plateforme et par ce livre. Les définitions sont courtes. Les chiffres portent la date de leur mesure : le 3 octobre 2026.
A
API REST
Interface qui permet à un autre logiciel de parler à la plateforme. Elle vit sous /api/v1. Un accès trop rapide répond 429 (voir Limites). Référence : Routes MCP.
Argon2id
Algorithme de hachage de mots de passe. Il rend le mot de passe stocké irréversible. Voir Sécurité.
Authentik
Fournisseur d'identité libre et auto-hébergé. La plateforme s'y connecte en OpenID Connect pour la connexion unique (SSO) ; un mot de passe avec second facteur reste le repli quand il n'est pas configuré. Voir SSO Authentik.
C
Catalogue (serveurs)
Liste des serveurs MCP proposés par la plateforme : 175 cartes dans l'application, dont 30 prouvées opérationnelles ; le catalogue public compte 108 entrées, dont 15 disponibles. Les autres sont en cours d'intégration. Le déploiement en un clic depuis le catalogue est prévu, pas livré (voir FAQ).
Cedar
Moteur de politiques d'autorisation. Une partie des règles d'accès (par exemple celles de la section Agence) est écrite comme des politiques ; le reste des gardes vit dans le code des routes. Voir Architecture de confiance zéro.
Compute-mode
Traitement de données sensibles avec chiffrement AES-256-GCM côté serveur. Ce n'est pas du chiffrement homomorphe : le chiffrement homomorphe n'est pas implémenté. Voir Comparatifs.
Connecteur
Fiche YAML (connectors/*.yaml) qui décrit comment joindre un outil : identifiant, URL de base, authentification, outils exposés. Il y en a 195. Voir Vue d'ensemble des connecteurs.
CRM
Gestion de la relation client : suivi des prospects et des clients. La page Leads de l'application en donne une vue (voir Analytique) ; le CRM complet vit dans l'outil connecté, par exemple Odoo.
D
Document store
Collection vectorielle (Qdrant) cloisonnée par organisation, utilisée pour la recherche sémantique. L'identifiant du store sert de nom de collection. Voir Routes des ressources.
E
Embedding (plongement vectoriel)
Représentation d'un texte par une liste de nombres. Le modèle est paraphrase-multilingual-MiniLM-L12-v2, qui produit 384 dimensions. Les vecteurs sont stockés dans Qdrant. Voir Connaissances.
EntityRouter
Routeur déterministe du chat. Il décide quel connecteur répond à une demande à partir de règles, pas à partir d'un modèle d'IA. Une même demande suit donc toujours le même chemin. Voir Chat.
Espace de travail (workspace)
Espace qui regroupe vos workflows, vos identifiants et vos données. Les données sont cloisonnées par organisation. Dans l'interface, la page /workspaces liste ces espaces. Voir Paramètres.
EuroLLM
Modèle de langue européen. La plateforme emploie EuroLLM 1,7B (quantifié q8) comme modèle principal, et pour la traduction entre les langues de l'UE. Il n'appelle pas d'outils : le routage reste celui d'EntityRouter. Voir Fournisseurs de modèles.
G
Gaia-X
Initiative européenne pour un espace de données fédéré. La plateforme s'y aligne par auto-évaluation. Elle ne détient pas de certification. Voir Gaia-X.
Gateway
Objet de l'API (ressource gateways) qui porte un workflow : son graphe, ses connecteurs activés, ses règles d'accès. C'est un assistant conversationnel qui peut être publié pour un usage public. Il est limité à l'espace de travail de son propriétaire. Dans l'API, on dit aussi « gateway » pour un workflow. À ne pas confondre avec la passerelle MCP, qui est le service hébergé. Voir Routes des gateways et de la prédiction.
I
Identifiants (credentials)
URL, identifiant et clé API que vous saisissez pour que la plateforme joigne un de vos outils. Ils sont chiffrés au repos. Voir Sécurité et identifiants.
J
Jeton (JWT)
Preuve de connexion que l'API attend dans l'en-tête Authorization: Bearer. Il s'obtient par la connexion. Voir Authentification.
JSON-RPC 2.0
Format de message du protocole MCP : un identifiant, une méthode, des paramètres. Voir Routes MCP.
K
Kit Numérique
Nom commercial de l'offre : « un Kit Numérique adapté à chaque étape de votre croissance ». C'est le même produit que Chatbotaurus. Voir Tarification et offres.
L
Locataire (organisation)
Organisation cliente de la plateforme. Ses données, ses identifiants et ses espaces de travail sont cloisonnés de ceux des autres. Voir Architecture Chatbotaurus.
M
MCP (Model Context Protocol)
Protocole ouvert qui permet à un modèle d'IA d'appeler des outils externes (voir Utiliser les connecteurs MCP). La plateforme implémente la version 2025-03-26.
MGaaS
« MCP Gateway as a Service » : la passerelle MCP hébergée que propose Chatbotaurus. Voir Architecture Chatbotaurus.
ministral-3:3b
Modèle de repli de la plateforme, de Mistral AI (France), voir Fournisseurs de modèles. Il remplace le modèle de repli précédent depuis le 10 août 2026.
N
NIS2
Directive européenne sur la sécurité des réseaux et des systèmes d'information. La plateforme est conçue pour y répondre, sans certification. Voir NIS2.
Nœud
Élément d'un workflow : départ, appel à un serveur MCP, condition, boucle, routage, parallèle, agrégation, fin. Le catalogue des nœuds est dans Workflows.
O
Odoo
ERP open source. Le connecteur Odoo expose 711 outils au registre. Voir Odoo.
Offre
Formule commerciale publiée sur la page Tarifs : un public visé, un prix et ce qu'elle inclut. À ne pas confondre avec le plan, qui est le niveau d'accès. Voir Tarification et offres.
OIDC
OpenID Connect : protocole standard de connexion unique, utilisé par le bouton « Authentik SSO ». Voir SSO Authentik.
OKF (wiki)
Format du wiki de connaissances : une page Markdown avec un en-tête YAML dont le champ type est obligatoire. L'identifiant d'une page est son chemin. Une page sans type est rejetée. Voir Connaissances.
Ollama
Serveur d'inférence qui exécute les modèles de langue de la plateforme. Voir Fournisseurs de modèles.
OpenBao
Coffre de secrets libre, sous licence MPL-2.0. Il sert aux déploiements régulés. Voir OpenBao et secrets.
Orchestrateur
Page de l'interface, dans la section « Écosystème MCP », où un assistant construit vos workflows par le dialogue. Voir MCP et Orchestrateur.
Organisation
Entité cliente de la plateforme et unité de cloisonnement : le filtre de locataire repose sur l'organisation. Le livre dit aussi « locataire » pour la même chose. Voir Architecture Chatbotaurus.
P
Passerelle MCP
Le service hébergé qui relie un assistant conversationnel à vos outils métier par le protocole MCP, avec une API REST. À ne pas confondre avec une « gateway », objet de l'API. Voir Architecture Chatbotaurus.
Plan
Niveau d'accès d'un compte : il décide des pages visibles dans le menu et des capacités disponibles, et chaque plan supérieur garde les capacités des précédents. L'interface dit « plan » (Plan actuel, Changer de plan). Dans les chapitres Podman, « plan » désigne aussi l'un des deux projets de déploiement. Voir Tarification et offres.
Plan (offre)
Niveau d'abonnement. La table des capacités compte six niveaux : Essentiel, Starter, Pro, Business, Enterprise, Souverain ; la grille de prix n'en publie que quatre. Voir Tarification et offres.
Podman
Moteur de conteneurs sans démon. Il fait tourner les services de la plateforme. Voir Déploiement avec Podman.
PQC (cryptographie post-quantique)
Algorithmes résistants à un ordinateur quantique. La plateforme propose ML-KEM-768 pour un canal hybride, en option. Il n'est pas actif par défaut. Voir Comparatifs.
Q
Qdrant
Base de données vectorielle. Elle sert à la recherche sémantique (RAG). Voir Connaissances.
Quadlet
Mode de déploiement de production : un fichier containers/<service>/<service>.container par service. En développement, le déploiement passe par Compose. Voir Déploiement avec Podman.
Quota
Plafond d'une ressource par offre (workflows, serveurs MCP, appels d'API, stockage, utilisateurs, minutes de voix, enregistrements vectoriels). Un quota atteint répond 402. Voir Limites.
R
RAG (Retrieval-Augmented Generation)
Technique où l'assistant cherche d'abord dans vos documents, puis répond en s'appuyant sur ce qu'il a trouvé. Cela réduit les erreurs, sans les supprimer. Voir Limites.
RGPD
Règlement général sur la protection des données. La plateforme est conçue pour y répondre. Voir RGPD.
RLS
Cloisonnement par organisation appliqué au niveau de la base PostgreSQL sur certaines tables seulement (appels, messages de gateway, sessions de l'Orchestrateur, journaux vocaux, entre autres), en plus des gardes des routes. Voir Architecture de confiance zéro.
S
SBOM
Inventaire des composants logiciels d'une image de conteneur, produit lors de l'analyse de sécurité. Voir Déploiement avec Podman.
Serveur MCP
Service qui expose des outils à l'assistant par le protocole MCP. Voir MCP et Orchestrateur.
SLA
Objectif contractuel de service sur les environnements de production sous contrat. Ce n'est pas une garantie sans condition. Voir SLA, support et niveaux de service.
SMTP
Protocole d'envoi de courriel. Le serveur SMTP que vous configurez envoie le code du second facteur. Voir Installation.
SSO
Connexion unique : se connecter avec le compte d'un fournisseur d'identité (ici Authentik) plutôt qu'avec un mot de passe propre à la plateforme. Voir Paramètres.
Streamable HTTP
Transport MCP de la plateforme : requêtes HTTP vers un point d'entrée unique, messages JSON-RPC 2.0. Il remplace l'ancien transport SSE, qui n'est plus utilisé. Voir Routes MCP.
STT et TTS
Reconnaissance vocale (STT, de la voix vers le texte) et synthèse vocale (TTS, du texte vers la voix). Voir Voix et Canaux.
T
TLS
Chiffrement du transport entre le navigateur ou le client d'API et le serveur. Voir Sécurité.
TOTP
Code à usage unique renouvelé par une application d'authentification, utilisé comme second facteur. Voir Paramètres.
Trivy
Scanner de vulnérabilités pour les images de conteneur. Voir Sécurité.
V
Valkey
Fork libre de Redis. Il sert de cache. Voir Gestion des conteneurs.
W
Webhook
Adresse que la plateforme appelle pour signaler un événement. L'envoi de test est réel ; l'émission automatique des événements n'est pas branchée. Voir Sécurité et identifiants.
Workflow
Graphe de nœuds qui automatise un processus. Voir Workflows.
Workspace
Voir « Espace de travail ». Dans les chapitres de développement, le mot désigne aussi le workspace Cargo : l'ensemble des crates déclarés par le Cargo.toml de la racine. Voir Architecture Chatbotaurus.
X
XML-RPC
Protocole d'appel à distance que le connecteur Odoo utilise pour joindre le serveur Odoo. Voir Odoo.
Z
Zero trust
Principe de sécurité : aucune requête n'est crue sur sa seule provenance réseau. Voir Architecture de confiance zéro.
Voir aussi
- Questions fréquentes — les mêmes notions, sous forme de questions et de réponses.
- Architecture Chatbotaurus — comment ces briques s'assemblent.
- Connecteurs MCP — connecteurs, catalogue et serveurs MCP, mesurés.
- Migration depuis d'autres outils — les équivalences de concepts avec d'autres outils.
Migration depuis d'autres outils
Ce guide aide à refaire vos automatisations existantes dans Chatbotaurus. La migration se fait à la main : il n'existe pas d'import automatique de flux venus d'un autre outil. Les noms de nœuds ci-dessous sont ceux du catalogue de l'éditeur de workflows, état au 3 octobre 2026.
Avant de commencer
Une plateforme hébergée dans l'UE refuse certains services (voir Conception des connecteurs MCP). À l'exécution, les identifiants de serveur de 25 services hors UE (messagerie, stockage, automatisation en ligne, hébergeurs cloud, paiement) sont refusés, et seuls les serveurs de la liste autorisée sont appelés. Une automatisation qui dépend d'un de ces services doit donc passer par un équivalent européen.
Équivalences de concepts
Les termes de l'outil d'origine varient. La colonne de gauche donne le concept, quel que soit le nom qu'il porte chez eux.
| Concept dans l'outil d'origine | Dans Chatbotaurus |
|---|---|
| Automatisation complète (scénario, flux) | workflow, appelé aussi gateway |
| Déclencheur | nœud MCP Start ; MCP Webhook Trigger pour un appel HTTP entrant |
| Action sur un service | nœud connecteur (par exemple Odoo Connector ou n8n Connector), ou tâche {serverId, query} dans MCP Parallel |
| Filtre, condition | MCP Condition |
| Chemins multiples | MCP Router |
| Itération sur une liste | MCP Loop |
| Regroupement de résultats | MCP Aggregator (stratégies merge, first, vote) |
| Exécution en parallèle | MCP Parallel |
| Reprise sur erreur | MCP Retry, MCP Fallback |
| Validation humaine | MCP Approval |
| Appel à un modèle d'IA | MCP LLM |
| Fin du flux | MCP End |
Ce qui n'a pas d'équivalent
- Code personnalisé. Les nœuds « fonction personnalisée » et « fonction si/sinon » (JavaScript) sont refusés à l'exécution : la plateforme n'exécute pas de JavaScript dans un workflow (voir Limites).
- Nœud « outil » seul. Le nœud
mcpToolNoden'est pas exécutable dans un graphe. Appelez l'outil par une tâche{serverId, query}dans MCP Parallel. - Transformation et état. Les nœuds de transformation et d'état de l'ancien moteur ne s'exécutent pas non plus.
Remplacer un service hors UE
La plateforme tient une table de remplacement. Voici des exemples de correspondances (21 services y figurent au total) :
| Besoin | Équivalents européens connus |
|---|---|
| Messagerie d'équipe | Mattermost, Rocket.Chat, Element |
| Visioconférence | Jitsi |
| Mesure d'audience | Matomo, Plausible |
| CRM | Odoo |
| Courriel marketing | Listmonk, Mautic |
| Documents partagés | CryptPad, OnlyOffice |
| Agenda | CalRS |
| Hébergement de code | Forgejo |
| Support client | Zammad |
| Moteur de recherche interne | Typesense |
| Stockage de fichiers | Nextcloud |
| Formation en ligne | Moodle, Chamilo |
Chaque équivalent est une fiche de connecteur du dépôt. La liste complète est dans Vue d'ensemble des connecteurs.
Étapes
- Inventaire. Listez toutes les automatisations actives.
- Priorité. Commencez par les automatisations simples.
- Correspondance. Pour chaque automatisation, notez le déclencheur, les actions et les conditions, puis trouvez le nœud équivalent.
- Identifiants. Recréez les identifiants dans la section Sécurité (Sécurité et identifiants).
- Recréation. Construisez le workflow dans l'éditeur (Workflows).
- Essai. Testez chaque workflow depuis le Chat avant de le publier.
- Parallèle. Faites tourner l'ancien et le nouveau côte à côte, le temps de comparer les résultats.
- Bascule. Désactivez l'ancien outil une fois la comparaison satisfaisante.
- Nettoyage. Fermez les comptes devenus inutiles.
Coexister avec n8n
Si vous utilisez déjà n8n, vous pouvez le garder. Le connecteur n8n de la plateforme liste, crée et active des workflows n8n, et lit leurs exécutions, depuis un workflow Chatbotaurus. Vous migrez ensuite les flux un par un, à votre rythme. Voir n8n.
Combien de temps ?
Il n'y a pas d'estimation chiffrée fiable : la durée dépend du nombre de services connectés et de la complexité des conditions. Mesurez-la sur la première automatisation que vous migrez, puis extrapolez.
Besoin d'aide ?
Écrivez à contact@chatbotaurus.com. Les délais de réponse sont dans SLA, support et niveaux de service. Le déploiement assisté de vos outils est une option de l'offre Pro (voir Tarification).
Voir aussi
- Workflows — la palette de nœuds citée dans les équivalences.
- Comparatifs — pourquoi migrer vers une passerelle hébergée dans l'UE.
- Connecteurs MCP — les fiches de connecteurs qui remplacent vos services.
- Connecteur n8n — garder n8n et migrer les flux un par un.
- Prise en main guidée — créer le premier workflow après la migration.