Aller au contenu

Outils MCP

Endpoint : https://api.prod.aim.dyneco.io/mcp Transport : Streamable HTTP, sans état.

Six outils, volontairement peu nombreux : un agent perd en précision quand on lui propose plusieurs outils voisins, il hésite au lieu d'agir.

Instructions données au serveur

Le serveur annonce lui-même à l'agent comment s'en servir :

Donne accès au contexte des clients chez qui l'utilisateur développe : conventions de code, décisions d'architecture, procédures de livraison, contraintes et pièges connus.

Avant d'écrire ou de modifier du code, appelle conventions avec le chemin du fichier concerné : tu obtiendras uniquement les règles qui s'y appliquent. En cas de doute sur une pratique locale, utilise search plutôt que de supposer — ces clients ont des usages qui ne se devinent pas.

Chaque fait cite sa source ; mentionne-la quand tu justifies une décision.


conventions

L'outil qui change le quotidien.

conventions(client: str, path: str)

Les règles applicables à un fichier précis, plutôt que tout le contexte du client.

{
  "path": "internal/api/payment_handler.go",
  "specific": [
    {
      "id": "nordwind:convention:2989f364c87b",
      "type": "convention",
      "statement": "N'utilise jamais panic en dehors de main.go ; propage les erreurs avec fmt.Errorf(\"contexte: %w\", err).",
      "confidence": 0.95,
      "status": "candidate",
      "scope": ["**/*.go"],
      "detail": "…",
      "sources": ["guide-dev-backend.md"]
    }
  ],
  "always_applicable": [  ]
}
  • specific — les faits dont la portée couvre ce chemin, les plus précis d'abord.
  • always_applicable — les faits sans portée, en version condensée.
search(client: str, query: str, limit: int = 10)

Recherche plein texte dans les faits. À utiliser dès qu'une pratique locale paraît incertaine.

runbook

runbook(client: str, topic: str = "")

Les procédures pas-à-pas : livraison, release, rollback, incident. topic filtre sur l'énoncé, le détail et les étiquettes ; vide, renvoie tout.

fact

fact(client: str, fact_id: str)

Un fait avec sa provenance complète : document et citation exacte. Sert à justifier une décision ou à vérifier qu'une règle n'est pas périmée.

{
  "id": "nordwind:constraint:7f3a91c2",
  "statement": "…",
  "provenance": [
    { "document": "guide-dev-backend.md",
      "quote": "Ne modifie jamais un script de migration déjà mergé sur main" }
  ]
}

context_pack

context_pack(client: str)

Le contexte complet en markdown. Utile au démarrage sur un client dont le dépôt ne contient pas encore de fichier d'instructions. Volumineux : préférer conventions pour une tâche ciblée.

clients

clients()

Les clients accessibles, avec mission, description et dépôts connus. À appeler en premier quand l'agent ignore sur quel client il travaille.


Sécurité

L'authentification se fait par en-tête Authorization: Bearer, avec une clé d'API ou un jeton Entra. La résolution du principal est la même fonction que celle de l'API REST, appelée par un middleware ASGI : il n'existe pas deux contrôles d'accès à garder cohérents.

Un client dont l'appelant n'est pas membre remonte l'erreur « client introuvable », et clients() renvoie une liste vide.

Détails de protocole

  • Le chemin est exactement /mcp, sans redirection. Les routes sont greffées sur l'application principale plutôt que montées sous un préfixe : un montage aurait répondu 307 sur /mcp et n'aurait accepté que /mcp/, or plusieurs clients MCP ne suivent pas une redirection sur un POST et perdent le corps de la requête.
  • Mode sans état : deux requêtes d'un même agent peuvent atterrir sur des réplicas différents sans rien perdre.
  • Le nom d'hôte public est déclaré au contrôle anti-DNS-rebinding du SDK ; sans cela, tout est rejeté en 421.

Vérifier à la main

KEY=aimk_…
API=https://api.prod.aim.dyneco.io

curl -s -X POST "$API/mcp" \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'