MCP to MCP : automatiser un export comptable de bout en bout entre Spendesk et un ERP
Deux façons de relier Spendesk à un système comptable avec un agent : quand les deux côtés parlent MCP (Spendesk ↔ Rillet), et quand l'autre système n'en a pas encore (Spendesk ↔ NetSuite). Avec, en clôture, un état des lieux des ERP clients Spendesk qui ont déjà un MCP en 2026.

Le problème
Faire parler Spendesk et un système comptable tiers, jusqu'ici, ça passait presque toujours par une plateforme d'intégration (un iPaaS type Chift) posée entre les deux — quelqu'un construit et maintient un connecteur dédié, pour chaque paire d'outils.
Avec le Model Context Protocol, une autre option apparaît : un agent qui appelle directement les outils MCP de chaque système, sans connecteur au milieu. Deux cas très différents se présentent selon que le système en face a, ou n'a pas, son propre serveur MCP — et les deux existent aujourd'hui, testés en conditions réelles.
Qu'est-ce que le MCP-to-MCP ?
Le MCP-to-MCP désigne une intégration où un agent IA connecte directement les serveurs MCP de deux logiciels différents — ici Spendesk et Rillet — sans plateforme d'intégration (iPaaS) au milieu. Chaque système reste responsable de son propre MCP ; l'agent se contente d'appeler les outils des deux côtés et de garantir que rien n'est créé en double.
Pourquoi ça compte, pour une équipe finance
Pas besoin de comprendre OAuth ou JWT pour saisir l'essentiel. Aujourd'hui, faire parler deux logiciels financiers coûte souvent plusieurs semaines de projet d'intégration, un abonnement à une plateforme tierce, et un connecteur à maintenir dans la durée. Avec un agent qui appelle directement les MCP de chaque système :
- Pas de projet d'intégration à lancer — un agent orchestre l'échange, pas une équipe technique qui code un connecteur sur mesure.
- Rien à souscrire en plus — aucune plateforme d'intégration tierce entre les deux systèmes.
- Traçabilité native — chaque écriture porte une référence vers son origine Spendesk, consultable à tout moment.
- Le contrôle humain reste entier — un rapport détaille exactement ce qui a été fait à chaque exécution, et une seule action manuelle (marquer comme exporté dans Spendesk) referme la boucle.
La suite de l'article détaille le fonctionnement technique — utile si vous êtes intégrateur ou partenaire technique. Si vous êtes côté finance, l'essentiel est ci-dessus.
MCP-to-MCP : Spendesk et Rillet se parlent directement
Le cas le plus propre : les deux systèmes exposent un MCP, et un agent (ici Claude, en routine planifiée) orchestre l'échange entre les deux, sans code d'intégration à maintenir de part ou d'autre. Ce que demandent le plus souvent les clients : exporter les payables vers Rillet dès qu'ils sont prêts, sans attendre le règlement — la réconciliation des settlements vient ensuite, dans un second temps, à son propre rythme.
Côté Spendesk (MCP) — lecture uniquement (voir les outils d'écriture à venir pour ce qui reste aujourd'hui hors MCP) :
get_payables— les payables prêts à exporter (bookkeepingStatus = toExport)get_payable_attachments— pour enrichir un fournisseur à la création (IBAN, adresse) via sa factureget_settlements— les settlements réglés, réconciliés dans un second tempsget_payable_by_id— pour retrouver, lors de la réconciliation, le payable associé à un settlement
Côté Rillet (MCP) — lecture et écriture :
- Recherche de vendor par
external_reference, puis par nom - Création ou mise à jour de vendor
- Création de vendor bill (idempotente)
- Recherche d'une bill déjà exportée par référence, puis création du bill payment
Le principe qui rend tout ça fiable, c'est l'idempotence par référence externe : chaque objet Rillet créé porte une external_reference qui pointe vers l'identifiant Spendesk d'origine ({ "type": "spendesk", "id": "<supplierId>" } pour un vendor, <payableId> pour une bill). À chaque exécution, l'agent vérifie cette référence avant de créer quoi que ce soit — pas de table de correspondance locale à maintenir, l'idempotence vit nativement dans les deux systèmes.
Le flux, en deux phases découplées

Phase 1 — Exporter les payables, dès qu'ils sont prêts
- Payables prêts — récupérer les payables dont
bookkeepingStatus = toExport, sans attendre le règlement. - Vérification du codage (à venir) — avant de créer la bill, vérifier que le compte GL, le centre de coût et le taux de TVA du payable sont plausibles. Aujourd'hui, une anomalie est seulement signalée dans le rapport ; demain, avec
update_payableen production (voir les outils à venir), elle pourrait être corrigée directement sur le payable avant l'export. - Vendor dans Rillet — recherche en 3 niveaux : par référence externe (arrêt si trouvé) → par nom (ajout de la référence externe si trouvé) → création (avec enrichissement via la pièce jointe et une recherche web pour la TVA/l'adresse si nécessaire).
- Vendor bill — vérifier l'absence de référence externe existante, puis créer avec le montant net, la TVA si applicable, et le compte résolu par mapping de catégorie.
Phase 2 — Réconcilier les settlements, dans un second temps
- Settlements réglés — récupérer les settlements soldés, sans lien de calendrier avec le moment où le payable a été exporté.
- Payable associé — remonter au payable via
allocations[0].payableId, pour retrouver la bill déjà exportée. - Bill déjà exportée — la retrouver dans Rillet via sa référence externe — jamais recréée.
- Bill payment — enregistrer le paiement (montant brut, date, méthode, référence Spendesk).
Un seul rapport peut consolider les deux phases, mais elles tournent indépendamment : un settlement peut se réconcilier des heures, voire des jours, après l'export de son payable.
Le mapping catégories → comptes
Un exemple concret de ce qu'un client doit fournir pour adapter le skill à son propre plan de comptes :
| Catégorie Spendesk | Compte |
|---|---|
| Outils et abonnements | 60212 |
| Serveurs et outils COGS | 50220 |
| Salaires | 60110 |
| Services — Paie | 60120 |
| Avantages & bien-être / CSE / RH / Formation | 60130 |
| Prestataires, freelances, salaires externalisés | 60190 |
| Espace de travail — loyer, entretien | 60211 |
| Marketing (ABM, paid, événements, PR, contenu sponsorisé) | 60213 |
| Voyages et notes de frais (T&E) / dépenses personnelles | 60214 |
| Espace de travail — fournitures, onboarding, snacks | 60215 |
| Agence, conseil, recrutement, marque employeur | 60216 |
| Services — assurance | 60220 |
| Frais bancaires, KYB | 60221 |
| Résultat financier | 60222 |
| Impôts et taxes | 60223 |
| Catégorie inconnue ou absente | 60216 (compte par défaut) |
Phase 1 illustrée : exporter les payables
⚠️ Les échanges ci-dessous sont un exemple illustratif type (chiffres non réels), à la différence de la section NetSuite plus bas qui cite des résultats réellement obtenus.
9 payables trouvés avec `bookkeepingStatus = toExport`. 2 étaient déjà exportés (référence externe déjà présente sur leur fournisseur/bill) — ignorés.
Vérification d'idempotence : aucune des 7 bills restantes n'existait déjà côté Rillet — 7 créations.
Je crée maintenant les 7 bills.
# Rapport Spendesk → Rillet — Export payables — 26/07/2026
## Résumé
| Indicateur | Valeur |
|---|---|
| Payables traités | 9 |
| Payables déjà exportés (ignorés) | 2 |
| Vendors créés | 1 |
| Vendors trouvés par référence externe | 5 |
| Vendors trouvés par nom (+ référence ajoutée) | 1 |
| Bills créées | 7 |
| Anomalies de codage détectées | 1 |
| Erreurs | 0 |
| Montant net total exporté | 4 218,50 € |
## ⚠️ Anomalies
Rapport complet disponible dans le fichier généré.

Phase 2 illustrée : réconcilier les settlements
Un second run, découplé du premier et lancé à son propre rythme, réconcilie les settlements déjà réglés — sans jamais recréer une bill :
7 settlements réglés le 26/07/2026. Pour chacun, le payable associé était déjà exporté vers Rillet en Phase 1 (référence externe trouvée) — aucune nouvelle bill créée.
Aucune anomalie : chaque settlement correspondait à une bill déjà exportée.
Et côté NetSuite, quand il n'y a pas de MCP ?
Le même principe (un agent qui orchestre, aucune plateforme d'intégration au milieu) fonctionne aussi quand l'autre système n'a pas de MCP — sauf qu'à la place d'appeler un MCP en face, l'agent parle directement à l'API du système, via un client construit pour l'occasion.
C'est le cas d'un second skill, construit pour tester si cette approche généralise à un ERP structurellement différent : Spendesk MCP d'un côté (lecture), un client REST NetSuite construit sur mesure de l'autre (OAuth 2.0 client-credentials, JWT signé en ES256, appels SuiteTalk REST). Contrairement au cas Rillet, il n'y a pas de référence externe native des deux côtés — le skill maintient sa propre table de correspondance locale (mapping/suppliers.json, mapping/cost_centres.json) pour assurer l'idempotence.
Ce skill est réellement en production contre un sandbox NetSuite (tstdrv2793048) — pas une simulation :
- Une facture fournisseur réelle a été postée (n° 32754), avec le bon fournisseur, le bon département résolu depuis le centre de coût Spendesk, et le bon compte GL résolu depuis l'
externalIddu compte Spendesk. - Une note de frais employé réelle a été exportée comme Expense Report NetSuite (n° 32854, "Candy Myers", ligne "202 6121 Travel Expenses") — pas comme une facture fournisseur contre un vendor inventé.
Deux gotchas NetSuite découverts en conditions réelles, qui montrent bien pourquoi cette étape de découverte-par-client est nécessaire (rien de générique ne les aurait prédits) :
- Sur ce compte, les champs
departmentetclassdoivent être renseignés à la fois sur l'en-tête ET sur chaque ligne de facture — les renseigner uniquement sur la ligne échoue, même avec un code de TVA par ailleurs valide. location, à l'inverse, ne nécessite que le niveau ligne — la même dimension analytique n'a pas la même exigence de placement selon le champ.
⚠️ Ce skill n'a pour l'instant été prouvé que sur un compte de test (sandbox), pas sur le compte réel d'un client — et sa variante Sage X3 (construite en second, pour tester la généralisation) n'a, elle, jamais dépassé le mode simulation : ses appels d'écriture réels sont explicitement des stubs non implémentés.
Analyse : les ERP des clients Spendesk ont-ils déjà un MCP ?
Spendesk propose aujourd'hui des intégrations comptables natives avec NetSuite, Xero, QuickBooks Online, Microsoft Business Central, Odoo, Exact Online, DATEV, Sage 100, ACD et Pennylane (bientôt). Voici, système par système, si le flux "MCP-to-MCP" décrit plus haut est déjà possible aujourd'hui, ou s'il faut encore passer par une API classique comme pour NetSuite ci-dessus :
| ERP / logiciel comptable | MCP disponible mi-2026 ? | Nature |
|---|---|---|
| NetSuite | ✅ Oui | Officiel — Oracle AI Connector Service (généralisé, étendu en mars 2026) |
| Microsoft Business Central | ✅ Oui | Officiel — Microsoft, endpoint hébergé, lecture + écriture configurable |
| Xero | ✅ Oui | Officiel — serveur MCP hébergé par Xero |
| QuickBooks Online | ✅ Oui | Officiel — Intuit, dépôt open source de l'éditeur |
| Odoo | ✅ Oui | Module natif (Odoo Apps Store) + implémentations communautaires |
| Exact Online | ✅ Oui | Communautaire/partenaire — pas d'implémentation officielle Exact confirmée |
| Pennylane | ✅ Oui | Communautaire (plusieurs implémentations) — pas d'implémentation officielle Pennylane confirmée |
| DATEV | ⚠️ Partiel | Communautaire, limité aux exports de fichiers — pas d'API transactionnelle live |
| Sage 100 | ❌ Aucun trouvé | (Sage Intacct, un produit Sage différent, a bien un MCP — pas Sage 100) |
| ACD | ❌ Aucun trouvé | — |
Lecture de ce tableau : 7 des 10 intégrations comptables natives de Spendesk ont déjà, d'une manière ou d'une autre, un MCP en 2026 — mais avec des niveaux de maturité très inégaux. NetSuite, Business Central, Xero et QuickBooks sont portés par l'éditeur lui-même, en production. Odoo l'intègre nativement. Exact Online et Pennylane n'ont, pour l'instant, que des implémentations communautaires — utilisables, mais non garanties par l'éditeur. DATEV et Sage 100/ACD restent aujourd'hui dans le cas "MCP-to-API" illustré par NetSuite plus haut.
Fait révélateur : le client REST NetSuite documenté dans cet article a été construit avant que l'AI Connector Service officiel d'Oracle n'atteigne sa maturité actuelle. Le schéma se répète probablement pour Sage 100 et ACD : le "MCP-to-API" n'est pas une impasse, c'est une solution transitoire qui rétrécit à mesure que chaque éditeur sort son propre MCP.
À retenir
- Deux façons de relier Spendesk à un système comptable avec un agent : MCP-to-MCP quand les deux côtés parlent le protocole (Rillet), MCP-to-API quand l'autre système n'en a pas encore (NetSuite).
- Exporter les payables et réconcilier les settlements sont deux besoins découplés : les clients veulent le premier dès que possible, le second peut suivre à son propre rythme.
- La prochaine brique, une fois
update_payableen production : vérifier et corriger le codage comptable avant l'export, pas seulement le signaler après coup. - L'idempotence est le vrai sujet des deux approches — par référence externe native côté MCP-to-MCP, par table de correspondance locale côté MCP-to-API.
- 7 des 10 ERP natifs de Spendesk ont déjà un MCP en 2026, à des niveaux de maturité très différents — le MCP-to-API restant est une étape transitoire, pas une limite définitive.
- Aucun de ces deux skills n'est aujourd'hui dans la bibliothèque publique : ce sont des cas d'usage avancés avec des écritures financières réelles, présentés ici comme étude de cas, pas comme skills prêts à télécharger.