Agents IA (MCP)

Les capacités exposées par l'API REST sont aussi publiées sous forme d'outils Model Context Protocol, afin qu'un agent IA puisse les utiliser directement.

Un outil n'est pas une implémentation parallèle : il dispatche le même handler que son équivalent REST, sous la même authentification, les mêmes scopes, le même quota et les mêmes règles d'idempotence. Ce qu'un agent ne peut pas faire en REST, il ne peut pas le faire en MCP.

tools/list va un pas plus loin que la découverte REST : il ne renvoie que les outils dont votre jeton porte les scopes. Là où l'OpenAPI liste toutes les routes et ne refuse qu'à l'appel, un outil hors de vos scopes n'apparaît simplement pas — appelé par son nom malgré tout, il répond en nommant le scope manquant.

Se connecter

Endpoint /mcp sur l'hôte de l'API Staff & Go
Transport Streamable HTTP
Authentification Serveur de ressources OAuth 2.1 — les mêmes identifiants partenaire qu'en REST

La découverte suit la RFC 9728 : GET /.well-known/oauth-protected-resource renvoie l'identifiant de la ressource, son serveur d'autorisation et les scopes qu'elle accepte. Un client MCP conforme lit cela et sait où s'authentifier.

Le jeton doit être émis pour l'audience de cette API. Nous n'acceptons jamais un identifiant transmis en passe-plat depuis ailleurs, et un jeton émis pour une autre audience est rejeté — c'est tout l'objet du rattachement d'audience.

Mise en place

L'accès partenaire est machine-to-machine, donc le flux prévu est client_credentials. Beaucoup de clients MCP n'implémentent que le flux interactif par redirection et ne peuvent pas l'exécuter ; coller un en-tête Authorization statique dans un fichier de configuration n'est pas une solution non plus, puisque le jeton expire.

Nous publions un petit proxy stdio exactement pour ce cas : il détient vos identifiants client, émet et rafraîchit le jeton, et parle du MCP stdio simple à votre client. Node 20 ou supérieur est le seul prérequis — le proxy n'a aucune dépendance à installer.

Téléchargement
mcp-stdio-proxy.mjs le proxy — le seul fichier strictement nécessaire
install.mjs enregistre le proxy auprès de Claude Desktop, et écrit un modèle de fichier de réglages si aucun config.yml n'est présent
install.ps1 · install.sh lanceurs pour le précédent

Chaque fichier est servi en texte brut, pour que vous puissiez lire un script dans le navigateur avant de l'exécuter. Faites-le.

Réglages

L'installeur lit ses réglages dans un config.yml posé à côté de lui. Le plus simple est de le télécharger depuis Staffngo : Applications (API), dans le dialogue du secret de votre application, bouton Télécharger la configuration MCP (config.yml). Si aucun config.yml n'est présent, l'installeur écrit à sa place un modèle commenté, à remplacer par le fichier téléchargé ou à remplir à la main. Quatre valeurs vous reviennent :

Réglage
EXTERNAL_MCP_URL https://<votre-hote-api-external>/mcp
KEYCLOAK_TOKEN_URL l'endpoint de jeton de votre serveur d'autorisation — publié, avec les scopes qu'il accepte, sur GET /.well-known/oauth-protected-resource du même hôte : inutile de le deviner
PARTNER_CLIENT_ID · PARTNER_CLIENT_SECRET les identifiants partenaire qui vous ont été remis

Il n'y a rien à déclarer sur les scopes : ceux accordés à votre application sont portés par vos identifiants et entrent dans le jeton sans être réclamés. C'est aussi ce qui fera survivre votre configuration le jour où un administrateur modifiera ce que votre intégration a le droit de lire.

Un réglage ne sert qu'en développement local : NODE_TLS_REJECT_UNAUTHORIZED: "0", présent dans le modèle sous forme de ligne commentée (#) que vous ne décommentez que face à un certificat de développement auto-signé. Node ne lit pas le magasin de certificats du système, donc faire confiance à un certificat de développement au niveau du système ne suffit pas à le lui faire accepter. Face à un hôte avec un vrai certificat, laissez-la commentée.

Le fichier est en clé: valeur plat — le lecteur refuse l'imbrication et les listes plutôt que de les mal lire.

Claude Desktop

Quatre étapes :

  1. Node 20 ou supérieur. node --version vous indique ce qui est installé.

  2. Téléchargez votre config.yml depuis Staffngo : Applications (API), dans le dialogue du secret de votre application, bouton Télécharger la configuration MCP (config.yml). Il contient déjà les quatre valeurs.

  3. Téléchargez les scripts (tableau ci-dessus) dans le même dossier que config.yml, puis lancez l'installeur :

    ./install.sh              # macOS / Linux
    .\install.ps1             # Windows (PowerShell)
    

    Sous Windows, si PowerShell refuse d'exécuter install.ps1 (politique d'exécution Restricted, ou invite « éditeur non approuvé »), lancez à la place node install.mjs : Node n'est pas soumis à cette politique, et c'est exactement le même installeur.

  4. Quittez Claude Desktop complètement — depuis la zone de notification, pas seulement la fenêtre — puis relancez-le. La configuration n'est relue qu'au démarrage. Le connecteur apparaît sous le nom staffngo.

L'installeur copie le proxy à côté de la configuration de Claude et fusionne une seule entrée dans claude_desktop_config.json, en conservant toutes les autres clés et tous les autres serveurs. Il sauvegarde le fichier au préalable (.bak-<horodatage>), et --dry-run montre exactement ce qui changerait sans rien écrire.

Sans config.yml, l'installeur écrit un modèle à côté de lui, vous l'indique et s'arrête sans erreur : remplacez-le par le fichier téléchargé (ou renseignez les quatre valeurs), puis relancez-le. C'est un repli, pas une étape du parcours.

Vous aviez déjà installé le MCP ? L'ancienne entrée external n'est pas renommée par l'installeur. Supprimez-la à la main de claude_desktop_config.json (une sauvegarde .bak-<horodatage> est faite à chaque écriture), puis relancez l'installeur. Pour enregistrer plusieurs environnements côte à côte, donnez un nom à chacun avec --name — par exemple --name staffngo-staging --config config.staging.yml.

Pour le faire à la main, le fichier se trouve ici :

Plateforme Chemin
Windows — version Store (MSIX) %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\
Windows — installeur classique %APPDATA%\Claude\
macOS ~/Library/Application Support/Claude/
Linux ~/.config/Claude/

La version Store est un paquet MSIX, et MSIX redirige %APPDATA% — sa configuration n'est donc jamais sous %APPDATA%\Claude, ce qui explique qu'on ne trouve rien en cherchant là. Le dossier n'apparaît qu'après un premier lancement de Claude Desktop.

Claude Code

Claude Code lit .mcp.json à la racine du projet, sous une clé mcpServers :

{
  "mcpServers": {
    "staffngo": {
      "command": "node",
      "args": ["/chemin/absolu/vers/mcp-stdio-proxy.mjs"],
      "env": {
        "EXTERNAL_MCP_URL": "https://<votre-hote-api-external>/mcp",
        "KEYCLOAK_TOKEN_URL": "https://<votre-serveur-autorisation>/realms/<realm>/protocol/openid-connect/token",
        "PARTNER_CLIENT_ID": "<votre client id>",
        "PARTNER_CLIENT_SECRET": "<votre secret client>"
      }
    }
  }
}

.mcp.json est committé par convention : mettez plutôt un fichier contenant un secret dans votre configuration non suivie.

VS Code

VS Code lit .vscode/mcp.json, dont les serveurs vivent sous une clé servers et non mcpServers. Le triplet command / args / env est identique au bloc ci-dessus. Vérifiez le schéma exact dans la documentation de votre version de VS Code — il a changé plus d'une fois.

Tout autre client stdio

Tout ce qui précède, ce sont les trois mêmes valeurs dans des emballages différents. Quel que soit le nom que votre client donne à sa configuration, il lui faut :

Utilisez des chemins absolus. Votre client démarre le process lui-même, hors de tout shell qui résoudrait un chemin relatif, un lien symbolique ou un alias.

Si le serveur n'apparaît pas, le proxy écrit ses diagnostics ([mcp-proxy] …) sur stderr, jamais sur stdout qui porte le flux JSON-RPC. Cherchez-les dans les journaux de votre client.

La seule chose qui vous coûtera une après-midi

Ne déclarez aucun scope côté client. Les scopes accordés à votre application sont portés par vos identifiants et entrent dans le jeton d'eux-mêmes : il n'y a rien à lister dans config.yml ni dans la configuration de votre client. Un outil dont votre jeton n'a pas les scopes est absent de tools/list — vous n'obtenez aucun refus qui l'expliquerait, vous ne voyez simplement jamais l'outil. Si un agent vous dit qu'une capacité n'existe pas, vérifiez d'abord dans Staffngo, menu Applications (API), les scopes accordés à votre application.

S'en servir dans un chat

Vous n'appelez pas les outils vous-même — vous demandez en langage naturel et l'agent choisit. Commencez par lui faire dire ce qu'il a, ce qui vaut aussi comme test que vos scopes sont bien passés :

Quels outils te donne le connecteur staffngo ? Liste-les avec ce que fait chacun.

Ensuite, demandez la chose, pas l'outil :

Ce que vous tapez Ce qu'il va chercher
À quoi mon accès partenaire a-t-il droit ? Quels modules sont actifs ? le profil partenaire
Liste les types de congé disponibles. une lecture de référentiel
Donne-moi les dix premiers salariés, avec leur fonction et leur manager. la liste des salariés
Prends le premier et montre-moi ses contrats de travail. les contrats de ce salarié
Quelles absences entre le 1er et le 30 septembre ? les lignes de congé, avec une fenêtre de dates
Et ses soldes de congés ? les soldes de ce salarié
Montre-moi la trace d'audit de ce que tu viens de faire. la piste d'audit

Le chaînage est là que c'est le plus utile. Les identifiants sont opaques : vous ne pouvez pas en taper un de mémoire. Le flux naturel est donc liste → « prends celui-là » → détail, et l'agent reporte l'identifiant tout seul. C'est la séquence qu'une intégration doit exécuter de toute façon ; le chat la rend simplement confortable.

Trois choses ressembleront à des pannes sans en être :

Une mise en garde à dire franchement : ces réponses portent des données personnelles, et dans un chat elles entrent dans la conversation et y restent. Pour montrer la forme d'une réponse à quelqu'un, préférez une ligne de test à un vrai dossier.

Nommage des outils et versions

Les noms d'outils sont stables et portent leur version dès qu'il en existe plusieurs — get_partner_profile et get_partner_profile_v2 sont deux outils distincts, aux contrats distincts. Épinglez celui que vous visez ; un nom ne change jamais de sens en silence.

Indications de sûreté

Chaque outil déclare ce qu'il fait, pour qu'un framework d'agent puisse décider s'il faut demander à un humain d'abord :

Indication Signification
ReadOnly Ne modifie rien.
Idempotent Répéter l'appel a le même effet que l'appeler une fois.
Destructive Produit un effet qui ne se défait pas trivialement.
OpenWorld Touche un état au-delà de cette API.

Servez-vous-en. Un outil marqué Destructive est un outil où la boucle de réessai d'un agent a des conséquences réelles : exigez une confirmation humaine, et envoyez un Idempotency-Key pour qu'un réessai ne puisse pas doubler l'effet. Voir Idempotence.

Quota

Les appels MCP et les appels REST partagent un seul compteur par tenant. Un agent qui interroge en boucle consomme le budget dont votre intégration a aussi besoin, et les en-têtes RateLimit s'appliquent de la même manière — voir Limites de débit.