Deux angles morts mesurés sur le tenant LIMAGRAI2512. L4.1 — QueryType est figé à 0 (Reading) en dur dans api-service.js : le modèle Writing est inatteignable. Ce n'est pas une limite de l'API, QueryType 1 répond correctement sur Context.Products — il manque le paramètre. D3 reste vrai en revanche : en Writing les statuts sont des énumérations, donc le défaut doit rester 0. L4.2 — Application vient de WMS_APPLICATION, partagé par tous les profils, sans surcharge possible. Le MCP n'interroge que EasyWMS alors que /AD/api/Application/GetAll en déclare 9. CustomApp porte le spécifique client (153 workflows, 54 queries, 11 entités préfixés CST_) et est entièrement invisible ; avec AGV, Notifications, GalileoFaults et Common, ce sont 260 workflows hors périmètre. Côté API AD le correctif est simple, l'application n'étant qu'un champ du payload — vérifié, ["CustomApp", tenant, 5, 0] renvoie bien les workflows CST_. Il faudra en revanche indexer les caches par application. Côté QueryExecute c'est non résolu : passer Application "CustomApp" ne change pas le contexte de lecture, les entités CST_ ne répondent ni au singulier ni au pluriel et aucune n'apparaît dans les 232 entités du Metadata EasyWMS. Elles sont définies dans EasyBuilder (FromMetadata: false). Consigné comme question ouverte, sans solution promise. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.6 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é.
Lot 4 — Modèle de données et applications
Deux angles morts constatés le 24/08/2026, plus larges que les lots 1 à 3. Les
chiffres ci-dessous sont mesurés sur le tenant LIMAGRAI2512.
L4.1 — Le modèle Writing est inatteignable
QueryType est figé à 0 (Reading) en dur dans api-service.js
(executeQuery et executeScalarQuery). Aucun outil ne permet d'interroger le
modèle Writing.
Ce n'est pas une limite de l'API : {"Application":"EasyWMS","QueryType":1, "Expression":"Context.Products.OrderBy(z => z.Id)","Take":1} répond
correctement. Il manque simplement le paramètre.
Attention en l'exposant : D3 reste vrai — en QueryType: 1 les champs de statut
sont des énumérations, donc les comparaisons par chaîne (== "Release")
échouent. Le défaut doit rester 0, et la bascule être un choix explicite et
documenté, pas une option qu'on active au hasard.
L4.2 — Une seule application sur neuf est visible
Application vient de WMS_APPLICATION dans .env, partagé par tous les
profils, sans surcharge par appel ni paramètre d'outil. Le MCP n'interroge donc
jamais que EasyWMS.
POST /AD/api/Application/GetAll en déclare 9 :
| Application | Workflows | Queries | Entities |
|---|---|---|---|
| EasyWMS | 4012 | 2239 | 338 |
| CustomApp | 153 | 54 | 11 |
| AGV | 71 | 14 | 5 |
| Notifications | 26 | 35 | 24 |
| GalileoFaults | 9 | 20 | 24 |
| Common | 1 | 7 | 25 |
| SmartUI, User, WarehouseWebDesigner | 0 | 0–8 | 0 |
CustomApp porte le spécifique client — ses workflows sont préfixés CST_
(CST_SendRejectContainersToPK, CST_Task, CST_Container…). C'est
précisément ce qu'on cherche en debug, et c'est aujourd'hui invisible. Au total
260 workflows et ~130 queries hors périmètre.
Deux chantiers de difficulté très différentes :
API AD — simple. L'application est un champ du payload
([application, tenant, pageSize, offset]). Vérifié : ["CustomApp", tenant, 5, 0] sur /Workflow/GetByApplication renvoie bien les workflows CST_. Il
suffit d'un paramètre application sur les outils AD et workflow, avec une clé
de cache incluant l'application (sinon un cache pollué mélange les
applications).
QueryExecute — non résolu, à investiguer. Passer Application: "CustomApp"
ne change pas le contexte de lecture : l'erreur reste
ApplicationReadingContext ne contient pas de définition pour …. Les 11 entités
CST_ ne sont atteignables ni au singulier ni au pluriel, et aucune n'est
présente dans les 232 entités du Metadata EasyWMS (vérifié). Elles sont
définies dans EasyBuilder (FromMetadata: false) — reste à déterminer si elles
sont interrogeables, et sous quel nom. Ne rien promettre avant d'avoir tranché.
É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).