Brancher le serveur MCP

En quittant cette page, vous saurez ce que le serveur MCP de SealTrust autorise un assistant à faire, comment le brancher dans votre client, quels identifiants lui passer, et ce que rend chacun de ses sept outils.

Sur cette page

Le serveur MCP est un petit programme que vous lancez sur votre poste. Il donne à un assistant conversationnel le droit d'interroger l'API publique de SealTrust, en lecture seule. MCP, pour Model Context Protocol, est le protocole normalisé par lequel un assistant appelle des outils extérieurs. En quittant cette page, vous saurez installer le serveur, le déclarer dans votre client, choisir l'identifiant à lui passer et appeler ses sept outils.

Le parcours tient en quatre étapes : vérifier que le périmètre correspond à votre besoin, brancher le serveur dans votre client, apprendre quel identifiant vous avez sous la main, appeler les outils.

#1. Le périmètre, avant tout le reste

Le serveur n'émet que des requêtes GET, vers des points d'entrée publics de https://api.sealtrust.io. Il n'envoie aucune clef d'API et n'en accepte aucune. Aucun de ses outils ne crée, ne modifie ni ne supprime quoi que ce soit.

Conséquence directe : le serveur voit exactement ce que voit un visiteur anonyme qui ouvre un passeport dans son navigateur. Le règlement ESPR distingue plusieurs publics : le public, les consommateurs, les professionnels de la chaîne de valeur et les autorités de surveillance du marché. SealTrust applique cette distinction avec six niveaux d'accès : public, end_user, repairer, recycler, upstream et authority. Ces valeurs sont celles de SealTrust. Le règlement, lui, nomme des publics. Le serveur MCP lit le niveau public et uniquement lui. Les champs réservés aux professionnels ou aux autorités ne sont pas atteignables par ce chemin.

Ce que le serveur annonce à votre client au moment de la connexion : son nom, sealtrust, sa version, et une phrase d'instructions qui rappelle à l'assistant que toutes les données sont publiques et qu'aucun outil ne modifie rien.

#2. Brancher le serveur

Il vous faut Node.js en version 18 ou plus récente. Le paquet s'appelle @sealtrust-io/mcp-server et la dernière version publiée est 0.4.0.

Vous pouvez le lancer directement, ce qui sert à vérifier qu'il démarre.

Terminal
npx @sealtrust-io/mcp-server

Le serveur communique par son entrée et sa sortie standard. Une ligne de démarrage part sur la sortie d'erreur et indique la version ainsi que l'adresse d'API utilisée. La sortie standard est réservée au dialogue avec le client, donc rien d'autre n'y est écrit.

#Déclarer le serveur dans un client

Un client MCP se configure avec une commande et ses arguments. Le bloc ci-dessous est la forme attendue par les clients de bureau, à placer dans leur fichier de configuration.

JSON
{
  "mcpServers": {
    "sealtrust": {
      "command": "npx",
      "args": ["-y", "@sealtrust-io/mcp-server"]
    }
  }
}

En ligne de commande avec Claude Code, la même déclaration s'écrit ainsi.

Terminal
claude mcp add sealtrust -- npx -y @sealtrust-io/mcp-server

Redémarrez le client après avoir modifié sa configuration. Les sept outils apparaissent alors dans sa liste d'outils disponibles.

#Les deux réglages disponibles

Deux variables d'environnement, et deux seulement, changent le comportement du serveur.

VariableValeur par défautEffet
SEALTRUST_API_URLhttps://api.sealtrust.ioL'adresse de l'API interrogée. Les barres obliques finales sont retirées.
SEALTRUST_TIMEOUT_MS15000Le délai maximal d'un appel, en millisecondes. Une valeur qui n'est pas un nombre strictement positif est ignorée, et la valeur par défaut s'applique.

Le délai couvre l'aller-retour complet, en-têtes et corps de réponse compris. Un dépassement rend une erreur de réseau explicite, jamais un blocage silencieux.

Ces deux variables se posent dans la configuration de votre client, sous la clef env. Le bloc ci-dessous est complet et copiable tel quel. Il porte un délai de 30 secondes.

JSON
{
  "mcpServers": {
    "sealtrust": {
      "command": "npx",
      "args": ["-y", "@sealtrust-io/mcp-server"],
      "env": {
        "SEALTRUST_TIMEOUT_MS": "30000"
      }
    }
  }
}

#3. Savoir quel identifiant vous avez

Six outils sur sept prennent un identifiant de produit. Quatre formes existent, et elles ne sont pas acceptées partout.

FormeÀ quoi elle ressembleOù vous la trouvez
Numéro de série12 caractères, chiffres et lettres majuscules, par exemple EXEMP1E00000C'est le seul identifiant lisible sur un produit. Le QR imprimé le porte. Une personne qui a scanné ou recopié une étiquette a celui-là.
Empreinte d'identifiant (uid_hash)0x suivi de 64 caractères hexadécimauxRendue par nos propres réponses. C'est l'identifiant interne du produit. Il vient de la puce NFC quand le produit en porte une. SealTrust le tire au hasard quand le produit est identifié par QR seul.
Identifiant de jetonUne suite de chiffresL'identifiant du jeton en chaîne, rendu sous le nom token_id.
Numéro de certificatCommence par ST-CERT-Sur le certificat d'authenticité. Accepté par verify_product et get_certificate seulement.

L'alphabet du numéro de série exclut les lettres I, L, O et U, pour qu'une personne qui recopie une étiquette ne confonde pas une lettre avec un chiffre. Le serveur MCP transmet le numéro tel qu'on le lui donne, sans réécrire aucun caractère. C'est l'API qui remet le numéro en majuscules et qui ramène les caractères ambigus à leur forme canonique : I et L valent 1, O vaut 0.

Deux outils prennent en plus un GTIN, le code article à 8, 12, 13 ou 14 chiffres. Un GTIN désigne un modèle. Il ne désigne aucun exemplaire en particulier.

#4. Les sept outils

#verify_product

Répond à la question « ce produit est-il authentique ». L'outil enchaîne deux appels : la résolution de l'identifiant, puis la lecture du certificat.

ParamètreTypeObligatoireDescription
identifierstringouiNuméro de série, empreinte d'identifiant, identifiant de jeton ou numéro de certificat.

La réponse porte un champ status qui prend cinq valeurs.

ValeurCe qu'elle signifie
authenticUn certificat d'authenticité actif est enregistré.
revokedLe certificat a été révoqué. Le produit est à traiter comme suspect.
expiredLe certificat a dépassé sa date de fin.
found_no_certificateLe produit existe dans le registre et aucun certificat actif n'y est rattaché.
unknownAucune trace de cet identifiant.

Viennent avec : un champ message en clair, un bloc product qui porte le nom du produit, le nom de la marque, la catégorie, l'identifiant de jeton, l'empreinte d'identifiant, l'adresse du contrat, l'opération de frappe et la date de création, un bloc certificate ou la valeur nulle, un booléen has_published_passport, et un booléen anchored_on_base.

anchored_on_base vaut vrai quand un ancrage existe, quel qu'il soit : celui du lot de produits, ou celui du contenu du passeport. Les deux sont indépendants. Un passeport peut être ancré alors que son lot ne l'a pas été, et l'inverse. Pour savoir lequel des deux, et avec quelle opération, appelez get_passport_proof.

Attendez-vous à ce que ce booléen vaille faux la plupart du temps. L'ancrage est une opération que SealTrust déclenche à la main. Une demande d'ancrage venue d'un compte de marque est refusée. Frapper un produit ne l'ancre pas, et publier un passeport ne l'ancre pas non plus. La plupart des produits ne sont jamais ancrés. Un anchored_on_base à faux ne dit donc rien contre le produit, et votre assistant ne doit jamais le présenter comme un soupçon.

#get_passport

Rend le passeport numérique publié, au niveau d'accès public.

ParamètreTypeObligatoireDescription
identifierstringouiNuméro de série, empreinte d'identifiant ou identifiant de jeton. Un numéro de certificat n'est pas accepté ici.
formatstringnonjson par défaut, ou jsonld pour une représentation en vocabulaire Schema.org et GS1. Toute autre valeur est refusée avant l'appel réseau.

La réponse au format par défaut porte la version du passeport, le contenu publié sous le champ data, l'empreinte SHA-256 de ce contenu sous data_hash, le nom du produit et de la marque, le GTIN et le lien GS1 Digital Link du produit.

Les deux champs qui pointent vers la copie IPFS valent toujours la valeur nulle sur ce chemin. Ils sont réservés aux niveaux d'accès authentifiés. Le lien vers la copie immuable, quand elle est publiée, apparaît dans la réponse de get_passport_proof.

#get_passport_proof

Rend les preuves publiques qui permettent de vérifier un passeport sans nous faire confiance.

ParamètreTypeObligatoireDescription
identifierstringnonL'exemplaire dont vous voulez la preuve.
gtinstringnonLe modèle dont vous voulez la preuve, au niveau référence.

Vous devez fournir exactement l'un des deux. Aucun des deux, ou les deux à la fois, donne un refus immédiat avec un message qui explique la différence. Les deux paramètres ne désignent pas la même chose : la preuve d'un exemplaire date l'objet, la preuve d'une référence date le document.

La réponse contient l'empreinte du contenu, le lien vers la copie IPFS quand elle est publiée, un bloc seal qui dit si la version est scellée et si son contenu correspond encore à ce qui a été scellé, l'état d'émission de l'attestation vérifiable, et le nombre de vérifications physiques réussies. Une preuve absente est absente de la réponse, sans champ vide.

Un passeport de niveau référence, celui qu'on obtient avec gtin, ne porte légitimement ni bloc anchor ni compte de vérifications. Il n'est lié à aucun exemplaire physique. Sa preuve est l'ancrage de son propre contenu, qui date le document. La réponse porte alors level: "model" et le GTIN normalisé.

#get_product_history

Rend l'historique d'un produit : les mouvements de propriété et les scans d'authentification, réunis dans une seule chronologie, du plus récent au plus ancien. Le premier élément de timeline est l'événement le plus récent.

ParamètreTypeObligatoireDescription
identifierstringouiNuméro de série, empreinte d'identifiant ou identifiant de jeton.

Chaque entrée porte un champ type qui vaut verify pour un scan ou transfer pour un mouvement de propriété, un horodatage, l'identifiant de jeton et l'empreinte d'identifiant. Le reste dépend du type. Une entrée verify porte un indicateur de validité et aucun libellé de partie. Une entrée transfer porte deux libellés prêts à l'affichage, pour la partie qui cède et celle qui reçoit, et aucun indicateur de validité.

Pour un appelant anonyme, et le serveur MCP en est un, les identités sont masquées : les adresses électroniques sont anonymisées et les adresses de portefeuille brutes ne sont pas rendues.

#get_certificate

Rend le certificat d'authenticité public d'un produit.

ParamètreTypeObligatoireDescription
identifierstringouiNuméro de série, empreinte d'identifiant, identifiant de jeton ou numéro de certificat.

La réponse porte le numéro du certificat, son état, sa date d'émission, sa date de fin quand elle existe, le nom de l'émetteur, le nom du produit et celui de la marque, ainsi que les champs personnalisés enregistrés à l'émission, rendus tels quels. Tout ce qui y est écrit est public.

#resolve_gs1

Part d'un lien GS1 Digital Link et rend le passeport qu'il désigne.

ParamètreTypeObligatoireDescription
gtinstringouiLe code article du modèle.
serialstringnonLe numéro de série imprimé sur l'exemplaire. Omettez-le pour viser le modèle.

La présence du numéro de série change ce que le lien désigne. Avec lui, le lien /01/{gtin}/21/{serial} désigne un exemplaire précis et la réponse porte level: "item". Sans lui, le lien /01/{gtin} désigne la classe d'articles et rend le passeport de niveau référence, celui que partagent tous les exemplaires du modèle, avec level: "model". C'est ce second niveau qu'utilisent les marchandises vendues au mètre, à la boîte ou à la palette. Une chaîne vide dans serial est lue comme une absence.

La réponse porte aussi le lien reconstruit, l'adresse vers laquelle la résolution redirige, l'identifiant retenu, et le passeport public quand il en existe un.

Sans passeport de référence publié, /01/{gtin} répond 404 et l'outil rend found: false avec le message « Unknown GS1 Digital Link ». Le résultat resolved: true accompagné d'un passeport nul ne survient que lorsque vous fournissez un serial et que cet exemplaire n'a pas de passeport publié.

Le numéro de série attendu ici est bien celui qui est imprimé sur le produit. L'identifiant de jeton en chaîne ne convient pas à cet endroit.

#verify_credential

Vérifie la signature de l'attestation vérifiable du passeport, au format SD-JWT-VC, contre la clef publiée par la marque émettrice sous la forme did:web.

ParamètreTypeObligatoireDescription
identifierstringouiNuméro de série, empreinte d'identifiant ou identifiant de jeton.

La réponse porte verified, l'identifiant décentralisé de l'émetteur, le type de l'attestation, la version de la clef de signature, le niveau d'accès appliqué, un champ error valant verification_failed en cas d'échec, et le contenu de l'attestation quand la signature est valide.

#5. Lire les réponses et les erreurs

Le serveur sépare trois situations, et cette séparation compte pour un assistant qui raisonne sur le résultat.

SituationCe que rend le serveurCe qu'il faut en conclure
Produit, passeport ou attestation introuvableUn résultat normal portant found: false et le message de l'API, ou status: "unknown" pour verify_productLa question a reçu une réponse. Rien ne s'est cassé.
Réponse d'erreur de l'API autre qu'un 404Une erreur d'outil dont le message s'écrit SealTrust API error (, le code HTTP, ): , puis le détail rendu par l'API. Il n'y a aucune espace avant les deux-points.L'API a répondu et a refusé. Le code dit pourquoi.
API injoignable, délai dépassé, DNS, connexion refuséeUne erreur d'outil qui commence par Network errorAucune information sur le produit. Ne concluez rien sur son authenticité.

Un argument mal formé est refusé avant tout appel réseau : un identifiant vide, un format qui n'est ni json ni jsonld, ou l'absence de choix entre identifier et gtin sur la preuve.

#6. Les plafonds d'appels

Les points d'entrée publics sont plafonnés par adresse IP appelante, sur une fenêtre de 60 secondes. Les familles de chemins qui ont un plafond à elles tiennent chacune leur propre compteur. Les autres relèvent d'un compteur général, commun à toutes les routes sans plafond dédié.

OutilChemin appeléPlafond
verify_productrésolution, puis certificat60 par minute sur chacun des deux
get_passport, get_passport_proof, verify_credentialpasseport60 par minute
get_certificatecertificat60 par minute
get_product_historychronologie30 par minute
resolve_gs1résolution GS1, puis passeportcompteur général sur la résolution GS1, partagé avec les autres chemins sans plafond propre, puis 60 par minute sur le passeport

Deux outils consomment deux appels au lieu d'un. verify_product interroge la résolution puis le certificat. resolve_gs1 lit la redirection du résolveur sans la suivre, puis demande le passeport directement. Comptez-les comme deux.

Un dépassement rend une réponse 429, que le serveur remonte en erreur d'outil. Un cas fait exception. Sur verify_product, seul le premier appel remonte un 429. Un dépassement sur la lecture du certificat est journalisé sur la sortie d'erreur et l'outil répond quand même, avec le certificat résumé que porte déjà la résolution.

#Ce qui peut vous arrêter

SymptômeCauseQue faire
Le client ne montre aucun outilLe serveur n'a pas démarré, ou le client n'a pas été redémarré après la modification de sa configurationLancez npx @sealtrust-io/mcp-server à la main. La ligne de démarrage doit apparaître. Redémarrez ensuite le client.
Network error sur tous les outilsL'API n'est pas joignable depuis la machine, ou SEALTRUST_API_URL pointe ailleursVérifiez la variable, puis la sortie réseau de la machine.
Un appel dépasse systématiquement le délaiLe délai de 15 secondes est trop court pour votre liaisonAugmentez SEALTRUST_TIMEOUT_MS sous la clef env de la configuration de votre client, comme au point 2, puis redémarrez le client.
found: false sur un identifiant que vous savez justeLa forme utilisée n'est pas acceptée par cet outilVérifiez la forme dans le tableau des identifiants. Un numéro de certificat ne passe que sur verify_product et get_certificate.
Les outils se contredisent sur un exemplaire retiré du marchéChaque outil traite la fin de vie à sa manièreverify_product rend status: "unknown". get_passport_proof et get_certificate rendent found: false. get_passport rend le passeport, assorti d'un bloc lifecycle qui indique que l'exemplaire n'est plus courant.
Le passeport revient sans lien IPFSLe niveau d'accès public ne le porte pasUtilisez get_passport_proof, qui rend le lien vers la copie immuable quand elle est publiée.
Une erreur 429Un plafond d'appels est atteintEspacez les appels. Le compteur repart après 60 secondes.

Votre réponse ouvre un courriel pré-rempli dans votre messagerie, à destination de contact@sealtrust.io. Vous le relisez avant de l'envoyer.

Proposer une correctionSignaler un problème