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.

MCP Inspector npx et CLI : comment tester un serveur MCP
Cristian Da Conceicao
Fondateur de Picasso IA

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.

Vue en plongée d’un bureau avec un terminal sur ordinateur portable, un croquis de deux boîtes connectées et une tasse d’espresso

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.

ModeCommandeIdéal pour
Interface webnpx @modelcontextprotocol/inspectorExplorer un serveur à la main
CLInpx @modelcontextprotocol/inspector --cliScripts, vérifications rapides, CI
TUInpx @modelcontextprotocol/inspector --tuiRester 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.

Gros plan de mains tapant sur un ordinateur portable, avec une fenêtre de terminal sombre floutée en arrière-plan

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églageInspector v1Inspector v2
Node.js22.7.5 ou plus récent22.19.0 ou plus récent
Port de l’interface web62746274
Port du proxy6277Supprimé, il n’y a plus de proxy
Variable du jeton d’authentificationMCP_PROXY_AUTH_TOKENMCP_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 échecLa chaîne de commandes continuaitLe 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.

CLIENT_PORT=6280 npx @modelcontextprotocol/inspector node build/index.js

Sous Windows PowerShell, définissez d’abord la variable avec $env:CLIENT_PORT = "6280", puis lancez la même ligne npx.

Passer des arguments et des variables d’environnement

Pour un serveur Node compilé, placez la commande juste après le nom du paquet :

npx @modelcontextprotocol/inspector node build/index.js

Les variables d’environnement s’ajoutent avec -e :

npx @modelcontextprotocol/inspector -e API_TOKEN=your-token -- node build/index.js

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 :

{
  "scripts": {
    "inspect": "npx @modelcontextprotocol/inspector node dist/index.js"
  }
}

💡 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 InspectorSi le fichier est absent
--config <path>Non, lecture seuleErreur
--catalog <path>Oui, modifiable dans l’interface webCréé 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.

Vue par-dessus l’épaule d’une femme surlignant des lignes de configuration imprimées à un bureau debout

Entrées stdio

{
  "mcpServers": {
    "my-server": {
      "type": "stdio",
      "command": "node",
      "args": ["build/index.js"],
      "env": { "API_TOKEN": "your-token" },
      "cwd": "/path/to/server"
    }
  }
}

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.

Entrées HTTP et SSE

{
  "mcpServers": {
    "remote-server": {
      "type": "http",
      "url": "https://mcp.internal.example/mcp",
      "headers": { "X-Tenant": "acme" }
    }
  }
}

Le champ type accepte stdio, http (HTTP diffusable) ou sse. En CLI, vous choisissez une entrée avec --server :

npx @modelcontextprotocol/inspector --cli --config ./mcp.json --server my-server --method tools/list

--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.

Un développeur appuyé en arrière à son bureau, examinant deux fenêtres de terminal sobres en fin d’après-midi

Lister d’abord les outils

Commencez toujours par demander ce que le serveur dit offrir :

npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list

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é :

npx @modelcontextprotocol/inspector --cli \
  --transport http --server-url https://example.com/mcp \
  --header 'Authorization: Bearer <token>' \
  --method tools/list

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é.

La main d’un pilote cochant des éléments sur une liste de contrôle en papier dans un petit cockpit

CodeSignification
0Succès
1Erreur d’utilisation ou échec inattendu
2Aucune application MCP trouvée (sonde --app-info)
3Authentification requise
4Serveur injoignable : DNS, délai dépassé ou connexion refusée
5L’outil a renvoyé isError: true, ou l’outil est introuvable
6Erreur 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.

Vue en contre-plongée d’une allée froide entre deux rangées de baies de serveurs noires

É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 :

npx --yes @modelcontextprotocol/inspector@2.9.0 --cli node build/index.js --method initialize

Donnez à chaque job son propre magasin de jetons, afin qu’une exécution ne puisse jamais réutiliser l’état de connexion d’une autre :

export MCP_STORAGE_DIR="$(mktemp -d)"
export MCP_INSPECTOR_OAUTH_STATE_PATH="$MCP_STORAGE_DIR/oauth.json"

Vérifier avec jq

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.

Une main tirant un câble noir hors d’un faisceau emmêlé sur un établi en bois rayé

SymptômeCause probableCorrectif
Code de sortie 4, délai de connexion dépasséLe serveur a planté au démarrage ou démarre lentementLancez la commande du serveur seule, puis augmentez --connect-timeout
Le handshake échoue avec des erreurs d’analyseQuelque chose a été écrit sur stdoutEnvoyez les journaux vers stderr
Erreur de transport sur une URLLe chemin ne se termine pas par /mcp ou /sseAjoutez --transport http ou --transport sse
Code de sortie 3Le serveur réclame un jeton ou une connexionPassez --header, et utilisez --stored-auth-only en CI
Code de sortie 5Erreur d’outil, ou mauvais nom d’outilExécutez tools/list et copiez le nom exact
L’interface rejette la pageJeton 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 :

npx @modelcontextprotocol/inspector --cli --server-url https://example.com/api \
  --transport http --method tools/list

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é.

Un appareil photo sur trépied face à un vase blanc sur un fond gris dans un petit studio photo

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.

Un designer souriant examinant des photos de paysages imprimées sur une table lumineuse de studio

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.

Partager cet article

Choisissez votre langue