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