Serveur MCP "sensaas-connecteur"
En bref
sensaas-connecteur est un petit serveur MCP (Model Context Protocol) qui donne à une IA deux
capacités sur l'API v2 : découvrir la surface (groupes, opérations, paramètres, conventions)
à partir du contrat OpenAPI, et l'appeler réellement (connexion, paramètres transverses,
enveloppe déballée, erreurs ProblemDetails). Six outils, aucune configuration côté connecteur.
C'est l'outil à mettre en place quand une IA, assistant de développement ou agent d'intégration, doit écrire ou exécuter du code contre l'API SenSaaS v2 sans qu'on lui recopie la documentation.
Il complète deux autres serveurs MCP qui visent la bibliothèque d'interopérabilité et le schéma SQL de Sage : ici, la cible est l'API HTTP v2 telle que le connecteur l'expose.
Prérequis
Le connecteur doit servir la spécification OpenAPI v2. C'est le cas par défaut : le contrat JSON est
toujours exposé sur /swagger/v2/swagger.json (anonyme, aucune donnée métier), même quand
l'outil de test est désactivé. C'est cette adresse que le serveur MCP interroge. Voir
Démarrer avec l'API v2.
Le script se trouve dans le dépôt du connecteur, sous Serveur/mcp/sensaas_connecteur_mcp_server.py.
Variables d'environnement
| Variable | Rôle | Défaut |
|---|---|---|
SENSAAS_BASE_URL |
URL de base du connecteur | https://localhost |
SENSAAS_USER |
identifiant pour la connexion automatique (sensaas_login sans argument) |
aucun |
SENSAAS_PASSWORD |
mot de passe associé | aucun |
SENSAAS_TOKEN |
jeton déjà obtenu ; court-circuite la connexion | aucun |
SENSAAS_VERIFY_TLS |
1 pour vérifier le certificat TLS |
0 (accepte un certificat auto-signé interne) |
SENSAAS_OPENAPI |
URL ou chemin d'un contrat v2 exporté, pour une découverte hors ligne | aucun |
SENSAAS_TOKEN est transmis tel quel en en-tête Authorization: Bearer. Le connecteur acceptant
aussi les jetons d'accès du serveur d'identité SenSaaS, un tel jeton peut y être placé ; il est alors
associé à l'utilisateur du connecteur de même adresse email (voir
Sécurité).
Le mot de passe est un secret
SENSAAS_PASSWORD et SENSAAS_TOKEN sont des identifiants de connexion au connecteur : passez
par le gestionnaire de secrets de votre poste ou de votre chaîne d'intégration, jamais par un
fichier versionné. SENSAAS_VERIFY_TLS=0 ne doit rester à 0 que face au certificat
auto-signé d'une installation interne.
Déclaration
Le serveur se déclare dans un fichier .mcp.json, à la racine du projet où travaille l'IA :
{
"mcpServers": {
"sensaas-connecteur": {
"command": "python",
"args": ["C:\\Projets\\SenSaaS\\Serveur\\mcp\\sensaas_connecteur_mcp_server.py"],
"env": { "SENSAAS_BASE_URL": "https://localhost" }
}
}
}
Adaptez le chemin du script et SENSAAS_BASE_URL à votre installation. Les identifiants se
renseignent dans env ou dans l'environnement du poste.
Les six outils
Découverte
| Outil | Rôle |
|---|---|
sensaas_groups |
Liste les groupes fonctionnels (les tags du contrat) avec leur nombre d'opérations, regroupés par catégorie de tête. |
sensaas_endpoints |
Liste les opérations : méthode, chemin, groupe, résumé. Filtres groupe (préfixe de groupe) et recherche (sous-chaîne dans le chemin, le groupe ou le résumé). |
sensaas_endpoint |
Détail d'une opération : paramètres de chemin et de requête, schéma du corps, réponses. Le chemin se donne sous sa forme de gabarit, par exemple /v2/entites/{entite}/{cle}. |
sensaas_conventions |
Rappelle l'enveloppe, le format d'erreur et les codes à traiter, les paramètres transverses, les règles d'écriture, le statut des routes historiques et l'authentification. À lire avant tout appel. |
sensaas_conventions résume notamment :
- les codes d'erreur courants, dont
AUTH.FORBIDDEN(droit retiré),DOSSIER.CONFLICT,SAGE.READONLYavecsageDetail,SAGE.IN_USE,QUERY.INVALID,CONFIG.INCOMPLETEetPDF.GENERATION; - la priorité de
?targets=sur la cible écrite dans le corps ; - les écritures : JSON partiel du DTO, objets documents spécialisés par domaine, transformations et
barèmes en
POST, écritures comptables saisies par pièce équilibrée sur/v2/ecriturepieceet modifiées seulement sur/v2/ecriture; - les routes historiques, obsolètes et à ne pas appeler.
Intégration
| Outil | Rôle |
|---|---|
sensaas_login |
Authentifie avec identifiant et mot de passe (POST /v2/auth/login) et mémorise le jeton pour les appels suivants. Sans argument, utilise SENSAAS_USER et SENSAAS_PASSWORD. Ne renvoie jamais le jeton en clair. |
sensaas_call |
Appelle une opération : méthode, chemin concret, paramètres de requête, corps. Injecte le jeton mémorisé, sauf si auth vaut False pour les opérations anonymes. |
sensaas_call normalise déjà la réponse :
| Situation | Ce que l'outil renvoie |
|---|---|
| Succès JSON emballé | { status, data, meta } : l'enveloppe est déballée |
| Succès JSON non emballé | { status, data } |
Erreur, ou application/problem+json |
{ status, problem } : le ProblemDetails complet |
| Contenu binaire (PDF, image) | { status, contentType, bytes } : le contenu n'est pas renvoyé, à récupérer en HTTP direct |
Le serveur expose en plus une ressource sensaas-connecteur://overview : un aperçu court du
connecteur et de la surface v2, que l'IA peut lire d'entrée de jeu.
Scénario d'intégration par une IA
L'enchaînement recommandé, du général au particulier :
sensaas_conventions() # comprendre l'enveloppe et les paramètres
sensaas_groups() # Auth, Kpi, Catalogue, Documents, …
sensaas_endpoints(groupe="Kpi") # GET /v2/kpi, /v2/kpi/{type}, …
sensaas_login() # via SENSAAS_USER / SENSAAS_PASSWORD
sensaas_call("GET", "/v2/kpi/clients-ca", query={"targets": "DEMO", "limit": 50})
sensaas_call("POST", "/v2/entites/famille", body={"reference": "F001", "intitule": "…"})
Quatre règles à donner à l'IA en même temps que l'accès :
- Lire les conventions avant d'appeler. L'enveloppe,
targetset le format d'erreur conditionnent tout le code qu'elle produira. - Une écriture vise un seul dossier. Plusieurs valeurs dans
targetsrenvoientDOSSIER.AMBIGUOUS. - Se brancher sur
code, pas surtitle. La taxonomie est stable, les textes ne le sont pas. - Ne pas insister sur un refus de droits. Un
403(AUTH.FORBIDDEN,AUTH.UTILISATEUR_INCONNU,DOSSIER.NOT_AUTHORIZED) ne se résout pas en renouvelant le jeton : il se règle dans l'outil de configuration.
Écritures sur un dossier réel
sensaas_call écrit vraiment dans Sage : les écritures v2 sont activées par défaut sur le
connecteur. Faites travailler l'IA sur un dossier de démonstration, jamais sur un dossier de
production.
Vérifier l'installation
Le test valide le chargement du script et les conventions ; si le connecteur est joignable, il
enchaîne sur la découverte du contrat OpenAPI et compte les opérations du groupe Kpi. Sortie
attendue, en résumé :
Base : https://localhost | VerifyTLS : False | OpenAPI override : (défaut)
[ OK ] conventions : N sections, paramètres = ['targets', 'limit', 'offset']
[ OK ] groupes : N catégories, N endpoints
[ OK ] endpoints Kpi : N
Un [SKIP] sur la découverte signifie que le contrat n'a pas été atteint : vérifiez
SENSAAS_BASE_URL, que le connecteur est démarré et joignable en TLS, ou fournissez un contrat
exporté via SENSAAS_OPENAPI.
Questions fréquentes
Faut-il que le connecteur soit joignable pour la découverte ?
Non. En renseignant SENSAAS_OPENAPI avec le chemin d'un contrat v2 exporté, la découverte
fonctionne hors ligne. Seuls sensaas_login et sensaas_call exigent un connecteur joignable.
L'IA peut-elle récupérer un PDF ou une image ?
Elle voit le type et la taille du contenu, mais pas le contenu lui-même : les binaires ne transitent pas par le serveur MCP. Il faut un appel HTTP direct.
Le jeton est-il exposé ?
Non. sensaas_login confirme seulement que le jeton a été mémorisé ; il reste en mémoire du
processus et est injecté par sensaas_call.
Le jeton du connecteur expire au bout de 20 minutes : que fait l'IA ?
sensaas_call renvoie alors le ProblemDetails 401 (AUTH.TOKEN_EXPIRED) ; il suffit de
relancer sensaas_login, puis de rejouer l'appel.