MCP Registry : comment publier un serveur de gouvernance IA

Publier un serveur MCP prend vingt minutes. Publier un serveur de gouvernance sans mentir sur ce qu'il fait demande une étape de plus — celle que ce guide met en premier.

Michel Fotsing, CISSP8 minRead in EnglishVersion Markdown

Le registre officiel Model Context Protocol est l'annuaire que consultent les clients MCP pour découvrir des serveurs. Y figurer, c'est être trouvable par quelqu'un qui cherche « compliance » ou « policy » sans connaître votre nom. Ne pas y figurer, c'est exister uniquement pour ceux à qui vous avez envoyé une URL.

Ce guide est la procédure telle qu'elle s'est réellement déroulée pour un serveur de gouvernance — y compris les deux endroits où elle s'est arrêtée net.

Étape 0 — Ne publiez pas avant que la promesse soit vraie

Avant de toucher au registre, quatre vérifications contre la production, pas contre votre machine. Elles prennent une minute et évitent le seul échec irréparable de cette procédure : un serveur listé qui ne tient pas sa description.

# 1. le site répond
curl -s -o /dev/null -w "%{http_code}\n" https://votre-domaine.tld/

# 2. la signature est ACTIVE — bloquant si le manifeste dit "signed evidence"
curl -s https://votre-domaine.tld/.well-known/votre-authority.json | grep -o '"status":"[a-z]*"'

# 3. l'endpoint MCP répond et liste l'outil annoncé
curl -s https://votre-domaine.tld/api/mcp-http \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

# 4. le manifeste est servi en JSON (et pas une redirection)
curl -sL -o /dev/null -w "%{http_code} %{size_download}\n" \
  https://votre-domaine.tld/.well-known/mcp-server.json
La quatrième vérification n'est pas décorative : voir la ligne « 15 octets » du tableau de dépannage.

Étape 1 — Choisir l'espace de noms (décision quasi irréversible)

L'espace de noms détermine la méthode d'authentification et la lecture que le marché fait de vous. Changer après publication crée un doublon, et le nom fait partie de l'identité que les clients mémorisent.

Espace de nomsNom du serveurAuthentificationLecture par le marché
Domaineca.exemple/mcpDNS TXT (Ed25519) ou fichier HTTPproduit d'entreprise
GitHubio.github.pseudo/serveurmcp-publisher login githubprojet personnel

Pour un serveur de gouvernance, le domaine n'est pas un choix esthétique : la preuve de propriété du domaine est l'affirmation d'identité sur laquelle repose la confiance dans vos décisions. Un serveur qui prétend arbitrer des questions de conformité depuis un pseudonyme GitHub demande beaucoup à ses appelants.

Étape 2 — Écrire server.json

Le manifeste minimal viable pour un serveur distant. Deux contraintes attrapent presque tout le monde : le nom doit être en DNS inversé, et la description est limitée à 100 caractères.

{
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "name": "ca.structureclerk/mcp",
  "title": "StructureClerk",
  "description": "AI agent policy decisions: ALLOW, DENY, APPROVE, ESCALATE. Signed evidence.",
  "version": "2.0.0",
  "websiteUrl": "https://structureclerk.ca/authority",
  "remotes": [
    { "type": "streamable-http", "url": "https://structureclerk.ca/api/mcp-http" }
  ]
}

Conseil de maintenance : gardez ce fichier dans le dépôt (par exemple sous public/.well-known/mcp-server.json), servi publiquement, et copiez-le en server.json au moment de publier. Un manifeste qui n'existe que sur le poste de celui qui a publié devient faux au premier changement d'outil, et personne ne s'en aperçoit.

Étape 3 — La partie qui bloque : la clé Ed25519

La documentation dit « prouvez la propriété du domaine par DNS ». On imagine un jeton affiché par l'outil, à coller dans la zone DNS. Ce n'est pas ça. C'est vous qui générez une paire de clés Ed25519 : la clé publique va dans l'enregistrement TXT, la clé privée est passée à l'outil en hexadécimal.

Lancer mcp-publisher login dns --domain exemple.tld sans clé donne exactement ceci, et rien d'autre :

Error: ed25519 private key (hex) is required

Les trois commandes qui débloquent :

# 1. an Ed25519 keypair (the private key never leaves your machine)
openssl genpkey -algorithm Ed25519 -out key.pem

# 2. the PUBLIC key, base64, for the DNS record
PUBLIC_KEY="$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)"
echo "v=MCPv1; k=ed25519; p=${PUBLIC_KEY}"

# 3. the PRIVATE key, hex — this is what the CLI asks for
PRIVATE_KEY="$(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n')"
  • L'enregistrement TXT va sur l'apex du domaine (exemple.tld, pas _mcp.exemple.tld), avec pour valeur exactement v=MCPv1; k=ed25519; p=<clé publique base64>.
  • Sur macOS, openssl est LibreSSL par défaut et n'implémente pas Ed25519 : installez OpenSSL 3 (Homebrew) et appelez ce binaire-là.
  • Sur Windows, cmd.exe n'interprète ni $HOME ni $(...). Utilisez le terminal Git Bash livré avec Git for Windows — ces commandes y fonctionnent telles quelles.
  • La clé privée ne se met nulle part d'autre : ni dans le dépôt, ni dans le manifeste, ni dans un CI. C'est elle qui prouve que vous êtes le domaine.

Attendez la propagation DNS avant de continuer. dig TXT exemple.tld doit renvoyer votre enregistrement ; comptez 5 à 30 minutes selon le registrar. Et gardez l'enregistrement en place après coup : le registre peut revérifier.

Étape 4 — Publier

  1. 1

    Installer l'outil

    mcp-publisher est distribué en binaire de release. Sous Windows, le binaire téléchargé n'est pas dans le PATH : appelez-le par son chemin complet, ou ajoutez son dossier au PATH.

    brew install mcp-publisher   # macOS
    # Linux / Windows : binaire de release du dépôt modelcontextprotocol/registry
  2. 2

    S'authentifier auprès du registre

    Avec la clé privée hexadécimale produite à l'étape 3, et le domaine dont l'enregistrement TXT est propagé.

    mcp-publisher login dns --domain exemple.tld --private-key "${PRIVATE_KEY}"
  3. 3

    Publier depuis le dossier qui contient server.json

    L'outil valide localement avant d'envoyer. S'il refuse, le message cite le champ fautif : corrigez-le dans le fichier source du dépôt, pas seulement dans la copie jetable.

    cp public/.well-known/mcp-server.json ./server.json
    mcp-publisher publish
  4. 4

    Vérifier le référencement

    Puis le seul test qui compte vraiment : le parcours d'un utilisateur réel, dans un client MCP, qui cherche votre serveur par mot-clé, l'ajoute, et lui pose une question de son métier.

    curl -s "https://registry.modelcontextprotocol.io/v0/servers?search=exemple"

Ce que la publication d'un serveur de gouvernance impose en plus

Un serveur qui convertit des devises peut se contenter d'être correct. Un serveur qui répond « cet agent a-t-il le droit ? » engage l'appelant devant un tiers : régulateur, client, auditeur. Cinq exigences en découlent, aucune imposée par le registre — elles sont imposées par la nature de la réponse.

  1. Déterminisme. La même question doit donner la même réponse. Un moteur de gouvernance qui échantillonne ne peut pas être audité ; le nôtre est une table de règles pure, sans LLM dans le chemin de décision.
  2. Citations au bon niveau. Citer un cadre est vérifiable ; citer un article précis comme s'il s'agissait d'un avis juridique est une promesse qu'un moteur ne peut pas tenir.
  3. Fraîcheur publiée. Chaque citation porte sa date de dernière vérification, et la réponse porte celle de sa source la plus ancienne. Un produit de conformité qui cache l'âge de ses données demande à être cru plutôt que vérifié.
  4. Preuve vérifiable sans vous. Empreinte, signature, chaînage, horodatage tiers — et vérification gratuite, sans compte. Une preuve qu'il faut payer pour vérifier n'est pas une preuve.
  5. Statut consultatif affiché. Le manifeste, la réponse et la documentation doivent dire la même chose : le serveur décide, l'infrastructure de l'appelant applique.

Déclarez aussi lesquels de vos outils sont facturés. Un agent qui découvre votre serveur dans le registre n'a aucun moyen de deviner qu'un appel coûte quelque chose, et un outil facturé non déclaré est la meilleure façon de perdre la confiance d'un intégrateur en une seule facture.

Dépannage — les erreurs réellement rencontrées

SymptômeCauseCorrection
Error: ed25519 private key (hex) is requiredLa commande login dns attend une clé que vous générez vous-mêmeÉtape 3, puis --private-key <hex>
mcp-publisher : commande non reconnueBinaire téléchargé mais absent du PATHAppeler par chemin complet, ou ajouter le dossier au PATH
Le manifeste téléchargé fait 15 octetscurl sans -L a enregistré le corps d'une redirectioncurl -L, puis vérifier que le fichier contient bien du JSON
openssl genpkey -algorithm Ed25519 échoue (macOS)LibreSSL, livré par défaut, n'implémente pas Ed25519Installer OpenSSL 3 et appeler ce binaire explicitement
login dns échoue en boucleTXT pas encore propagédig TXT exemple.tld, attendre, réessayer
Description rejetéePlus de 100 caractèresRaccourcir dans le fichier source, republier
Le serveur apparaît, les outils échouentProduction pas à jourLe registre référence, il ne proxifie pas : redéployez

Après la publication

  • Garder l'enregistrement DNS TXT en permanence.
  • Incrémenter version dans le manifeste à chaque changement, puis republier avec la même commande.
  • Traiter la description du registre comme une affirmation publique : si elle cesse d'être vraie, elle se corrige le jour même.
  • Noter la date de publication quelque part dans le dépôt — c'est le genre de fait qu'on croit retenir et qu'on ne retient pas.
+Faut-il un domaine pour publier au registre MCP ?

Non : l'authentification GitHub permet de publier sous io.github.<pseudo>/<serveur>. Mais pour un serveur de gouvernance, la preuve de propriété du domaine fait partie de l'argument de confiance, et l'espace de noms est très difficile à changer après coup.

+Où doit être placé l'enregistrement TXT ?

Sur l'apex du domaine, avec la valeur v=MCPv1; k=ed25519; p=<clé publique base64>. Pas sur un sous-domaine, pas sur un sélecteur. Il doit rester en place après la publication, le registre pouvant revérifier la propriété.

+La clé privée doit-elle être conservée ?

Oui, dans votre gestionnaire de secrets : elle sera nécessaire à chaque republication. Elle ne va ni dans le dépôt, ni dans le manifeste, ni dans une variable de CI partagée.

+Le registre exécute-t-il mon serveur ?

Non. Il référence son nom, sa description et son URL. Si votre production tombe ou régresse, le référencement reste intact et pointe vers un serveur cassé — d'où l'étape 0.

+Comment mettre à jour un serveur déjà publié ?

Incrémentez version dans le manifeste et relancez mcp-publisher publish avec la même authentification. Le nom, lui, ne change pas : c'est l'identité que les clients ont mémorisée.

Le serveur décrit ici est réel : ca.structureclerk/mcp expose un outil de décision d'autorité pour agents IA. Sa spécification et son format de preuve sont publics sur la page Autorité.

Mettez vos agents sous autorité

Décisions consultatives ALLOW, DENY, APPROVE, ESCALATE et preuve signée, en REST, A2A et MCP. La vérification de preuve est gratuite et sans compte.