Module 11 — MCP : connecter Claude Code à vos outils et à vos données
Claude Code, tel qu'il sort du terminal, sait lire vos fichiers, écrire du code, lancer des commandes shell. Il ignore tout du reste : votre dépôt GitHub, votre base Postgres de recette, votre tracker de tickets, votre bucket S3, votre système d'observabilité. Le MCP, Model Context Protocol, est le mécanisme standardisé par lequel Claude Code parle à ces services sans qu'on ait à écrire soi-même le code de l'intégration.
Le principe : un protocole, plusieurs transports
MCP est un protocole ouvert. Le service (« serveur MCP ») expose des outils — actions atomiques telles que read_file, search_issues, run_query — et Claude Code (« client MCP ») les appelle comme s'il s'agissait d'outils internes. Le vocabulaire de sortie est identique côté Claude : peu importe que l'outil vive dans le processus ou à l'autre bout du monde.
Ce qui varie, c'est le transport. Quatre transports sont documentés :
| Transport | Cas d'usage | Notes |
|---|---|---|
http (streamable-http) | Serveur distant, service cloud | Transport recommandé pour les services cloud, supporte OAuth |
sse | Legacy, quelques services encore uniquement en SSE | Marqué déprécié, préférer HTTP |
stdio | Processus local, script maison, outil CLI | Idéal pour un accès direct au système ou une base locale |
ws (WebSocket) | Serveurs distants qui poussent des événements | Ne supporte pas OAuth ni --transport ws en CLI ; configuration via JSON |
Le champ type dans un fichier de configuration accepte aussi streamable-http comme alias de http — c'est le nom officiel MCP, utile quand on colle une configuration copiée depuis la documentation d'un autre client.
Trois scopes pour trois usages
Un serveur MCP se déclare à l'un de trois scopes, chacun avec un fichier de destination et une visibilité différente.
| Scope | Charge dans | Partagé avec l'équipe | Stocké dans |
|---|---|---|---|
| Local | Ce projet seulement | Non | ~/.claude.json |
| Project | Ce projet seulement | Oui, versionné | .mcp.json à la racine du projet |
| User | Tous vos projets | Non | ~/.claude.json |
Le scope se choisit en ligne de commande avec --scope local|project|user (défaut : local). En cas de doublon de nom entre scopes, la précédence est local > project > user > plugin > connecteur claude.ai : Claude Code utilise l'entrée entière du scope prioritaire, sans fusion champ à champ.
Attention à un piège de sécurité : les serveurs déclarés dans un .mcp.json versionné exigent une approbation manuelle à la première ouverture du projet. En session claude -p (headless) ou dans le SDK, il n'y a pas de prompt : Claude Code charge les serveurs sans demander, sauf si vous ajoutez --strict-mcp-config ou si vous listez le serveur dans disabledMcpjsonServers. Un dépôt fraîchement cloné dont on n'a pas encore accepté le dialogue de workspace trust laisse chaque serveur au statut ⏸ Pending approval.
Installer un serveur : les quatre chemins
Serveur distant HTTP
C'est l'option recommandée pour connecter un service cloud. Syntaxe :
claude mcp add --transport http <nom> <url>
claude mcp add --transport http notion https://mcp.notion.com/mcp
claude mcp add --transport http secure-api https://api.example.com/mcp \
--header "Authorization: Bearer <token>"
Serveur distant SSE
À réserver aux services qui n'exposent qu'un endpoint SSE. Syntaxe équivalente avec --transport sse. Fonctionnalité dépréciée, migrez vers HTTP dès que le service le permet.
Serveur local stdio
Un serveur stdio est un processus lancé par Claude Code sur votre machine, qui échange par les descripteurs standard. La séparation entre les options de claude mcp add et la commande à lancer se fait par -- :
claude mcp add [options] <nom> -- <commande> [args...]
Claude Code injecte automatiquement CLAUDE_PROJECT_DIR dans l'environnement du processus serveur, pointant vers la racine du projet. C'est stable pour toute la session, indépendant du répertoire courant. Les variables sont passées via --env KEY=value, placées avant le -- et pas immédiatement après si le nom du serveur suit :
claude mcp add --env AIRTABLE_API_KEY=<clé> --transport stdio airtable \
-- npx -y airtable-mcp-server
Serveur distant WebSocket
Réservé aux serveurs qui poussent des événements sans être sollicités. --transport n'accepte pas ws en CLI ; passer par claude mcp add-json ou éditer .mcp.json directement :
claude mcp add-json events '{"type":"ws","url":"wss://mcp.example.com/socket","headers":{"Authorization":"Bearer <token>"}}'
Anatomie de .mcp.json
Le format standard, versionnable et partagé, ressemble à ceci :
{
"mcpServers": {
"shared-server": {
"type": "http",
"url": "https://example.com/mcp"
}
}
}
Deux points-clés. Un entrée avec url mais sans type est une erreur : Claude Code lit alors le serveur comme un stdio, échoue, et affiche MCP server "<nom>" has a "url" but no "type". Ajouter explicitement "type": "http" (ou "sse" / "ws"). L'expansion ${VAR} est acceptée dans command, args, env, url et headers, avec deux formes : ${VAR} (échoue silencieusement en warning si absent) et ${VAR:-défaut}. Cela permet de commiter un .mcp.json en clair sans exposer les secrets — chaque développeur met sa valeur dans son environnement.
Gérer les serveurs
Un ensemble de commandes CLI couvre le cycle de vie.
| Commande | Rôle |
|---|---|
claude mcp add [options] <nom> ... | Ajouter un serveur (défaut : local scope) |
claude mcp add-json <nom> <json> | Ajouter depuis une chaîne JSON |
claude mcp list | Lister tous les serveurs configurés, avec statut de santé |
claude mcp get <nom> | Détail d'un serveur, endpoint résolu, statut |
claude mcp remove <nom> | Supprimer un serveur (efface aussi les tokens OAuth) |
claude mcp login <nom> | Lancer le flux OAuth depuis le shell |
claude mcp logout <nom> | Révoquer l'authentification stockée |
claude mcp reset-project-choices | Réinitialiser les approbations .mcp.json |
Côté session interactive, la commande /mcp ouvre un panneau qui liste les serveurs, leur statut (Connected, Needs authentication, Failed to connect, Pending approval, cached), leur nombre d'outils, et permet de désactiver un serveur sans le supprimer, de le reconnecter, ou de nettoyer son authentification.
Authentification OAuth
Un serveur distant qui renvoie 401 ou 403 est marqué « needs authentication ». Ouvrir /mcp, sélectionner Sign in, un navigateur s'ouvre pour le flux OAuth. Alternative en ligne de commande depuis la v2.1.186 : claude mcp login <nom>.
Deux subtilités opérationnelles. Sur une session SSH sans navigateur local, la commande imprime l'URL d'autorisation à ouvrir manuellement puis attend le collage de l'URL de redirection — se connecter avec ssh -t pour que le terminal soit interactif. Et si vous configurez vous-même un header Authorization (via --header ou un headersHelper), un 401 ne déclenchera pas le flux OAuth : Claude Code considère que le crédential vient de vous et rapporte simplement la connexion en échec.
Kiosque : un .mcp.json complet
L'équipe de Kiosque veut deux serveurs : GitHub pour lire les issues, ouvrir des PR, lire les revues automatiques (HTTP distant, authentification par PAT) ; Postgres en lecture seule pour interroger la base de recette (stdio local, DSN en variable d'environnement).
Nadia crée le fichier à la racine et le commite. Les secrets restent à l'extérieur, dans chaque .env local :
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_MCP_TOKEN}"
}
},
"postgres": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@bytebase/dbhub",
"--dsn",
"${KIOSQUE_DB_DSN:-postgresql://readonly:local@localhost:5432/kiosque}"
]
}
}
}
Le paquet @bytebase/dbhub est cité tel qu'il figure dans la documentation officielle (exemple pratique de mcp.md) ; il expose Claude à une base relationnelle à travers un DSN, avec un utilisateur en lecture seule pour empêcher toute écriture. Le DSN par défaut pointe vers une base locale : chaque développeur bascule sur la sienne via KIOSQUE_DB_DSN dans son environnement.
À la première ouverture, Karim voit un dialogue de workspace trust, accepte, puis chaque serveur passe par ⏸ Pending approval — il approuve. Pour le GitHub HTTP, il lance ensuite claude mcp login github et complète le flux OAuth (ou renseigne son PAT si l'organisation impose cette voie). Pour Postgres, Claude Code lance npx -y @bytebase/dbhub ... à la volée à la première utilisation.
Ce que Claude peut faire, une fois connecté
Sur le canal GitHub, Karim peut demander : « Résume les 20 dernières issues ouvertes tagguées bug, groupe-les par module. » Claude Code appelle search_issues, agrège, résume — sans que Karim ait besoin d'écrire du curl. Sur le canal Postgres : « Quel est le panier moyen des commandes livrées ce mois-ci ? » — Claude Code compose une requête SQL en lecture seule, l'exécute, remet le résultat en langage naturel.
Trois précautions valent la peine d'être répétées.
- Le user Postgres doit être en lecture seule au niveau de la base. Un hook
PreToolUsesur les outilsmcp__postgres__*peut renforcer, mais c'est la base qui est la source de vérité. - Le PAT GitHub doit être fin (fine-grained) et limité aux dépôts précis auxquels Claude a besoin d'accès. Un token trop large est une porte d'entrée dangereuse.
- Le
.mcp.jsonversionné ne doit contenir aucun secret, uniquement des${VAR}avec valeurs par défaut génériques. Les vrais secrets vivent dans les.envlocaux ou dans un gestionnaire.
Le SDK et les outils personnalisés
Si aucun serveur MCP ne répond au besoin, on peut en écrire un. Le côté serveur suit la spécification MCP officielle et se code dans n'importe quel langage. Côté Claude Code, une approche plus légère consiste à définir un outil personnalisé via l'Agent SDK : la doc agent-sdk__custom-tools.md décrit un mécanisme pour exposer une fonction locale comme un outil MCP en process, sans lancer de serveur externe. C'est particulièrement utile pour les outils métiers propres à Kiosque — par exemple, appeler l'API interne de calcul de commission — quand on ne veut pas les publier sous forme de serveur MCP réutilisable.
/mcp en session : la vue de contrôle
Une fois configuré, /mcp donne l'image de l'instant. Chaque serveur est affiché avec :
- Son transport et son endpoint (avec les
${VAR}non expansées côté affichage — jamais de secret à l'écran). - Son statut :
Connected,Needs authentication,Failed to connect,⏸ Pending approval,⊘ Disabled for this project,cached(tools chargés depuis un cache de découverte). - Son nombre d'outils.
- Un menu par serveur :
Sign in,Re-authenticate,Clear authentication,Reconnect, désactivation par projet.
Sur un échec, la ligne Issue: donne le code HTTP retourné (401, 403, 500…) et le texte d'erreur du serveur, sans jamais inclure l'URL complète — les secrets qui pourraient s'y trouver sont protégés.
Un serveur en Failed to connect avec un 401 : le token est probablement mauvais ou expiré. En Failed to connect avec un code réseau : dig ou curl l'URL à la main pour vérifier la connectivité. En Pending approval persistant : le workspace n'est pas trusted ; taper claude dans le répertoire, accepter le dialogue.
En résumé
- MCP standardise l'accès de Claude Code aux services externes ; quatre transports :
http(recommandé),sse(déprécié),stdio(local),ws(push). - Trois scopes : local (
~/.claude.json, privé), project (.mcp.json, versionné, exige approbation), user (~/.claude.json, tous vos projets). - CLI :
claude mcp add,add-json,list,get,remove,login,logout,reset-project-choices. En session :/mcpouvre le panneau de contrôle. .mcp.json: format{"mcpServers": {...}}, expansion${VAR:-défaut}danscommand,args,env,url,headers;typeobligatoire pour les serveurs distants.- Authentification : OAuth automatique sur les serveurs distants ;
claude mcp login <nom>sans passer par/mcp; un headerAuthorizationque vous fournissez court-circuite OAuth. - Pour Kiosque, un
.mcp.jsonde deux entrées suffit : GitHub HTTP authentifié par PAT ; Postgres stdio en lecture seule via un DSN passé en${VAR:-défaut}.
Module suivant : Plugins et marketplaces : empaqueter et partager votre outillage — comment regrouper vos skills, sous-agents, hooks et serveurs MCP dans un plugin unique et le diffuser à toute l'équipe.