MCP et agents de code
Normik est un serveur MCP distant : les agents s'y connectent avec une URL et un token — rien à installer, rien à mettre à jour.
Se connecter
Claude Code, une seule commande :
claude mcp add --transport http normik https://api.normik.io/api/mcp \
--header "Authorization: Bearer $NORMIK_TOKEN"Ou dans un fichier de configuration MCP (.mcp.json) :
{ "mcpServers": { "normik": {
"type": "http",
"url": "https://api.normik.io/api/mcp",
"headers": { "Authorization": "Bearer nmk_…" } } } }Le token borne tout : un token de workspace sert les règles de ce workspace, plus les règles globales héritées.
La surface d'outils
Volontairement réduite — la fenêtre de contexte de votre agent doit servir votre code, pas nos schémas. Trois outils typés sur le chemin critique, deux méta-outils pour le reste :
| Outil | Rôle |
|---|---|
get_playbook | Les règles compactées et un hash de version — les agents mettent en cache tant qu'il ne bouge pas. |
get_rule | Le détail complet et les exemples d'une règle, à la demande. |
report_check | Remonte le pass/fail par règle pour une session de travail — c'est ce qui alimente le dashboard de taux de correction. Envoyez si possible agentName et modelId pour que le dashboard compare quels agents et quels modèles dérivent le plus sur vos règles. |
list_capabilities | Découvrir les capacités secondaires et leurs arguments. |
use_capability | En invoquer une : list_skills, get_skill, get_gate_result, propose_rule, propose_skill, bootstrap_playbook. |
Le flux pré-commit
get_playbook— charger les règles une fois, les réutiliser tant que le hash de version ne bouge pas.- Écrire du code ; avant de committer, contrôler soi-même le diff au regard de chaque règle applicable.
report_checkavec unsessionIdstable (le nom de la branche, par exemple), en listant le pass/fail par règle — plusagentNameetmodelIdquand l'agent les connaît.- Corriger les échecs, remonter à nouveau le résultat — Normik mesure quelles règles cassent le plus, et à quelle fréquence les agents les corrigent avant le commit.
Quand la CI bloque : lire le verdict de la gate
La gate CI fait échouer le build sur les violations de sévérité error. L'agent qui a écrit le code peut lire ce verdict et le corriger, sans qu'un humain ait à coller des logs :
use_capability { "capability": "get_gate_result",
"arguments": { "repo": "acme/api", "sha": "9f21c3d" } }Tous les arguments sont optionnels — repo, sha (complet ou préfixe d'au moins 7 caractères, insensible à la casse) et pr restreignent la recherche ; sans aucun argument, vous obtenez l'analyse la plus récente dans le périmètre du token, qui peut très bien appartenir à un autre repo ou à une autre PR — l'agent est donc invité à vérifier d'abord les repo/pr/sha renvoyés. Les noms de branche ne filtrent rien : la gate enregistre le repo, le numéro de PR et le sha de tête.
Le périmètre du token compte. Un token restreint à un workspace ne voit que les analyses de son propre workspace, plus celles enregistrées sans workspace ; un token au niveau de l'organisation voit toute l'organisation. Si la CI tourne sous un token de workspace client et que l'agent du développeur utilise un autre token de workspace, l'agent ne verra pas cette analyse — donnez-lui un token au niveau de l'organisation. La raison renvoyée avec found: false le dit explicitement.
La réponse est écrite pour un agent, pas pour quelqu'un qui lit un log :
violations[]—path,line,severity,ruleId,ruleTitleet lecommentdu reviewer. Appelezget_rulequand un énoncé demande son texte complet et ses exemples.suggestionsur une violation (peut êtrenull) — une correction courte, écrite à partir du seul diff, sans le reste du repo. Une piste à confronter au code réel, pas un patch à appliquer tel quel.blocking/blockingCount— indiquent si c'est bien une violation de sévérité error qui a fait échouer le build.blockingvautnull, jamaisfalse, quand la réponse ne peut pas être déterminée.violationCount(ce que la gate a enregistré) face àviolationsReturned,violationsUnreadableetdetailComplete. QuanddetailCompletevautfalse, le détail stocké est partiel : le commit ne doit pas être lu comme propre, et le log CI reste la référence.truncatedettruncatedNote— indiquent si seule une partie du diff a été analysée. Pour l'instant, c'estnull(inconnu) : l'enregistrement d'analyse ne le stocke pas, et la ligne partial analysis du log CI fait foi.status: "unavailable"— la gate n'a pas pu analyser le commit (fail-open : pas de clé BYOK, ou incident chez le provider). Rien à corriger ; le merge est simplement passé sans vérification.found: falseavec une raison — aucune analyse ne correspond, dit explicitement plutôt que sous la forme d'une liste vide.
La boucle complète : écrire → bloquer → corriger
- L'agent écrit du code et le contrôle lui-même au regard de
get_playbookavant de committer. - La CI exécute la gate sur le diff poussé ; une violation bloquante fait échouer le check.
- L'agent appelle
get_gate_resultet récupère les violations, le fichier et la ligne. - Il les corrige, revérifie les changements, et appelle
report_check. - L'exécution CI suivante passe — et le dashboard consigne ce qui a cassé, et que ça a été corrigé.
C'est tout l'intérêt d'être présent aux deux moments : Normik est l'outil auquel l'agent parle pendant qu'il écrit et celui qui contrôle la pull request.
Propositions — les agents suggèrent, les humains décident
propose_rule et propose_skill permettent à un agent de codifier une convention qu'il rencontre sans arrêt ; bootstrap_playbook dérive un playbook initial à partir d'échantillons du repo. Tout arrive signalé généré par IA et attend dans la file de revue (sauf si votre organisation a désactivé la validation).Le détail dans Gouvernance.
Skills
list_skills renvoie les noms et une description d'une ligne ; les agents ne chargent le markdown complet d'un skill que lorsqu'il est pertinent. Chaque récupération est comptée — le dashboard montre quels skills servent réellement.