MCP Inspector npx et CLI : comment tester un serveur MCP
MCP Inspector v2 joue le rôle du client pour que vous puissiez tester un serveur MCP seul. Cet article montre comment le lancer avec npx, passer des arguments et des variables d’environnement, utiliser un fichier de configuration, appeler des outils depuis la CLI avec des arguments JSON, lire les codes de sortie, lancer des vérifications en CI avec jq, et corriger les erreurs de stdout et de transport.
Un serveur MCP peut démarrer sans la moindre erreur et rester inutilisable. Le processus tourne, le journal reste silencieux, et le client que vous y branchez affiche une liste d’outils vide ou un vague message « failed to connect ». Avant d’accuser le client, testez le serveur seul. MCP Inspector est l’outil du projet Model Context Protocol pour cette tâche : il joue le rôle du client, effectue le handshake et vous permet de lister et d’appeler tout ce que votre serveur expose. Cet article montre comment le lancer avec npx, comment le piloter depuis la CLI, comment lire ses codes de sortie et comment corriger les erreurs qui font perdre le plus de temps.
💡 Vérification de la version : La plupart des tutoriels en ligne décrivent Inspector v1. La dernière version publiée sur npm au moment de la rédaction est 2.9.0, et la v2 a modifié les ports, les variables d’environnement, les options et les codes de sortie. Toutes les commandes ci-dessous suivent la documentation v2.
Ce que fait MCP Inspector
Inspector est un client MCP conçu pour le débogage. Il démarre votre serveur (stdio) ou s’y connecte (HTTP ou SSE), exécute le handshake initialize et vous montre exactement ce qui revient. Aucun grand modèle de langage n’intervient dans la boucle : quand quelque chose échoue, vous savez que la faute vient du serveur ou de la connexion, et non du comportement du prompt.
Le handshake qu’il vérifie
Le premier appel, initialize, prouve que le serveur parle MCP. La réponse contient quatre éléments qui méritent d’être lus ligne par ligne :
serverInfo : le nom et la version que votre serveur annonce.
protocolVersion : la révision du protocole sur laquelle les deux parties se sont accordées.
capabilities : les fonctionnalités disponibles, comme les outils, les ressources et les prompts.
instructions : le texte facultatif que le serveur transmet aux clients.
Si capabilities n’a pas d’entrée tools, aucun client n’affichera jamais un outil, quel que soit le nombre que vous avez enregistré dans le code. Cette seule vérification explique une grande part des signalements du type « mes outils n’apparaissent pas ».
Interface web, CLI et TUI
Un seul paquet, trois interfaces. L’option de mode doit venir en premier, juste après le nom du paquet.
Mode
Commande
Idéal pour
Interface web
npx @modelcontextprotocol/inspector
Explorer un serveur à la main
CLI
npx @modelcontextprotocol/inspector --cli
Scripts, vérifications rapides, CI
TUI
npx @modelcontextprotocol/inspector --tui
Rester dans le terminal
Utilisez l’interface web pendant le développement, et la CLI lorsque vous avez besoin d’un résultat que vous pouvez reproduire.
Le lancer avec npx
Rien à installer. npx télécharge le paquet, l’exécute et transmet tout ce qui suit le nom du paquet au serveur à tester. Un premier lancement raisonnable tient en une ligne et prend une minute.
Version de Node et ports
La v2 nécessite Node.js 22.19.0 ou plus récent. Exécutez node --version avant tout le reste, car une version d’exécution trop ancienne est la première chose à écarter.
Les changements de ports et de variables piègent ceux qui suivent d’anciens articles. Voici la comparaison rapide :
Réglage
Inspector v1
Inspector v2
Node.js
22.7.5 ou plus récent
22.19.0 ou plus récent
Port de l’interface web
6274
6274
Port du proxy
6277
Supprimé, il n’y a plus de proxy
Variable du jeton d’authentification
MCP_PROXY_AUTH_TOKEN
MCP_INSPECTOR_API_TOKEN (l’ancien nom fonctionne encore en secours)
Fichier de configuration
--config, lecture seule
--config (lecture seule) ou --catalog (en écriture)
Arguments des outils
--tool-arg
--tool-arg et --tool-args-json
Appel d’outil en échec
La chaîne de commandes continuait
Le code de sortie 5 l’arrête
Modifiez le port de l’interface web avec CLIENT_PORT, un entier fixe entre 1 et 65535. La v2 réserve aussi le port 6275 pour le bac à sable MCP Apps et le port 6278 pour le serveur d’origine des applications, donc laissez-les libres.
Un serveur TypeScript sans étape de compilation fonctionne de la même façon, par exemple avec npx @modelcontextprotocol/inspector tsx src/index.ts. La plupart des projets encapsulent la ligne dans un script npm pour que toute l’équipe exécute la même commande :
💡 Le double tiret change de sens. En mode interface web et TUI, tout ce qui suit -- est transmis à votre serveur. En mode CLI, tout ce qui précède -- désigne la cible, et tout ce qui suit est une option d’Inspector. En mode CLI, la commande du serveur doit aussi venir en premier : --cli --method tools/list node build/index.js ignore silencieusement la cible.
Le jeton derrière l’interface
La v2 crée un jeton d’API aléatoire à chaque lancement et l’exige sur chaque route /api/*. Une page ouverte sans lui est rejetée. Définissez vous-même MCP_INSPECTOR_API_TOKEN si vous voulez une valeur stable, et relancez si un onglet signale une erreur, car l’ancien jeton a disparu avec l’ancien processus.
Le serveur web se lie par défaut à 127.0.0.1 via HOST. L’ouvrir à d’autres interfaces demande un DANGEROUSLY_BIND_ALL_INTERFACES explicite, et DANGEROUSLY_OMIT_AUTH=true désactive entièrement la vérification du jeton. Inspector lance des processus locaux pour votre compte : traitez le jeton comme un mot de passe et gardez ces deux dérogations à l’écart des machines partagées.
Utiliser un fichier de configuration
Taper la commande devient pénible dès qu’un serveur demande trois arguments et deux variables d’environnement. Placez-les dans un fichier et sélectionnez le serveur par son nom. Il existe deux options, qui s’excluent mutuellement :
Option
Écrit par Inspector
Si le fichier est absent
--config <path>
Non, lecture seule
Erreur
--catalog <path>
Oui, modifiable dans l’interface web
Créé et initialisé
Le catalogue par défaut se trouve à ~/.mcp-inspector/mcp.json. Aucune de ces options ne peut être combinée avec une cible ad hoc sur la même ligne de commande.
Gardez command et chaque élément de args comme entrées distinctes. Inspector lance ces éléments directement au lieu de les joindre dans une seule chaîne, ce qui préserve les limites des arguments lorsqu’un chemin contient des espaces.
--server ne sert qu’à sélectionner un serveur en mode CLI. Le client web affiche un avertissement et l’ignore lorsque vous chargez un fichier, et la TUI le rejette comme option inconnue.
Tester un serveur MCP depuis la CLI
Le mode CLI se passe du navigateur et affiche la réponse sur stdout, ce qui en fait l’outil idéal pour les vérifications rapides et tout ce que vous voulez automatiser. Chaque commande a la même forme : la cible d’abord, puis --method, puis ce que la méthode demande.
Lister d’abord les outils
Commencez toujours par demander ce que le serveur dit offrir :
Remplacez la méthode par resources/list ou prompts/list pour vérifier les deux autres fonctionnalités. Un serveur distant demande une adresse et un transport, ainsi qu’un jeton bearer s’il est protégé :
Comparez les noms affichés avec ce que votre client attend. Un outil enregistré sous generateImage mais demandé sous generate_image est un classique, et une seule commande suffit à le repérer.
Appeler un outil avec des arguments JSON
npx @modelcontextprotocol/inspector --cli node build/index.js \
--method tools/call \
--tool-name generate_image \
--tool-args-json '{"prompt":"a ceramic mug on an oak desk, soft window light","aspect_ratio":"16:9"}'
--tool-args-json prend un seul objet JSON et n’applique aucune conversion : les nombres restent des nombres et les booléens restent des booléens. Pour un test rapide, --tool-arg prompt="a red door" est plus court, mais ses valeurs sont interprétées comme du JSON lorsqu’elles sont valides, si bien qu’une chaîne qui ressemble à un nombre devient un nombre. Quand les types comptent, utilisez la forme JSON.
💡 Remarque pour Windows : Windows PowerShell 5.1 supprime les guillemets doubles internes du JSON passé aux programmes natifs. Échappez chacun avec une barre oblique inverse, ou utilisez --tool-arg pour les valeurs courtes.
Lire les codes de sortie
La CLI indique le résultat dans son code de sortie, si bien qu’un script n’a jamais à analyser du texte pour savoir ce qui s’est passé.
Code
Signification
0
Succès
1
Erreur d’utilisation ou échec inattendu
2
Aucune application MCP trouvée (sonde --app-info)
3
Authentification requise
4
Serveur injoignable : DNS, délai dépassé ou connexion refusée
5
L’outil a renvoyé isError: true, ou l’outil est introuvable
6
Erreur de portabilité du schéma avec --strict
Le code 5 compte le plus pour les tests. Un outil qui échoue proprement fait maintenant échouer la commande, si bien que inspector --cli ... && next-step s’arrête là où la v1 aurait poursuivi. Par défaut, les connexions abandonnent au bout de 15 secondes pour les exécutions ad hoc, et --connect-timeout <ms> relève cette limite lorsque votre serveur charge une base de données ou un modèle au démarrage.
Lancer les vérifications d’Inspector en CI
Un test de fumée utile vérifie quatre choses : le serveur se connecte, l’outil existe, un appel valide réussit et un appel invalide échoue. Quatre commandes, sans navigateur, et une version défectueuse n’atteint jamais les utilisateurs.
Épingler la version
Épinglez une version exacte en CI, jamais une plage comme @2.x, car les options et les codes de sortie ont changé entre les versions majeures :
Ajoutez --format json et la CLI affiche un seul objet JSON contenant un champ result, prêt pour jq. Deux pièges valent la peine d’être connus. Ne fusionnez jamais stderr avec stdout avec 2>&1 pendant l’analyse, car les diagnostics se retrouveraient à l’intérieur du JSON. Et capturez le statut de sortie avant le tube, car un pipeline renvoie le statut de sa dernière commande, ce qui masque une CLI en échec derrière un jq réussi.
#!/usr/bin/env bash
set -u
INSPECT="npx --yes @modelcontextprotocol/inspector@2.9.0 --cli node build/index.js"
# 1. The handshake works
$INSPECT --method initialize --format json > init.json || exit 1
# 2. The tool exists (status captured before the pipe)
tools=$($INSPECT --method tools/list --format json); code=$?
[ "$code" -eq 0 ] || { echo "tools/list failed with $code"; exit "$code"; }
echo "$tools" | jq -e '.result.tools | map(.name) | index("generate_image")' > /dev/null || exit 1
# 3. A valid call succeeds
$INSPECT --method tools/call --tool-name list_models --tool-args-json '{}' \
--format json > call.json || exit 1
# 4. An invalid call fails
if $INSPECT --method tools/call --tool-name generate_image --tool-args-json '{}' \
> /dev/null 2>&1; then
echo "tool accepted empty input"; exit 1
fi
La quatrième vérification est celle que l’on oublie. Un serveur qui accepte un prompt manquant et renvoie une image vide passera tous les tests positifs que vous écrirez.
Corriger les erreurs que vous rencontrerez
La plupart des échecs entrent dans quelques schémas. Identifiez d’abord le symptôme, puis lisez la section qui l’explique.
Symptôme
Cause probable
Correctif
Code de sortie 4, délai de connexion dépassé
Le serveur a planté au démarrage ou démarre lentement
Lancez la commande du serveur seule, puis augmentez --connect-timeout
Le handshake échoue avec des erreurs d’analyse
Quelque chose a été écrit sur stdout
Envoyez les journaux vers stderr
Erreur de transport sur une URL
Le chemin ne se termine pas par /mcp ou /sse
Ajoutez --transport http ou --transport sse
Code de sortie 3
Le serveur réclame un jeton ou une connexion
Passez --header, et utilisez --stored-auth-only en CI
Code de sortie 5
Erreur d’outil, ou mauvais nom d’outil
Exécutez tools/list et copiez le nom exact
L’interface rejette la page
Jeton d’API périmé
Relancez Inspector pour en obtenir un nouveau
Pollution de stdout avec stdio
Le transport stdio transporte ses messages JSON-RPC sur stdout, et le protocole indique qu’un serveur ne doit rien y écrire qui ne soit pas un message MCP valide. Un console.log égaré, une bannière de démarrage ou un avertissement affiché par une dépendance altère le flux. Le handshake échoue alors avec des erreurs d’analyse, ou reste simplement bloqué.
Pour corriger cela, envoyez chaque ligne de journal vers stderr (console.error en Node, sys.stderr en Python). Pour trouver le coupable, lancez la commande du serveur seule : un serveur stdio sain n’affiche rien tant qu’un client ne lui parle pas.
Transport non détecté
La v2 ne devine plus. Elle déduit le transport uniquement lorsque le chemin de l’URL se termine par /mcp ou /sse, et tout autre cas exige l’option explicite :
Quand un message d’erreur ne vous dit rien, collez la sortie stderr et le schéma de votre outil dans Claude Sonnet 5 ou GPT 5.6 Sol et demandez les trois causes les plus probables. Les deux lisent bien les traces de pile, et vous vérifiez toujours la réponse avec Inspector.
Tester un serveur de génération d’images
Les serveurs qui produisent des médias se comportent différemment en test. Les appels sont lents, ils peuvent coûter de l’argent, et le travail s’exécute généralement en arrière-plan. L’API développeur de PicassoIA illustre bien le schéma. Elle fonctionne comme Replicate : vous créez une prédiction avec POST /v1/models/{owner}/{name}/predictions sur https://api.picassoia.com/v1, vous vous authentifiez avec un jeton bearer, vous interrogez GET /v1/predictions/{id} et vous lisez le résultat une fois terminé.
Au moment de la rédaction, l’API et la connexion MCP exposent les mêmes quatre modèles : PicassoIA Image, PicassoIA Image Editor Pro, PicassoIA Video et Seedance 2.5 Lite. Un compte autorise 5 prédictions simultanées, partagées entre tous les jetons et les connexions MCP, avec des prompts pouvant atteindre 4 000 caractères.
💡 Testez en série. Une boucle d’appels d’outils dans une même session Inspector peut remplir les cinq emplacements et priver votre client réel de ressources. Lancez les tests d’images un appel à la fois.
Les outils asynchrones ont besoin d’un outil de statut
Un outil qui lance une tâche doit renvoyer un ID en quelques secondes, et un second outil doit signaler la progression. Testez les deux moitiés séparément :
L’appel de démarrage renvoie rapidement un ID au lieu de garder la connexion ouverte pendant des minutes.
L’appel de statut accepte cet ID et indique un état de progression ainsi qu’un état final.
Une tâche en échec revient sous forme de résultat avec isError: true, et non sous forme d’appel bloqué.
Un mauvais ID produit le code de sortie 5, et non un plantage du processus serveur.
L’URL de sortie répond avec le statut 200 et un type de contenu image lorsque vous la récupérez.
Cette dernière vérification est la moins coûteuse, et elle détecte la panne que les lecteurs remarquent en premier : une image cassée sur une page publiée.
Créer ensuite votre première image
Vous avez maintenant un moyen de prouver qu’un serveur fonctionne avant que quiconque n’en dépende. La même habitude paie du côté créatif : lancez un petit test, lisez le résultat et ne changez qu’une chose à la fois.
Ouvrez PicassoIA et essayez la boucle vous-même. Rédigez un prompt d’une phrase dans PicassoIA Image, affinez le résultat avec PicassoIA Image Editor Pro, puis donnez vie à l’image fixe avec PicassoIA Video. Changez l’objectif, la lumière ou le sujet d’un essai à l’autre et comparez les sorties côte à côte. Cinq commandes de cet article méritent d’être gardées à côté de votre terminal :
--method initialize pour confirmer le handshake.
--method tools/list pour confirmer les noms des outils.
--method tools/call --tool-args-json pour confirmer le comportement.
--format json plus jq pour vérifier la réponse.
Le code de sortie, à toujours lire avant le résultat.