Aucune borne de VOLUME n'existait sur query_wms_entities, call_query_api et
search_wms_data -- seulement une borne de LIGNES (MAX_QUERY_ROWS). Le modele
Writing serialise l'agregat complet (navigations, $id) : une seule ligne
Products y pese 95 288 caracteres, la ou la meme ligne Reading en fait ~4 500.
Toutes ces reponses depassaient le seuil de rejet du client MCP (D24), qui
renvoie un echec opaque plutot qu'un resultat partiel.
Plafond commun MAX_QUERY_RESPONSE_CHARS (defaut 25 000, meme ordre de grandeur
que MAX_LOG_SEARCH_CHARS), applique par src/services/response-limit.js : on
ecarte des LIGNES ENTIERES, jamais coupees au milieu, et on signale avec le
vocabulaire D24 (truncated / returned / omitted / hint). Le helper est partage
parce que les trois outils partagent le meme mecanisme -- ce que les mecanismes
de get_system_parameters et search_logs, eux, ne font pas. La recherche
dichotomique evite 200 reconstructions d'une charge utile de ~1 Mo.
Mesures avant/apres (protocole, LIMAGRAIN, longueur de content[0].text) :
query_wms_entities Products limit 200 957 234 -> 24 432
count 200, returned 5, omitted 195, truncated
search_wms_data "PAL" 847 543 -> 22 992
totalFound 150, returned 4, omitted 146 ; reparti en tourniquet :
Products 2, Containers 1, Tasks 1 -- sans quoi Products, en tete,
consommerait tout le budget et les deux autres reviendraient a zero
resultat sans que rien ne le dise
call_query_api Products query_type 1 95 288 -> 738
cas limite : returned 0, omitted 1, truncated, hint expliquant le
volume Writing et renvoyant vers Reading
Sous le plafond, rien ne change -- verifie identique OCTET POUR OCTET contre
la version precedente :
query_wms_entities Container limit 1 4 476 -> 4 476
call_query_api Products limit 2 9 671 -> 9 671
get_entity_schema Container 11 172 -> 11 172
search_wms_data sous plafond 11 767 -> 11 767
count_wms_entities Products 120 -> 120 (non concerne)
MAX_QUERY_ROWS et les limites par defaut des outils sont inchanges : le
correctif est le bornage signale, pas une reduction silencieuse. L'avertissement
de volume rejoint la description du parametre query_type (D25) de
query_wms_entities et call_query_api, pas celle de count_wms_entities dont la
reponse est un scalaire.
Baseline preservee : 23 outils, 6 resources.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
8.3 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.
Lot 4 — Modèle de données et applications
Deux angles morts constatés le 24/08/2026, plus larges que les lots 2 et 3. Les
chiffres ci-dessous sont mesurés sur le tenant LIMAGRAI2512.
L4.1 (reliquat) — Explorer le contexte Metrics
L'exposition de query_type est livrée (D25). Reste l'investigation : le
contexte Metrics (QueryType: 3, ApplicationMetricDataContext) mérite une
exploration à part — c'est probablement là que vivent les données agrégées
produites par les jobs MetricGatherer. Livrable : un rapport, pas du code
(même phase d'investigation que L4.4).
L4.3 — Identifier le MCP dans les logs du WMS
Les requêtes du MCP apparaissent dans les logs du WMS sous
Execute error. Client: GNA — le client OAuth partagé — donc indistinguables de
celles du vrai client GNA.
La piste ClientModule est invalidée (mesuré le 24/08/2026, lot 1) : le
champ est bien accepté par QueryExecute (pas d'erreur), mais il est sans
effet observable. Une requête en échec envoyée avec
ClientModule: "MCP-WMS" est tracée Execute error. Client: GNA, et ni
MCP-WMS ni ClientModule n'apparaissent nulle part dans
ApplicationService.log ni HttpResponseTime.log. Le Client: des logs vient
du client OAuth, pas du payload — le champ n'a donc pas été renseigné.
Piste restante (non vérifiée) : un client OAuth dédié au MCP côté EasySTS
changerait le Client: des logs, mais suppose une configuration côté WMS.
L4.4 — Historique d'exécution des workflows par API
ApplicationService expose une API WorkflowLog que le MCP n'utilise pas :
| Endpoint | Usage |
|---|---|
GET /WorkflowLog/GetInstances?processDefinitionId=&skip=&take=&startDateFrom=&startDateTo= |
instances d'un workflow sur une plage de dates, filtrables par attribut |
GET /WorkflowLog/GetInstance?processId= |
une instance |
GET /WorkflowLog/GetLogs?processId=&skip=&take=&logDateFrom=&logDateTo= |
journal d'exécution d'une instance |
GET /WorkflowLog/Validate?applicationName=&processDefinitionId= |
validation d'une définition |
Endpoints joignables et fonctionnels — Validate renvoie
{"Success":true,"ErrorMessage":null,"Warnings":[]}. GetInstances répond []
sur le workflow testé : à confirmer sur un workflow ayant réellement tourné, la
journalisation n'étant pas forcément active partout.
Peut remettre en cause D16 (historique des shipment templates jugé hors de portée faute de logs fichier) : si l'historique d'exécution est disponible par API, la conclusion change. À vérifier avant d'écrire quoi que ce soit.
L4.5 — Champs de QueryExecute inexploités
La référence de l'API documente des champs que le MCP n'envoie jamais :
| Champ | Intérêt |
|---|---|
Parameters |
requêtes paramétrées (dictionnaire nom -> {TypeName, Value}) — supprimerait toute concaténation de chaîne dans les filtres, et pourrait débloquer D13 (Select) |
CommandTimeout |
timeout par requête, au lieu du timeout HTTP global de 30 s |
QueryId + POST /QueryCancel |
annulation d'une requête longue |
POST /QueryExecuteStream |
résultats en flux — piste long terme pour les sorties volumineuses, au-delà du bornage signalé de D24 |
Autres endpoints jamais utilisés, à évaluer : QueryEvents, QueryCommands,
QueryCorrelationEvents, QuerySnapshots (event sourcing — utile en debug),
GET /Metadata/Commands|Events|Aggregates et leurs variantes …All,
GET /configuration/applications (liste les applications avec leur version,
plus riche que /AD/api/Application/GetAll), GET /healthcheck?tenantCode= et
GET /ready?tenantCode= (sondes de disponibilité, répondent 200).
Lot 5 — Clore la famille D24 (rejets client sur sorties volumineuses)
Mesures du 25/08/2026 (protocole, LIMAGRAIN), toutes au-dessus du seuil de rejet client (~70 000 caractères, D24) :
| Appel | Taille |
|---|---|
query_wms_entities("Products", limit: 200) — Reading ordinaire |
957 234 |
search_wms_data("PAL") |
847 543 |
get_workflow_details(CST_SendRejectContainersToPK) |
~101 800 |
call_query_api("Products", query_type: 1, limit: 1) — une seule ligne Writing |
95 288 |
L5.3 — Champ tool absent des erreurs construites localement
Les catch locaux d'api-tools.js renvoient { success: false, error } sans
le champ tool du contrat (convention 3) — antérieur au lot 4. Balayer tous
les modules d'outils pour le même motif.
L5.4 — Rendre les autres applications découvrables depuis search_workflows
Cas réel (25/08/2026, session Cowork sur LIMAGRAIN) : une session cherchant
des workflows CST_* sans passer application: "CustomApp" a conclu à tort
« l'AD contient 4 012 workflows, aucun CST_ » — alors que
CST_PickingTasksSequencing_PR et CST_ChooseDestinationFromPS existent bien
dans CustomApp (vérifié en révision). Le paramètre application (D26) existe,
mais rien dans la réponse ne signale qu'on n'a regardé qu'une application.
Ajouter aux réponses de search_workflows (et search_ad_elements) un rappel
peu coûteux : l'application interrogée, et — quand la recherche renvoie peu ou
pas de résultats — un hint listant les autres applications (la liste allégée
d'Application/GetAll est déjà en cache, D26) avec renvoi vers le paramètre
application. Aucun préchargement des autres applications (D26).
É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)
- Profil
AD: tenant introuvable (mesuré le 24/08/2026).npm test -- --alléchoue 0/4 sur ce profil ; le STS de10.255.255.2répond400 {"error":"invalid_request","error_description":"Tenant not found"}pour le tenantAD. L'hôte et le STS fonctionnent (LIMAGRAIN, même hôte, passe 4/4) : c'est la valeurAD_TENANTdu.envqui ne correspond plus à un tenant existant. Correction côté propriétaire du dépôt (mettre à jour ou retirer le profil) — pas un bug du code. Depuis L3.2, le corps de la réponse du STS (Tenant not found) remonte dans les erreurs d'outils et du smoke test. - Bascule de profil concurrente aux appels en vol (mesuré le 25/08/2026,
révision du lot 2). Le serveur traite les
tools/callen concurrence : en envoyant une rafale de requêtes dans une même session, les réponses reviennent dans le désordre, et unswitch_wms_profileémis pendant que des requêtes sont en vol les fait partir sur le nouveau profil (observé : une requête destinée à EUROTRAFIC exécutée sur l'hôte10.255.255.2après la bascule suivante). Conséquence du singleton d'état global (D8). Sans gravité pour un usage conversationnel séquentiel, mais Claude peut émettre des appels d'outils en parallèle : à traiter si un cas réel de mélange de profils est observé (piste : sérialiser lestools/callou figer le profil résolu au début de chaque appel). 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).