← Tous les articles

Claude Code sous Windows : ton serveur MCP lance le mauvais bash.

2026-07-16 · mis à jour le 2026-09-25 · 7 min de lecture · par Nabil BA-MOH

Ton serveur MCP marche sur un Mac. Sous Windows, Claude Code affiche Failed to reconnect to <server>: CONNECTION_CLOSED (parfois -32000). Claude Code lui-même tourne bien, son outil Bash marche, Git Bash est installé. Et quelque part dans un log, il y a une ligne qui n’a aucun sens sur une machine où tu n’as jamais demandé Linux :

Windows Subsystem for Linux has no installed distributions.

Ton serveur n’a jamais été lancé par Git Bash. Il a été lancé par le lanceur de WSL. Voici pourquoi, comment le voir en dix secondes, pourquoi la correction habituelle du PATH ne peut pas marcher, et ce qui marche.

Correction, 25 septembre 2026. La version de juillet de cet article te disait d’ajouter Git\bin à la fin de ton PATH utilisateur pour que « tout ce qui lance bash par son nom marche ». C’est faux, et nous l’avons prouvé sur nos propres machines en août. Notre test CI de juillet passait seulement parce qu’il donnait au test son propre Git Bash, un chemin qu’aucun vrai utilisateur n’a. Le reste de cet article, c’est ce que nous aurions dû écrire.

Mesuré sur nos machines Windows entre le 5 et le 14 août 2026, dont une VM neuve. Tu n’as besoin de WSL pour rien de tout ça.

Pourquoi le terminal marche et le serveur non

Deux choses différentes lancent bash dans Claude Code sous Windows, et elles ne le trouvent pas de la même façon.

Donc un serveur déclaré avec "command": "bash" reçoit ce que Windows trouve en premier sous ce nom. Sur les machines que nous avons testées, ce n’était jamais Git Bash.

Le voir en dix secondes

Dans PowerShell :

Get-Command bash -All | Select-Object -ExpandProperty Source

Ce que nous avons obtenu :

C:\WINDOWS\system32\bash.exe
C:\Users\<you>\AppData\Local\Microsoft\WindowsApps\bash.exe
C:\Program Files\Git\bin\bash.exe

La ligne 1 est le lanceur WSL, la ligne 2 un alias WSL du Store, la ligne 3 le Git Bash que tu voulais. C’est la première ligne qui s’exécute. C:\Windows\System32\bash.exe est le lanceur WSL. La suite dépend de la machine :

Dans les deux cas, le processus meurt avant la poignée de main MCP, et Claude Code signale une connexion fermée sans parler ni de bash ni de WSL.

Pourquoi corriger le PATH ne peut pas marcher

Le réflexe, c’est de mettre Git Bash dans le PATH. Nous avons fait exactement ça, et nous l’avons publié comme la solution. Ça ne peut pas marcher.

Un processus Windows construit son PATH avec d’abord les entrées Machine, puis les entrées User. C:\Windows\System32 est une entrée Machine. Tout ce que tu ajoutes à la fin de ton PATH User passe après, donc System32\bash.exe gagne à chaque fois. C’est comme ça que Windows construit le PATH sur toutes les machines, pas une bizarrerie de la tienne.

Tu pourrais mettre Git en tête du PATH Machine en tant qu’administrateur. Nous ne le recommandons pas : ça change ce que bash veut dire pour tous les programmes de la machine, et une seule mise à jour de Windows ou une réinstallation de Git l’annule sans bruit.

La solution, si c’est toi qui écris le serveur

Arrête de nommer bash dans command. Lance directement le runtime dont ton serveur a vraiment besoin :

"my-server": {
  "command": "uv",
  "args": ["run", "--directory", "${CLAUDE_PLUGIN_ROOT}/server",
           "--frozen", "python", "${CLAUDE_PLUGIN_ROOT}/server/main.py"]
}

Pareil pour node server.js, ou n’importe quel binaire que ton installeur met lui-même dans le PATH. Nous avons fait passer nos deux serveurs de bash run.sh à uv run. Avec un substitut qui reproduit exactement l’échec WSL, l’ancien lancement mourait avec l’erreur de notre utilisateur, mot pour mot, et le nouveau démarrait les deux serveurs.

Ça compte encore plus pour les plugins. L’entrée mcpServers d’un plugin a command, args et env, et aucune variante par OS. Une seule commande doit marcher sur macOS, Linux et Windows. bash est le seul nom qui veut dire autre chose sous Windows, donc c’est le seul nom que tu ne peux pas utiliser.

Si ton script d’enveloppe faisait un travail utile (le nôtre ajoutait ~/.local/bin et les dossiers Homebrew au PATH, parce que Claude Code lancé depuis une app de bureau peut ne pas les voir), déplace ce travail dans l’installeur ou dans le serveur. Ne le laisse pas tomber en silence.

La solution, si tu ne fais qu’utiliser le serveur

Dans ton propre .mcp.json ou ta config utilisateur, remplace le nom nu par le chemin complet, que Windows n’a pas à chercher :

"command": "C:\\Program Files\\Git\\bin\\bash.exe"

Vérifie d’abord où Git se trouve sur ta machine. Une installation de Git par utilisateur se trouve dans %LOCALAPPDATA%\Programs\Git, pas dans C:\Program Files\Git.

Pour le serveur d’un plugin, ça ne tient pas : le cache du plugin est remplacé à chaque mise à jour. Signale-le à l’auteur avec la sortie de la ligne Get-Command ci-dessus. Cette sortie, c’est tout le diagnostic.

Être présent n’est pas s’exécuter

Pourquoi ça a tenu si longtemps chez nous ? Nos vérifications demandaient si bash.exe existe. Il existe. Le lanceur WSL est un vrai fichier exécutable. La ligne « Git Bash OK » de notre installeur était verte sur toutes les machines où les serveurs étaient morts.

Deux règles que nous appliquons maintenant partout :

  1. Vérifie en exécutant, jamais en trouvant un fichier. Lance exactement la commande et les arguments que Claude Code utilisera, depuis PowerShell, sans bash fourni, et exige une vraie réponse MCP. Une vérification qui trouve bash.exe ne prouve rien.
  2. Teste ce que les utilisateurs lancent, pas ce que la CI te donne. Une étape de CI Windows avec shell: bash donne Git Bash gratuitement à ton test. Tes utilisateurs n’ont pas ça. Lance le test de démarrage sous PowerShell et lis la commande dans ta vraie config.

Le même piège existe pour python3 : sous Windows, ça peut être un raccourci du Microsoft Store. Le fichier existe, et il ouvre le Store au lieu de lancer Python.

Un deuxième piège si tu utilises bien Git Bash : deux fichiers bash.exe

Git for Windows en fournit deux :

Pour lancer un serveur, ça compte rarement. Pour un test qui prouve « ça échoue proprement quand l’outil X manque » en retirant X du PATH, l’enveloppe remet X et ton test ne prouve rien. Utilise le bash simple dans ce cas.

Les autres pièges Windows que nous avons rencontrés

Toujours vrai depuis la version de juillet.

import fcntl tue les serveurs Python au chargement. fcntl n’existe que sous POSIX. Au niveau du module, l’import échoue avant que ton serveur puisse parler en stdio. Protège-le et traite les verrous de fichiers comme un « au mieux » :

try:
    import fcntl
except ImportError:
    fcntl = None

L’encodage du texte. Windows utilise cp1252 par défaut. read_text() sans encodage passe sur macOS et échoue sous Windows au premier caractère hors de cp1252. Passe toujours encoding="utf-8", en lecture comme en écriture.

OpenSSH refuse une clé privée copiée. Ses permissions viennent d’ACL héritées, trop ouvertes. Corrige-les :

icacls <key> /inheritance:r /grant:r "%USERNAME%:R"

Ne code jamais en dur C:\Program Files\Git. Les installations par utilisateur sont ailleurs. Demande où est Git : where.exe git renvoie ...\Git\cmd\git.exe, et bash.exe se trouve dans le dossier voisin bin.

Alors, quand as-tu besoin de WSL ?

Quand ton travail a vraiment besoin de Linux : des images Docker uniquement Linux, des appels système Linux, des outils sans version Windows, ou l’exécution de commandes en bac à sable (Claude Code gère le sandboxing sur WSL 2, pas sur Windows natif). Pour faire tourner Claude Code et des serveurs MCP, non. Tu as besoin de serveurs qui ne nomment pas bash.

Ça nous a coûté neuf jours, et nous avions déjà publié la mauvaise solution. Klyr existe pour qu’un assistant garde ce qui a été appris à la dure, au lieu que tu le redécouvres sur la machine suivante. Si c’est un problème que tu as, prends Klyr.

Tu débutes avec Claude Code ? Commence par notre guide pour les non-développeurs.

FAQ

Pourquoi mon serveur MCP affiche CONNECTION_CLOSED seulement sous Windows ?

Si sa command est bash, Windows lance C:\Windows\System32\bash.exe, le lanceur WSL, pas Git Bash. Il sort avant la poignée de main MCP. Vérifie avec Get-Command bash -All dans PowerShell.

J’ai ajouté Git\bin à mon PATH. Pourquoi ça ne marche toujours pas ?

Windows place les entrées du PATH Machine avant celles du PATH User, et System32 est une entrée Machine. Une entrée du PATH User ne peut jamais passer devant.

Pourquoi l’outil Bash de Claude Code marche si bash est le mauvais ?

Claude Code trouve Git Bash pour son propre outil Bash, ou utilise CLAUDE_CODE_GIT_BASH_PATH. Les serveurs MCP sont lancés directement depuis leur champ command, sans shell, et ce réglage ne s’applique pas à eux.

Comment corriger un serveur que je n’ai pas écrit ?

Dans ta propre config, mets dans command le chemin complet du bash.exe de Git. Pour un plugin, signale-le à l’auteur : le cache du plugin est remplacé à chaque mise à jour.

Ai-je besoin de WSL pour utiliser Claude Code sous Windows ?

Non. Claude Code tourne en natif. Tu n’as besoin de WSL que pour des outils uniquement Linux ou pour l’exécution en bac à sable.

Pourquoi mon serveur MCP Python plante instantanément sous Windows ?

Souvent à cause d’un import fcntl au niveau du module, qui n’existe que sous POSIX. Protège-le avec try/except ImportError.

Partager ce guide