
Sécuriser ses clés API MCP dans Claude Code (et pourquoi c'est urgent)
Le problème : des clés en clair dans mcp.json
Le contenu typique d'un ~/.claude/mcp.json non sécurisé :
{
"mcpServers": {
"mon-serveur": {
"command": "npx",
"args": ["-y", "mon-mcp-server@latest"],
"env": {
"API_KEY": "sk-1234567890abcdef..."
}
}
}
}
Des clés API en clair. Pas chiffrées, pas dans un vault.
L'argument « c'est local, ce n'est pas grave » ne tient pas. En février 2026, deux CVE sont tombées sur Claude Code (CVE-2025-59536 et CVE-2026-21852). La seconde était vicieuse : un repo malveillant pouvait overrider ANTHROPIC_BASE_URL dans les settings projet et rediriger tout le trafic API vers un serveur tiers. Corrigé depuis la v2.0.65.
Et il n'y a pas besoin d'une CVE pour se faire avoir : un git add . trop enthousiaste, un collègue qui copie votre config, un script npm douteux qui scanne ~/.claude/. Une clé API leakée, ce sont parfois des centaines d'euros de consommation frauduleuse avant qu'on remarque quoi que ce soit.
L'interpolation ${VAR}
Claude Code supporte les variables d'environnement entre ${} dans mcp.json :
{
"mcpServers": {
"mon-serveur": {
"command": "npx",
"args": ["-y", "mon-mcp-server@latest"],
"env": {
"API_KEY": "${MON_SERVEUR_API_KEY}"
}
}
}
}
Au lancement du serveur MCP, Claude Code remplace ${MON_SERVEUR_API_KEY} par la vraie valeur depuis l'environnement. Le fichier JSON reste propre.
La mise en place, en 4 étapes
1. Un fichier secrets avec les bonnes permissions
# Créer le fichier
cat > ~/.env.claude << 'EOF'
# API keys pour MCP servers Claude Code
MON_SERVEUR_API_KEY="sk-1234567890abcdef"
AUTRE_SERVICE_TOKEN="token_ici"
SERVICE_EMAIL="mon@email.com"
EOF
# Permissions : lecture/écriture uniquement pour le propriétaire
chmod 600 ~/.env.claude
Le chmod 600 n'est pas optionnel : sans lui, n'importe quel process de la machine peut lire le fichier.
2. Charger les variables au démarrage du shell
Les variables doivent exister dans l'environnement avant que Claude Code démarre.
Fish (dans ~/.config/fish/config.fish) — verbeux, parce que fish ne source pas les fichiers .env nativement :
# Load Claude MCP secrets
if test -f ~/.env.claude
for line in (grep -v '^#' ~/.env.claude | grep '=')
set -l key (echo $line | cut -d= -f1)
set -l val (echo $line | cut -d= -f2- | tr -d '"')
set -x $key $val
end
end
Bash/zsh (dans ~/.bashrc ou ~/.zshrc) :
# Load Claude MCP secrets
[ -f ~/.env.claude ] && set -a && source ~/.env.claude && set +a
Le set -a exporte automatiquement toutes les variables sourcées, ce qui évite un export par ligne, et set +a restaure le comportement normal ensuite.
3. Nettoyer mcp.json
{
"mcpServers": {
"serveur-recherche": {
"command": "npx",
"args": ["-y", "mcp-recherche@latest"],
"env": {
"SEARCH_API_KEY": "${SEARCH_API_KEY}"
}
},
"serveur-gestion": {
"command": "npx",
"args": ["-y", "mcp-gestion@latest"],
"env": {
"GESTION_API_KEY": "${GESTION_API_KEY}",
"GESTION_TOKEN": "${GESTION_TOKEN}"
}
},
"serveur-ia": {
"command": "uvx",
"args": ["mcp-ia-server"],
"env": {
"IA_API_KEY": "${IA_API_KEY}"
}
}
}
}
Quiconque ouvre ce fichier ne voit plus que des noms de variables.
4. Deny rules, ceinture et bretelles
Claude Code peut lire n'importe quel fichier de la machine, y compris ~/.env.claude. Une hallucination ou une prompt injection via un MCP douteux suffirait à l'y pousser. Dans ~/.claude/settings.json :
{
"permissions": {
"deny": [
"Edit(~/.env.claude)",
"Read(~/.env.claude)",
"Edit(~/.ssh/**)",
"Edit(~/.aws/**)",
"Read(~/.ssh/id_*)",
"Read(~/.aws/credentials)"
]
}
}
Defense in depth : même si tout le reste échoue, la lecture du fichier se heurte à un mur.
Vérifier que ça marche
Relancez le shell (exec fish / source ~/.bashrc), puis :
# Les variables sont-elles chargées ?
echo $MON_SERVEUR_API_KEY
# Doit afficher la clé
# Le fichier secrets est-il bien protégé ?
ls -la ~/.env.claude
# Doit afficher -rw------- (600)
# Plus de secrets en dur dans mcp.json ?
grep -c "sk-\|token_\|AIza" ~/.claude/mcp.json
# Doit afficher 0
Si un serveur MCP refuse de démarrer, la variable n'est probablement pas exportée dans l'environnement — un env | grep MON_SERVEUR le confirme.
Quelques compléments
Rotation des clés : renouveler une clé revient à changer une ligne dans ~/.env.claude et relancer le shell, au lieu d'éditer le JSON en priant pour ne pas casser la syntaxe.
Plusieurs environnements : rien n'empêche d'avoir ~/.env.claude.perso, ~/.env.claude.work, ~/.env.claude.client-x et de charger le bon via un alias.
Le .gitignore, si vous avez un dossier .claude/ dans un projet versionné :
# Claude Code
.env.claude*
.claude/settings.local.json
HTTP Hooks : depuis début 2026, les hooks HTTP ("type": "http") interpolent aussi des variables d'environnement via allowedEnvVars. Même réflexe — jamais de token en dur, et une liste de variables autorisées réduite au strict nécessaire.
Récapitulatif
~/.env.claude— toutes les clés, chmod 600mcp.json— que des${VAR}, zéro secretsettings.json— deny rules sur le fichier secrets- Shell config — loader automatique au démarrage
Vu les CVE de février et l'accès grandissant des agents IA à nos machines, sécuriser ses clés MCP n'est pas de l'excès de zèle mais de l'hygiène de base — et ça prend quinze minutes.
Articles similaires
Claude Code comme back-office : connecter Drive, Gmail et Trello pour piloter sa boîte
claude-code · ia · mcp
MCP chrome-devtools depuis WSL : piloter (et auto-lancer) une Chrome Windows
claude-code · mcp · wsl
Créer une skill Claude Code pour vérifier les affirmations scientifiques
claude-code · ia · mcp