Ajoute ROADMAP.md et le relie depuis README.md et CLAUDE.md.
Origine : un rapport d'usage d'une session Cowork sur le profil LIMAGRAIN a
signalé 8 anomalies. Vérification faite contre le WMS réel, 4 bugs sont
confirmés et reproduits, dont un non signalé par le rapport.
Cause racine commune : entity_type est interpolé dans Context.{entity_type}
sans aucune validation, alors que le nom attendu est le TableName de l'API
Metadata et non le nom d'entité de l'AD. Container -> Containers, mais
Alias -> Alias : c'est un mapping, pas une règle de pluralisation. L'API
Metadata connaît 232 entités là où le MCP en expose 12 en dur, et la liste
documentée était fausse (Aliases n'existe pas).
Lot 1 (déblocage) : corps des erreurs HTTP remonté, routage des outils par
table explicite, projections de champs des workflows.
Lot 2 (fond) : résolution des entités via l'API Metadata, rejet des
paramètres inconnus.
Lot 3 : bornage des sorties volumineuses, documentation.
Trois propositions du rapport sont explicitement écartées, avec leur raison :
uniformisation des noms de paramètres, indexStatus sur generic_search, outil
dédié d'aide à la syntaxe.
CLAUDE.md : la section « Points ouverts » renvoie désormais vers la roadmap et
avertit des deux pièges non encore corrigés.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6.9 KiB
Roadmap
Travaux planifiés, par lot. Chaque lot est livrable indépendamment.
Constats issus de la session de diagnostic du 24/08/2026 (profil LIMAGRAIN,
host 10.255.255.2, tenant LIMAGRAI2512), déclenchée par un rapport d'usage
d'une session Cowork. Toutes les anomalies ci-dessous ont été reproduites
contre le WMS réel — ce ne sont pas des hypothèses.
Les décisions actées vivent dans DECISIONS.md ; ce fichier ne contient que ce qui reste à faire.
Cause racine commune
Le MCP interpole entity_type dans Context.{entity_type} sans aucune
validation (vérifié : aucune liste blanche dans le code). Or le nom attendu
par le contexte de lecture n'est pas le nom d'entité de l'Application
Dictionary.
L'API Metadata (GET /Metadata/Entities, 232 entités) donne la
correspondance exacte :
Name (renvoyé par search_ad_elements) |
TableName (attendu par Context.) |
|---|---|
Container |
Containers |
Product |
Products |
ContainerType |
ContainerTypes |
Alias |
Alias — invariant, pas de pluriel |
Item |
n'existe pas dans le modèle Reading |
Ce n'est donc pas une règle de pluralisation : c'est un mapping, et seul
TableName fait foi. TableName est unique sur les 232 entités.
Conséquences déjà constatées :
- une session utilisant les noms de l'AD (singuliers) déclenche un HTTP 500 sur chaque requête ;
- la liste d'entités documentée était fausse (
Aliasesn'existe pas, c'estAlias) ; - le MCP n'expose que 12 entités figées là où l'API en connaît 232.
Lot 1 — Déblocage
Objectif : rendre le MCP auto-diagnosticable et réparer ce qui est cassé. Ce lot seul aurait suffi à ce qu'une session se débrouille sans intervention.
L1.1 — Remonter le détail des erreurs HTTP
Aujourd'hui toute erreur d'API se résume à Request failed with status code 500.
Or le WMS renvoie déjà le diagnostic complet dans le corps de la réponse :
{"ClassName":"System.AggregateException","Message":"Compile Error: ...
'ApplicationReadingContext' ne contient pas de définition pour 'Container' ..."}
Enrichir l'erreur au point de passage unique (api-service.post / .get) avec :
statut, URL, verbe, payload envoyé, corps de réponse tronqué à ~2000 caractères.
Fichier : src/services/api-service.js (catch de post et get).
L1.2 — Fiabiliser le routage des outils
Deux outils sont listés dans tools/list mais ne sont routés vers aucun module,
à cause du routage par préfixe :
| Outil | Cause | Erreur observée |
|---|---|---|
get_entity_metadata |
capté par startsWith('get_entity_') avant sa propre branche |
Unknown WMS query tool |
list_log_files |
ne contient pas _logs mais _log_files |
Unknown tool |
Remplacer le routage par préfixe par une table explicite nom → module,
construite depuis les listTools() de chaque module. Un outil listé mais non
routé devient alors impossible par construction, au lieu d'être rattrapé au cas
par cas.
Fichier : src/index.js (handler tools/call).
L1.3 — Corriger les projections de champs des workflows
L'API AD renvoie les champs en minuscules (id, name, version,
applicationName). Deux endroits supposent une autre forme :
search_workflowsprojettew.Id,w.Code,w.Name,w.Category→ tousundefined, supprimés parJSON.stringify→ 50 objets vides pour uncountpourtant correct ;workflow-servicelitw.category || w.Category, deux clés inexistantes →list_workflow_categoriesrenvoie 0 catégorie et classe les 4012 workflows enUncategorized.
Le champ le plus proche d'une catégorie est applicationName, mais il vaut
EasyWMS pour tous les workflows : la notion de catégorie n'a aucun support
dans les données. Décider en connaissance de cause plutôt que d'inventer une
taxonomie.
Fichiers : src/tools/workflow-tools.js, src/services/workflow-service.js.
Lot 2 — Correctif de fond
L2.1 — Résolution des entités via l'API Metadata
Accepter entity_type au nom d'entité (Container) ou au nom de jeu
(Containers), insensible à la casse, et émettre Context.{TableName}. Cache
identique aux autres (TTL partagé, invalidation au changement de profil).
Sur nom inconnu, échouer avant tout appel réseau, avec un message actionnable :
« Item » n'existe pas dans le modèle Reading. Proches : ItemGroup, StockItem. 232 entités disponibles — utilisez
get_entity_metadatapour la liste.
Supprime la cause des 500 et débloque 232 entités au lieu de 12.
L2.2 — Rejeter les paramètres inconnus
Le SDK MCP ignore silencieusement les paramètres non déclarés : un appel
read_recent_logs(lines: 60) retombe sur le défaut count = 100 sans le
moindre signal, et l'appelant conclut à un paramètre ignoré.
Ajouter additionalProperties: false aux 23 schémas d'outils.
C'est le correctif retenu à la place d'une uniformisation des noms de paramètres : renommer casse les usages existants pour un gain cosmétique, alors que la cause réelle est l'absence de signal.
Lot 3 — Ergonomie et documentation
L3.1 — Bornage des sorties volumineuses
get_system_parameters: ajouterlimit/offset, aujourd'hui absents (sortie constatée : 70 000 caractères, rejetée par le client).search_logs: garde-fou de taille.max_resultsexiste déjà, mais lescontext_linesmultiplient le volume (88 000 caractères pour 50 résultats).- Renvoyer
truncated: trueexplicitement plutôt que de laisser le client se faire rejeter.
L3.2 — Documentation
- DECISIONS.md : D21 la règle
TableName, D22 le routage par table explicite. - CLAUDE.md : corriger la liste d'entités (
Aliases→Alias) et renvoyer versget_entity_metadatacomme source de vérité. wms://query-examples: un exemple singulier/pluriel commenté.
Écarté
| Proposition | Raison |
|---|---|
Uniformiser les noms de paramètres (entity_type / query partout) |
Casse les usages existants ; les alias de transition doublent la surface à maintenir. La cause réelle est traitée par L2.2. |
Exposer un indexStatus sur generic_search |
TotalDocuments: 0 est déjà le signal. Le MCP n'a aucun moyen d'interroger l'état de l'index de recherche. |
Outil dédié get_query_syntax_help |
L'information doit se trouver dans le message d'erreur, là où elle est lue (L2.1), pas dans un outil qu'il faut penser à appeler. |
Points ouverts (hors lots)
select_expression: les projections via le paramètreSelectprovoquent des erreurs de compilation côté serveur (D13). Irritant principal restant.- Déploiement SSH sur la VM : l'exécutable est validé, la configuration SSH reste à faire.
- Historique des shipment templates : hors de portée, les logs concernés n'existent pas sur l'hôte joignable (D16).