---
title: Where's my sofa?
tagline: Un agent de service client sur MuleSoft Agent Fabric, avec son propre serveur MCP
description: Where's my sofa? est un agent de service client pour un magasin de meubles fabriqués sur commande, construit sur MuleSoft Agent Fabric : un broker Agent Script derrière Omni Gateway, un serveur MCP Mule et une System API Mule qui porte les règles.
date: 2026-10-18
repo: https://github.com/brbousnguar/wheres-my-sofa
stack: MuleSoft Agent Fabric · Agent Script · MCP · A2A · Mule 4 · CloudHub 2.0
status: A tourné sur CloudHub 2.0 dans une org Anypoint d'essai, octobre 2026
video: /assets/video/wheres-my-sofa-demo-fr.mp4
video_square: /assets/video/wheres-my-sofa-demo-fr-square.mp4
poster: /assets/img/demo/wheres-my-sofa-fr.jpg
video_caption: La page de démo du repo parle au broker Care Desk déployé sur mon org Anypoint d'essai, avec les données de la System API à droite. Chaque réponse est un vrai appel A2A. Voix off : ma propre voix, clonée par IA. Les attentes du modèle sont accélérées, et c'est indiqué.
video_duration: 63.5
install_video: /assets/video/wheres-my-sofa-config-fr.mp4
install_video_square: /assets/video/wheres-my-sofa-config-fr-square.mp4
install_poster: /assets/img/demo/wheres-my-sofa-config-fr.jpg
install_video_label: La configuration
install_video_caption: Une visite en lecture seule de l'org Anypoint d'essai où tournait l'agent : agent-network.yaml sur GitHub, puis le réseau, le serveur MCP et la carte A2A dans Exchange, les instances et leurs politiques dans API Manager, l'Omni Gateway et les applis dans Runtime Manager. Le nom de l'org et ses identifiants sont floutés. Voix off : ma propre voix, clonée par IA. Chargements coupés, défilement jusqu'à 1,5x.
install_video_duration: 101.0
---

Where's my sofa? est un agent de service client pour un magasin de meubles qui fabrique la plupart de ses pièces sur commande. Les clients lui demandent où en est leur commande, déplacent une livraison réservée ou signalent un dommage, en A2A. Il tourne sur MuleSoft Agent Fabric, et tout ce qu'il touche passe par Mule : un serveur MCP devant une System API.

Mon métier, c'est l'intégration MuleSoft, et il n'y a pas encore d'agent dedans. MuleSoft avance vite sur les agents (Agent Fabric, Agent Script, un connecteur MCP), alors j'ai construit le plus petit vrai cas d'usage possible, de bout en bout, en API-led. Le magasin, ses produits et ses clients sont inventés.

## Le modèle classe, le graphe décide

Un meuble fait sur commande, c'est un bon test pour un agent. « Où est mon canapé ? » demande de croiser la commande, l'étape de fabrication à l'atelier et la réservation de livraison. Et certaines décisions ne doivent jamais revenir à un modèle : à qui appartient la commande, quels créneaux sont libres, et qu'une livraison à moins de 48 heures ne bouge plus.

Le broker est donc un graphe Agent Script, et le modèle ne reçoit que ce qui demande du langage :

- `understandRequest` fait un seul appel LLM, sans outil : intention, numéro de commande, email, créneau souhaité.
- Un routeur, sans LLM, choisit le chemin et vérifie que le numéro de commande et l'email sont là.
- `orderStatus` n'a que les deux outils de son chemin, avec l'email lié par le graphe : le modèle ne peut pas viser la commande de quelqu'un d'autre.
- Pour déplacer une livraison, un exécuteur lit les créneaux libres, un appel LLM choisit celui qui correspond, et un autre exécuteur la déplace. Le modèle choisit un créneau mais n'appelle jamais l'outil, et quand il faut demander quel créneau convient, la question est une réponse fixe.
- Les réclamations, et les livraisons trop proches pour être déplacées, vont à des exécuteurs qui ouvrent un dossier avec des arguments fixes. Aucun modèle ne décide si un dossier est ouvert.

Les règles vivent dans la System API. Un mauvais email reçoit la même 404 qu'une commande inexistante : l'API ne confirme jamais qu'un numéro de commande existe.

## Ce qu'il y a dedans

- **sofa-orders-sapi** : une System API Mule sur un ERP simulé, avec ses règles en DataWeave.
- **sofa-care-mcp** : une app Mule sur le connecteur MCP 1.7, cinq outils sur la System API, et une clé d'API vérifiée à l'ouverture de chaque session MCP.
- **Le broker Care Desk**, déployé par Agent Fabric derrière Omni Gateway : contrôle du client ID, 60 requêtes par heure et par client pour plafonner la facture LLM, et un contexte utilisateur pour que chaque appelant ait sa propre mémoire de conversation.
- `gpt-5-mini` via OpenRouter, avec un effort de raisonnement faible.

## Ce qui a cassé

L'agent répondait parfois aux clients avec son propre raisonnement. Agent Fabric fait tourner ses nœuds LLM avec un humain dans la boucle : quand le modèle estime qu'il lui manque une information, la tâche s'arrête pour attendre le client, et le raisonnement du modèle devient la réponse. La solution a été de retirer cette décision au modèle : il remplit des champs, le graphe décide, et chaque question au client est une réponse fixe. Et le connecteur MCP 1.6 gardait un flux SSE ouvert pour chaque réponse, si bien que la découverte des outils par le broker expirait derrière la gateway. Le connecteur 1.7 répond avec un seul corps JSON.

## L'éval vérifie le système, pas la réponse

Une réponse peut sonner juste et faire la mauvaise chose. `scripts/eval.py` envoie huit messages clients et photographie chaque créneau de livraison et chaque dossier de la System API avant et après chacun. Un déplacement ne passe que si cette commande-là a bougé vers ce créneau-là, et rien d'autre. Une injection de prompt sur la commande de quelqu'un d'autre ne passe que si rien n'a bougé.

Toute l'histoire, avec les passes d'éval : [Un agent de service client sur MuleSoft Agent Fabric, où le modèle ne fait que parler](/fr/notes/mulesoft-agent-fabric-care-desk.html).

## Le lancer

Le dépôt contient les deux apps Mule, le réseau d'agents et les scripts de déploiement. Avec une org Anypoint qui a Agent Fabric, une connected app et une clé OpenRouter :

```bash
scripts/deploy-apps.sh                                                     # les deux apps Mule sur CloudHub 2.0
SETUP_GATEWAY=1 SOFA_CARE_MCP_URL=https://... scripts/deploy-network.sh    # gateway, publication, broker
scripts/ask.py                                                             # lui parler en A2A
```

`demo/server.py` sert la page de la vidéo : la conversation à côté des données de la System API.
