Files
mcp-wms-api/MONITORING.md
T
Arthur Ria 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>
2026-08-24 15:15:31 +02:00

8.9 KiB

Supervision du serveur MCP

Comment savoir si le serveur tourne, ce qu'il fait, et pourquoi il ne répond pas. Ce document décrit l'existant — il n'y a ni endpoint de santé, ni métriques exportées : toute l'observabilité passe par stderr et par le smoke test npm test.

Pour lire les logs du WMS (et non ceux du serveur MCP), voir docs/logs.md.


1. Où regarder

Quoi
Logs du serveur MCP %APPDATA%\Claude\logs\ (fichier mcp-server-wms.log)
Logs applicatifs du WMS partages \\<host>\... — voir docs/logs.md
État de la connexion WMS npm test (voir §5)
Profil actif / caches outils get_current_wms_profile, get_application_summary

Tout passe par stderr. stdout est réservé au JSON du protocole MCP : la moindre écriture sur stdout casse la session Claude Desktop (voir D6 dans DECISIONS.md). En pratique, cela veut dire que les logs sont la seule sortie observable, et qu'ils sont complets.

Suivre les logs en direct :

Get-Content -Wait -Tail 50 "$env:APPDATA\Claude\logs\mcp-server-wms.log"

2. Lire les préfixes

Chaque ligne est préfixée par son composant. Le préfixe suffit à localiser le problème.

Préfixe Composant Ce qu'il signale
[Server] src/index.js démarrage, routage des outils, erreurs non rattrapées
[Profile] config/profile-manager.js chargement des profils, bascule de profil
[API] services/api-service.js OAuth, chaque requête HTTP, retries 401
[Workflow] services/workflow-service.js cache workflows, pagination
[AD] services/ad-service.js cache par type d'élément, pagination
[Logs] services/log-service.js chemins de logs illisibles ou absents
[WMSQuery], [Metadata] services construction des requêtes
[*Tools] src/tools/ exécution d'un outil précis

3. Démarrage : à quoi ressemble un boot sain

[dotenv@17.2.4] injecting env (30) from .env
[Profile] Loaded 3 profile(s). Active: LIMAGRAIN
[Server] Starting WMS MCP Server...
[Server] Architecture: 100% API-based (no direct database access)
[Server] Profiles available: AD, EUROTRAFIC, LIMAGRAIN
[Server] Active profile: LIMAGRAIN
[Server] WMS MCP Server running on stdio
[Server] Ready to accept requests from Claude Desktop

Trois points à contrôler dans cet ordre :

  1. injecting env (N) — si N vaut 0, le .env n'a pas été trouvé. En mode packagé il est attendu à côté de l'exe (D7).
  2. Loaded N profile(s) — si 0, WMS_PROFILES est vide ou les variables <NOM>_HOST/USERNAME/PASSWORD/TENANT manquent.
  3. Active profile: … — si le message est No active profile, ce n'est pas une panne : Claude doit appeler switch_wms_profile avant la première requête, et l'erreur renvoyée le lui indique explicitement (D8).

Aucune connexion au WMS n'est tentée au démarrage : un boot propre ne prouve donc pas que le WMS est joignable. Pour cela, voir §5.


4. Cycle de vie du token OAuth

Le token est obtenu paresseusement, à la première requête, puis rafraîchi automatiquement. Réglages dans .env :

Variable Défaut Rôle
TOKEN_REFRESH_THRESHOLD 1000 s âge au-delà duquel un refresh est déclenché avant la requête
TOKEN_MAX_AGE 1190 s âge au-delà duquel on ne tente plus le refresh_token mais une ré-authentification complète
QUERY_TIMEOUT 30000 ms timeout HTTP de toute requête WMS

Séquence observable :

[API] Authenticating profile="LIMAGRAIN" tenant="LIMAGRAI2512" ...
[API] Authentication successful. Token expires in ~1190s
[API] POST /QueryExecute
...  (~17 min plus tard)
[API] Refreshing token with refresh_token grant...
[API] Token refreshed successfully

Trois filets de sécurité, dans cet ordre :

  1. Avant la requête — si âge > TOKEN_REFRESH_THRESHOLD, refresh préventif.
  2. Refresh en échec — bascule automatique sur le grant password ([API] Token refresh failed, re-authenticating).
  3. Réponse 401 — un refresh est déclenché et la requête est rejouée une fois ([API] Unauthorized, refreshing token and retrying...).

Ce qui est normal. Une ligne Token refresh failed isolée suivie d'une authentification réussie : le filet a joué son rôle.

Ce qui ne l'est pas. Ces trois lignes en boucle rapprochée signalent des credentials invalides ou un tenant erroné — le serveur n'abandonne jamais de lui-même, il retentera à chaque requête.


5. Test de bout en bout

npm test

Teste le profil actif ; npm test -- AD cible un profil, npm test -- --all les teste tous. Quatre vérifications en lecture seule, aucune écriture WMS :

Test Ce qu'il prouve
OAuth host joignable, credentials et tenant corrects
QueryExecute API ApplicationService opérationnelle
QueryScalarExecute requêtes scalaires (Count) opérationnelles
AD API (Validator) API Application Dictionary opérationnelle

Sortie attendue :

=== Profil LIMAGRAIN ===
  host=10.255.255.2 tenant=LIMAGRAI2512 saas=false
  OK   OAuth - token obtenu (age max ~1190s)
  OK   QueryExecute - 1 ligne(s)
  OK   QueryScalarExecute - 51160 produit(s)
  OK   AD API (Validator) - 10 element(s)
  -> 4/4 tests reussis

Code de sortie 0 si tout passe, 1 sinon — utilisable tel quel dans une tâche planifiée.

C'est le premier réflexe quand Claude signale une erreur WMS : il isole en quelques secondes une panne de connectivité d'un problème de requête.


6. État des caches

Deux caches, TTL commun WORKFLOW_CACHE_TTL (1 h par défaut), tous deux vidés à chaque switch_wms_profile (D8).

Cache Contenu Purge
workflows ~3 700 workflows TTL, ou bascule de profil
AD un cache par type (20 types, ~38 800 éléments) TTL par type, ou bascule de profil

Les inspecter sans redémarrer : l'outil get_application_summary liste les types chargés et leur nombre d'éléments — un type absent signifie simplement qu'il n'a jamais été demandé dans cette session (D10).

Signature d'un chargement dans les logs :

[AD] Cache expired or empty, fetching Resource...
[AD] Fetching Resource: offset=0, pageSize=15000
[AD] Fetched 15000 Resource (total: 15000)
[AD] Fetching Resource: offset=15000, pageSize=15000
...
[AD] Successfully cached 29374 Resource
[AD] Cache hit: Resource (29374 elements)      <- appels suivants

Une première requête sur Resource prend plusieurs dizaines de secondes : ce n'est pas un blocage, c'est la pagination. Les suivantes sont instantanées.


7. Symptômes → causes

Symptôme Cause probable Vérification
Le serveur n'apparaît pas dans Claude Desktop chemin invalide dans claude_desktop_config.json, ou Claude pas redémarré ouvrir %APPDATA%\Claude\logs\
Unexpected token … is not valid JSON quelque chose a écrit sur stdout chercher un console.log() ajouté (D6)
injecting env (0) .env introuvable en packagé : le placer à côté de l'exe (D7)
No WMS profile selected DEFAULT_WMS_PROFILE absent ou invalide c'est un état normal — appeler switch_wms_profile
Authentication failed: … 400 tenant_code ou credentials erronés npm test -- <PROFIL> (D2)
Boucle refresh failed / Authenticating credentials invalides npm test
ETIMEDOUT / ECONNREFUSED host injoignable (VPN, pare-feu) Test-NetConnection <host> -Port 443
timeout of 30000ms exceeded requête trop lourde ajouter un Where, réduire take, ou augmenter QUERY_TIMEOUT
Successfully cached 0 workflows réponse non enveloppée par entities D4
Recherche vide sur un élément existant casse des propriétés (name vs Name) D5
Log access is disabled for SaaS profile profil SAAS=true comportement voulu (D9), utiliser les outils API
Erreur de compilation LINQ sur une date DateTime.Now employé date littérale (D12)

8. Ce qui n'est pas instrumenté

À connaître avant de promettre une supervision qui n'existe pas :

  • Pas de healthcheck exposé, ni HTTP ni MCP. npm test est le seul contrôle automatisable, et il faut le lancer soi-même.
  • Pas de métriques : ni compteur d'appels, ni latence, ni taux d'erreur.
  • Pas de fichier de log propre au serveur : tout est capté par Claude Desktop, avec sa rotation à lui.
  • Pas d'alerte : une panne d'authentification n'est visible qu'au prochain appel d'un outil.
  • uncaughtException et unhandledRejection sont journalisés mais n'arrêtent pas le processus (src/index.js). Le serveur peut donc survivre dans un état dégradé — d'où l'intérêt de relire les logs jusqu'au début en cas de comportement erratique, et non seulement la dernière erreur.