6f54d765c43ce8150d97498a6d0c0058e2601801
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
6f54d765c4 |
L5.1 : fenetre verbatim sur le blob data de get_workflow_details
La reponse embarquait la definition EasyBuilder complete, au-dela du seuil de
rejet du client MCP (~70 000 caracteres, D24). Deux parametres de fenetre au
schema (D23) : max_data_chars (defaut 20 000) et data_offset (defaut 0). Les
metadonnees du workflow restent completes dans chaque tranche ; seul `data`
est fenetre, et dataTotalChars est porte par toute reponse.
La tranche est verbatim -- decoupe de chaine, rien d'autre. Ne jamais resumer
ni parser ce blob : la concatenation des tranches doit reconstituer la
definition a l'octet pres. Verifie : 20 000 + 20 000 + 20 000 + 11 512 =
71 512, concatenation identique au blob d'origine (premiers et derniers
caracteres compris).
Mesures avant/apres (protocole, LIMAGRAIN, longueur de content[0].text) :
StackerCrane_LocationIsAccessibleByExtractor_PR 79 092 -> 23 117
(blob data : 71 512, desormais annonce par dataTotalChars)
CST_SendRejectContainersToPK (CustomApp) 101 816 -> 23 023
(blob data : 92 362)
StackerCrane_LoadMovementForOutboundTask_PR 10 587 -> 10 652
(blob de 9 013 : sous le defaut, objet workflow identique a l'octet pres,
ni truncated ni hint -- les +65 caracteres sont les trois champs de
fenetre, contrat "total toujours porte" de D24)
Gardes de valeur dans le code de l'outil, pas dans le wrapper (D23 ne valide
que les noms) : data_offset: -5 et max_data_chars: 1.5 echouent avant tout
appel reseau avec un message nommant l'attendu.
Baseline preservee : 23 outils, 6 resources.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
92de85cf53 |
L4.2 : paramètre application sur les outils AD et workflow (D26)
L'application venait de WMS_APPLICATION (partagée par tous les profils) : le MCP n'interrogeait que EasyWMS, alors que CustomApp porte le spécifique client (153 workflows CST_ sur ce tenant) et que 9 applications sont déclarées par Application/GetAll. Paramètre application (défaut : l'application du profil, comportement inchangé sans lui) sur get_ad_elements, search_ad_elements, get_ad_element_details, search_workflows, get_workflow_details, list_workflow_categories. Clés de cache : ad-service passe par (application, type), workflow-service par application — sans quoi un appel CustomApp polluerait le cache EasyWMS. L'invalidation reste l'abonnement onSwitch (D8), le chargement reste paresseux (aucun préchargement des 9 applications, D10). list_workflow_categories s'adosse à Application/GetAll (liste allégée en cache : le blob data de chaque application pèse ~100 Ko) ; get_application_summary regroupe par application et ne détaille que les entrées en cache (D24), workflows compris. Acté en D26 ; CLAUDE.md mis à jour (Caches, AD), L4.2 retiré de la ROADMAP. Vérifications rejouées via le protocole (LIMAGRAIN / LIMAGRAI2512), requêtes séquentielles : - search_workflows(CST_, application:CustomApp) -> 5 objets peuplés dont CST_SendRejectContainersToPK ([Workflow] Successfully cached 153 workflows for "CustomApp"). - get_ad_elements(Workflow, application:CustomApp) -> count 153, éléments CST_* ([AD] Successfully cached 153 CustomApp::Workflow). - Séquence EasyWMS -> CustomApp -> EasyWMS sur search_workflows : 4012 vs 153, retour en cache hit ([Workflow] Using cached data for "EasyWMS"), aucune pollution ; get_application_summary montre les deux caches (workflowCachesByApplication EasyWMS 4012 / CustomApp 153). - Sans paramètre application -> comportement inchangé (W1 = W3). - switch_wms_profile EUROTRAFIC puis retour -> [Workflow] Cache cleared, [AD] All caches invalidated, [EntityResolver] Cache cleared ; summary vide. - list_workflow_categories -> 9 applications, comptes réels des applications chargées. Baseline : tools/list 23 (les 23 noms répondent), resources 6, rejet D23 d'un paramètre inconnu OK (search_workflows/applikation), npm test 4/4 exit 0. Anomalie hors périmètre consignée dans ROADMAP.md : get_workflow_details peut dépasser le seuil de rejet client (~101 800 caractères mesurés sur CST_SendRejectContainersToPK), comportement antérieur au lot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
706e628715 |
L4.1 : expose query_type sur les outils de requête (D25)
QueryType était figé à 0 en dur dans executeQuery/executeScalarQuery : le modèle Writing, opérationnel et mesuré, était inatteignable. Paramètre query_type (défaut 0) sur call_query_api, query_wms_entities, count_wms_entities — get_entity_schema et search_wms_data restent des raccourcis Reading. D3 reste la règle par défaut : la bascule est un opt-in, avertie dans les descriptions d'outils (statuts en énumérations en Writing). Garde de valeur assertValidQueryType dans le code (le wrapper D23 ne valide pas les valeurs), avant tout réseau. En query_type != 0, un nom inconnu du Metadata Reading passe tel quel avec warning (allowUnknown du resolver) — conservé aussi dans la réponse d'erreur si le WMS échoue ensuite. Acté en D25 ; CLAUDE.md nuancé, L4.1 retiré de la ROADMAP (reliquat : exploration Metrics, rapport à part). Vérifications rejouées via le protocole (LIMAGRAIN / LIMAGRAI2512) : - call_query_api(Products, query_type:1, limit:1) -> success, 1 ligne, queryType:1 dans la réponse. - call_query_api(Products, query_type:3) -> erreur structurée contenant 'ApplicationMetricDataContext' ne contient pas de définition pour 'Products'. - call_query_api(Products, query_type:7) -> erreur locale nommant les 4 contextes, aucun [API] POST/GET dans stderr. - query_wms_entities(Container, limit:1) sans query_type -> comportement inchangé (resolvedTableName Containers, Reading, pas de champ queryType). - call_query_api(FooBar123, query_type:1) -> transmis tel quel (payload QueryType:1 Expression Context.FooBar123...), erreur WMS ApplicationWritingRepository + warning de résolution dans la réponse. - count_wms_entities(Product, query_type:1) -> count 51145 (~51160). Baseline : tools/list 23, resources 6, rejet D23 d'un paramètre inconnu OK. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b37c2ac251 |
L3.1c : acte le contrat de troncature en D24, retire le lot 3 de la ROADMAP
Les deux bornages (L3.1a pagination, L3.1b plafond de volume) partagent le même vocabulaire de signal — truncated présent uniquement quand la réponse est coupée, hint actionnable, returned vs total avant coupe — mais gardent des implémentations locales : paginer et plafonner un volume sont deux mécanismes distincts, un helper commun forcerait une abstraction qu'ils n'ont pas. D24 consigne ce contrat, les garde-fous de cadrage (défauts inchangés, mesure protocolaire qui fait foi) et le changement de sens de totalParameters. ROADMAP : L3.1 livré, le lot 3 devenait vide — section retirée ; la référence à L3.1 dans L4.5 (QueryExecuteStream) renvoie désormais à D24. read_recent_logs est laissé tel quel : sans helper partagé, rien de gratuit à lui apporter (L3.1c). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
5386f54922 |
L2.2 : rejette les paramètres inconnus et les requis manquants (D23)
Mesure V1 (24/08/2026) : le SDK MCP ignore additionalProperties: false —
read_recent_logs({lines: 5}) avec la clause sur le schéma répondait
success: true, returnedLines: 100 (retombée silencieuse sur le défaut).
La validation vit donc dans le wrapper tools/call de src/index.js,
pilotée par les schémas de la table de routage (D22) : paramètre inconnu
ou requis manquant -> erreur structurée nommant le fautif et les
paramètres valides, avant tout dispatch.
Les 23 schémas portent additionalProperties: false — inerte côté SDK,
mais c'est le contrat que lisent les clients. Pas de renommage de
paramètres (écarté, cf. ROADMAP).
Mesures (via le protocole) :
- read_recent_logs({"lines": 5}) -> "Paramètre(s) inconnu(s) pour
read_recent_logs : lines. Paramètres valides : count, log_file."
- read_recent_logs({"count": 5}) -> succès, returnedLines: 5
- boucle sur 22 outils avec {} (execute_command vérifié statiquement) :
22/22 répondent, aucun Unknown tool, les 11 outils à paramètres requis
échouent avec le message actionnable
- handshake : 23 outils, 6 resources
Docs : D23 dans DECISIONS.md, L2.2 retirée de la ROADMAP.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
cb625a7918 |
L2.1 : résout entity_type via l'API Metadata (D21)
Context.{entity_type} attend le TableName du Metadata, pas le nom
d'entité de l'AD (Container -> Containers, mais Alias -> Alias) : un nom
faux partait en HTTP 500 de compilation LINQ. Nouveau service
entity-resolver.js : table Name|TableName (insensible à la casse) ->
TableName, agrégée sur les applications déployées (via
GET /configuration/applications — les applications sans contexte
requêtable n'y figurent pas et n'apportent 0 entité Metadata), cache TTL
partagé, invalidation par onSwitch (D8). Branché dans wms-query-service
(query/count/schema/search) et call_query_api.
Nom inconnu -> échec avant tout appel réseau de requête, suggestions
proches + renvoi vers get_entity_metadata. Metadata injoignable -> le
nom passe tel quel avec un warning dans la réponse.
Mesures (LIMAGRAIN, via le protocole) :
- query_wms_entities("Container", limit 1) -> succès, 1 ligne, résolu
Containers
- query_wms_entities("Alias") -> succès, invariant (pas de pluriel)
- query_wms_entities("Item") -> "Item" n'existe pas dans le modèle
Reading. Proches : RFMenuItems, Sites. 288 entités disponibles —
aucune ligne [API] POST dans stderr
- count_wms_entities("Product") -> 51160
- get_entity_schema("Container") et call_query_api("Container") : mêmes
résolutions
- 288 TableName distincts sur 5 applications, aucun conflit
Name -> TableName (mesuré le 24/08/2026)
Docs : D21 dans DECISIONS.md ; CLAUDE.md (piège retiré des points
ouverts, liste d'entités corrigée Aliases -> Alias, entity-resolver dans
la structure) ; exemple singulier/pluriel dans wms://query-examples ;
ROADMAP allégée (cause racine + L2.1 + L3.3 livrés).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
e0bdc1707d |
L1.2 : route les outils par table explicite nom -> module (D22)
Le routage par préfixe de nom laissait deux outils listés dans
tools/list mais injoignables : get_entity_metadata (capté par
startsWith('get_entity_') avant sa propre branche) et list_log_files
(aucune branche : le nom contient _log_files, pas _logs).
Une table nom d'outil -> module est construite au démarrage depuis les
listTools() des 8 modules de src/tools/. tools/list est servi depuis
cette même table et le dispatch devient un lookup : un outil listé est
un outil routé, par construction. Deux modules déclarant le même nom
font échouer le serveur au démarrage avec un message nommant les deux
modules. Le wrapper d'erreur du handler tools/call est inchangé, les
23 outils gardent leurs noms.
Vérifié contre le WMS réel : get_entity_metadata renvoie 232 entités,
list_log_files renvoie 19 fichiers, tools/list expose toujours 23
outils et chaque nom listé est traité par le executeTool() de son
module.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
86923542fa |
Roadmap et décisions : exploitation de la référence API du service
Source : la page d'aide générée https://<host>/ApplicationService/Help, qui documente des champs et des endpoints que le MCP n'utilise pas. Toutes les affirmations ci-dessous ont été testées contre LIMAGRAI2512. D3 corrigé — QueryContextType a quatre valeurs, pas deux : Reading 0 (ApplicationReadingContext), Writing 1 (ApplicationWritingRepository), DataWarehouse 2 (non configuré sur ce tenant : IDataWarehouse non résolu), Metrics 3 (ApplicationMetricDataContext, présent, modèle non exploré). Le message d'erreur nomme le contexte, ce qui donne un moyen rapide de savoir quel QueryType a servi. L4.1 étendu aux quatre contextes. L4.2 tranché sur son point dur : le champ Application ne partitionne pas le contexte de lecture. Context.AgvTasks répond aussi bien avec Application AGV qu'avec EasyWMS — le contexte est commun au tenant. La table de résolution du lot 2 devra donc agréger le Metadata de toutes les applications, mais un paramètre application sur QueryExecute serait inutile. Les entités CustomApp restent inatteignables sous les quatre QueryType, au singulier comme au pluriel, et Metadata renvoie 0 entité pour cette application : ce sont des définitions EasyBuilder sans projection requêtable. L'API AD est le seul accès au spécifique client. Trois chantiers ajoutés : - L4.3 ClientModule, non renseigné, d'où des requêtes du MCP journalisées sous « Client: GNA » et indistinguables du vrai client GNA. - L4.4 API WorkflowLog (GetInstances, GetLogs, Validate), joignable et fonctionnelle, susceptible de remettre en cause D16. - L4.5 champs inexploités de QueryExecute : Parameters (requêtes paramétrées, piste pour D13), CommandTimeout, QueryId + QueryCancel, QueryExecuteStream (piste pour L3.1), plus les endpoints event sourcing et les sondes healthcheck/ready. CLAUDE.md pointe désormais vers la page d'aide comme source de vérité. MONITORING.md documente healthcheck/ready comme sonde légère. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0ff44f7b78 |
Documentation : structure README / CLAUDE / DECISIONS / MONITORING
Nouveaux documents :
- README.md : porte d'entrée humaine, absente jusqu'ici. Objet du projet,
installation, npm test, branchement Claude Desktop, ajout d'un profil WMS,
compilation de l'exécutable.
- DECISIONS.md : 20 décisions et pièges vérifiés sur un WMS réel (D1..D20),
chacun avec son pourquoi. Extrait ce qui était noyé dans CLAUDE.md :
100 % API, tenant_code OAuth, réponses {entities}, casse des propriétés,
dotenv sur stderr, dates relatives LINQ non traduisibles, absence de
CommandParameterData, etc.
- MONITORING.md : supervision du serveur MCP. Préfixes de logs, séquence
d'un démarrage sain, cycle de vie du token OAuth et ses trois filets,
état des caches, table symptôme -> cause. Une section dit explicitement
ce qui n'est pas instrumenté (ni healthcheck, ni métriques, ni alerte).
- docs/logs.md : accès aux logs du WMS. Chemins, placeholder {host},
blocage volontaire sur les profils SaaS, les trois outils, format des
lignes, limites connues.
Mises à jour :
- CLAUDE.md réécrit et aligné sur le code. Correction de l'écart le plus
gênant : le code utilise QueryType 0 (Reading), la doc annonçait 1, soit
l'inverse de ce qui fonctionne pour les comparaisons de statut par
chaîne. Corrigés également : 6 resources et non 7 (workflows://categories
n'existe pas), section .env mono-profil obsolète, références à des
fichiers de test absents, README annoncé mais inexistant. Le suivi de
projet et les checklists de phases sont retirés.
- docs/README.md : index réel du dossier. L'ancien promettait une resource
docs:// qui n'a jamais existé.
- docs/getting_started.md : avertissement en tête, c'est une capture
partielle du portail Mecalux dont les liens internes ne résolvent pas.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|