Claude Code
Piloter l'agent au lieu de l'exécuter
Setup, CLAUDE.md, Skills, Hooks, Subagents, MCP, patterns avancés (Writer/Reviewer, fan-out, CI/CD).
- 01Installer et configurer Claude Code pour un projet réel
- 02Maîtriser les Skills, Hooks et Subagents
- 03Connecter des services externes via MCP
- 04Utiliser les patterns avancés : Writer/Reviewer, fan-out, mode CI/CD
1. Installation & Setup
Installation
# Méthode recommandée : binaire natif, se met à jour tout seul en tâche de fond
curl -fsSL https://claude.ai/install.sh | bash
# Windows PowerShell : irm https://claude.ai/install.ps1 | iex
# Alternatives : brew install --cask claude-code
# winget install Anthropic.ClaudeCode
# npm install -g @anthropic-ai/claude-code (demande Node.js 22+)
# Vérification
claude --version
claude doctor # diagnostic install + settings, sans lancer de session
Le paquet npm installe le même binaire natif que l'installeur : Node ne sert qu'à le télécharger, pas à l'exécuter. Il faut un compte Pro, Max, Team, Enterprise ou Console ; le plan gratuit de claude.ai ne donne pas accès à Claude Code.
Un mot sur la première ligne, puisqu'on parle de supply chain au Module 9 : curl | bash exécute un script distant sans que tu l'aies lu. C'est la méthode officielle et l'URL est bien celle d'Anthropic, mais si ta politique interne l'interdit, ouvre l'URL dans un navigateur avant, ou passe par brew / winget qui vérifient les signatures.
Première session
# Dans le répertoire de ton projet
cd my-project
claude
# Mode non-interactif (CI/CD)
claude --print "Génère un résumé de l'architecture du projet"
Structure d'un projet équipé
.claude/
settings.json → Permissions et hooks, versionné, partagé avec l'équipe
settings.local.json → Tes surcharges perso, gitignoré
skills/ → Skills, invocables aussi en /slash-command
security-audit/
SKILL.md
test-generator/
SKILL.md
agents/ → Définitions de subagents
reviewer.md
CLAUDE.md → Contexte global (Module 5)
.mcp.json → Serveurs MCP partagés (à la racine, pas dans .claude/)
Deux emplacements surprennent souvent. Les serveurs MCP ne vivent pas dans settings.json mais dans .mcp.json à la racine (voir §6). Et settings.local.json est là pour tes réglages personnels : c'est lui qu'on gitignore, pas settings.json.
2. Permissions & Sécurité
Claude Code demande ta permission avant d'agir. C'est le mécanisme Human-in-the-Loop fondamental.
Où vivent les réglages
Quatre niveaux, du plus fort au plus faible :
| Niveau | Fichier | Pour qui |
|---|---|---|
| Managed | déployé par l'IT (managed-settings.json) | toute l'organisation, non contournable |
| Local | .claude/settings.local.json | toi, sur ce repo (gitignoré) |
| Projet | .claude/settings.json | toute l'équipe (versionné) |
| Utilisateur | ~/.claude/settings.json | toi, sur tous tes projets |
Une exception utile à connaître : les règles de permission ne s'écrasent pas d'un niveau à l'autre, elles fusionnent, et un deny l'emporte toujours sur un allow. C'est ce qui permet à une équipe de poser un socle interdit dans settings.json sans qu'un développeur puisse le lever depuis son fichier local.
Trois verdicts possibles
// .claude/settings.json
{
"permissions": {
"allow": [
"Bash(npm run test)",
"Bash(npm run lint)",
"Bash(git diff:*)",
"Bash(git log:*)",
"Edit(src/**)",
"Edit(tests/**)"
],
"ask": [
"Bash(git commit:*)",
"Bash(npm run build)",
"Edit(*.config.*)"
],
"deny": [
"Bash(git push:*)",
"Bash(npm publish:*)",
"Bash(rm -rf:*)",
"Read(./.env)",
"Read(./.env.*)",
"Edit(.env*)"
]
}
}
allow passe sans demander, ask demande à chaque fois, deny bloque. Note le Read(./.env) en deny : interdire l'écriture d'un fichier de secrets ne sert à rien si l'agent peut encore le lire et le recracher dans un log ou un commentaire de PR.
Règles de permission
À autoriser librement :
- Lecture de fichiers (
Read) - Exécution de tests et linters
- Écriture dans
src/,tests/ git diff,git log,git status
À autoriser avec précaution :
git commit(vérifie le message)- Commandes de build
- Modifications de config
À ne jamais autoriser :
git push(tu décides quand)npm publish,docker push- Modifications de
.env rm -rfsur des chemins critiques
3. Les Skills : expertise on-demand
Un Skill est une expertise encapsulée, chargée uniquement quand l'agent en a besoin. Cela économise le contexte et améliore la précision.
Créer un skill manuellement
.claude/skills/security-audit/SKILL.md
---
name: security-audit
description: >
Audite le code source pour détecter des vulnérabilités de sécurité.
Couvre OWASP Top 10, secrets codés en dur, et mauvaises pratiques auth.
Utilise quand : on te demande un audit sécurité, une revue de code critique,
ou l'analyse d'un module d'authentification.
---
# Security Auditor
Tu es un expert en sécurité applicative (OWASP Top 10, CWE).
## Processus d'audit
Référentiel : OWASP Top 10 2025. Pour chaque fichier analysé :
### A01 — Broken Access Control
- Accès aux ressources sans vérification de propriété (IDOR)
- Routes non protégées, contrôle d'autorisation côté client uniquement
### A02 — Security Misconfiguration
- CORS trop permissif
- Headers de sécurité manquants
- Stack traces exposées
### A03 — Software Supply Chain Failures
- Dépendance inventée ou inexistante (hallucination de package)
- Version non épinglée, dépendance abandonnée
### A04 — Cryptographic Failures
- PII dans les logs, données sensibles dans les URLs
- Absence de chiffrement at-rest, algorithme obsolète
### A05 — Injection
- SQL : paramètres non bindés, concaténation de strings
- XSS : sortie HTML non échappée, innerHTML non sanitizé
- Command : exec/eval avec user input
### A07 — Authentication Failures
- Tokens ou mots de passe codés en dur
- Sessions sans expiration
## Format de sortie
Pour chaque problème :
| Fichier:Ligne | Catégorie OWASP | Sévérité | Description | Fix recommandé |
Sévérité : Critical / High / Medium / Low / Info
Termine par un score de risque global : Critical / High / Medium / Low
Créer un skill avec l'IA
Activer un skill
Choisir qui déclenche quoi
Le déclenchement automatique n'est pas toujours souhaitable. Trois champs de frontmatter suffisent à le cadrer :
disable-model-invocation: true # Toi seul peux l'invoquer, via /nom
user-invocable: false # Claude seul peut le charger, il n'apparaît pas dans le menu /
allowed-tools: Read, Grep # Outils pré-approuvés le temps du tour qui invoque le skill
disable-model-invocation est celui qui compte en pratique. Un skill /deploy ou /commit a des effets de bord : tu ne veux pas que l'agent décide tout seul que le code a l'air prêt. À l'inverse, un skill de connaissance métier pure (comment marche le vieux système de facturation) gagne à être en user-invocable: false : Claude le charge quand c'est pertinent, mais /vieux-systeme n'est pas une action qu'un humain a envie de taper.
4. Les Hooks : automatisation déterministe
Les Hooks s'exécutent à des moments précis du cycle de l'agent, indépendamment de ce que l'IA décide. C'est le plan de contrôle.
Les événements qui servent vraiment
Il y en a une trentaine. Ceux qui couvrent 90 % des besoins :
| Événement | Déclencheur | Usage principal |
|---|---|---|
SessionStart | Début de session | Injecter contexte dynamique (branche Git, sprint actuel) |
SessionEnd | Fin de session | Archiver le transcript, nettoyer un environnement temporaire |
UserPromptSubmit | Avant que le prompt utilisateur soit envoyé | Réécriture, ajout de contexte, refus |
PreToolUse | Avant chaque outil | Bloquer des actions, scan sécurité |
PostToolUse | Après chaque outil | Logger, valider, enrichir |
PostToolUseFailure | Après un outil qui a échoué | Remonter l'erreur, déclencher un fallback |
Notification | Notification système (permission, idle…) | Routage vers Slack, pager |
PreCompact / PostCompact | Autour de la compaction du contexte | Sauvegarder un résumé avant compression |
Stop | Fin de la réponse de l'agent | Rapport d'audit, mise à jour du journal |
SubagentStart / SubagentStop | Autour d'un subagent | Logger les sous-tâches indépendamment |
Le reste couvre des besoins plus pointus : PermissionRequest et PermissionDenied pour instrumenter les refus, FileChanged pour réagir à une modification externe, WorktreeCreate pour préparer un worktree. La liste complète est dans la doc.
Exemple : Scan de secrets avant écriture de fichier
// .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/scan-secrets.sh"
}
]
}
]
}
}
Claude Code passe le contexte du hook en JSON sur stdin (et non en argument de ligne de commande). Le script lit tool_input.file_path :
# .claude/hooks/scan-secrets.sh
#!/usr/bin/env bash
# Le hook reçoit un objet JSON sur stdin. On en extrait le chemin du fichier.
FILE=$(jq -r '.tool_input.file_path // empty')
[ -z "$FILE" ] && exit 0
# Détecte les patterns de secrets courants
if grep -Eq "(api_key|secret|password|token)[[:space:]]*=[[:space:]]*['\"][^'\"]{8,}" "$FILE" 2>/dev/null; then
echo "SECRET DÉTECTÉ dans $FILE — écriture bloquée" >&2
exit 2 # Code 2 = bloque l'action et renvoie stderr à Claude
fi
exit 0
Exemple : Injection de contexte Git au démarrage
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/inject-git-context.sh"
}
]
}
]
}
}
Ce que le hook écrit sur stdout est injecté dans le contexte de la session :
# .claude/hooks/inject-git-context.sh
BRANCH=$(git branch --show-current)
LAST_COMMITS=$(git log --oneline -5)
CHANGED_FILES=$(git diff --name-only HEAD~1)
printf '## Contexte Git actuel\n'
printf 'Branche : %s\n' "$BRANCH"
printf 'Derniers commits :\n%s\n' "$LAST_COMMITS"
printf 'Fichiers modifiés depuis le dernier commit :\n%s\n' "$CHANGED_FILES"
Codes de retour des hooks
| Code | Comportement |
|---|---|
0 | Succès. stdout n'enrichit le contexte que sur SessionStart, UserPromptSubmit et UserPromptExpansion ; ailleurs il part dans le log de debug |
2 | Erreur bloquante : l'action est stoppée et stderr est renvoyé à Claude |
autre (1, …) | Erreur non bloquante : stderr est montré à l'utilisateur, l'exécution continue |
5. Les Subagents : délégation et isolation
Les subagents permettent d'isoler des tâches spécifiques dans des sessions séparées, sans polluer le contexte principal.
Cas d'usage
L'intérêt n'est pas la parallélisation, c'est le contexte jeté. Le subagent lit trente fichiers, remonte dix lignes de conclusion, et les trente fichiers ne polluent jamais ta session principale.
Définir un subagent réutilisable
Quand tu relances toujours le même type d'investigation, fige-le dans un fichier. Projet : .claude/agents/, versionné avec le repo. Perso : ~/.claude/agents/, disponible partout.
---
name: reviewer
description: Revue de code critique. Utilise après une implémentation,
avant d'ouvrir la PR.
tools: Read, Glob, Grep
model: sonnet
---
Tu es un architecte senior. Tu revois du code sans savoir qui l'a écrit.
Cherche : bugs, failles sécu, violations de @CLAUDE.md, edge cases non gérés.
Pour chaque point : fichier:ligne, gravité, correctif concret.
Sois critique. Pas de complaisance.
Le champ tools fait le vrai travail : en le limitant à Read, Glob, Grep, ce reviewer ne peut pas écrire, même si on le lui demande. C'est un garde-fou structurel, pas une consigne que le modèle peut ignorer. Omettre le champ donne au subagent tous les outils de la session. Le champ model sert à router : un subagent qui trie des logs n'a pas besoin d'Opus.
Pattern Writer / Reviewer
Un pattern simple et redoutable pour la qualité : deux sessions Claude distinctes, aucune mémoire partagée entre elles.
Résultat : le Reviewer n'a aucun biais positif envers le code du Writer. La qualité de la revue est maximale.
Fan-out sur plusieurs fichiers
Deux réflexes avant d'écrire la boucle. On laisse l'agent modifier le fichier en place au lieu de rediriger sa sortie : --print renvoie de la prose, avec parfois des blocs de code markdown autour, donc un > fichier.ts produit un fichier qui ne compile pas. Et on plafonne le parallélisme : sans ça, une boucle sur 400 fichiers ouvre 400 sessions d'un coup.
# Documenter tout src/, quatre sessions à la fois.
shopt -s globstar # rend src/**/*.ts récursif
document_file() {
claude --print --permission-mode acceptEdits \
"Ajoute les JSDoc manquants dans $1, directement dans le fichier.
Conventions : @src/examples/documented.ts
Ne touche à aucun autre fichier et ne modifie pas le code lui-même."
}
export -f document_file
printf '%s\n' src/**/*.ts | xargs -P 4 -I{} bash -c 'document_file "$@"' _ {}
6. Model Context Protocol (MCP)
Le MCP permet de connecter Claude Code à des services externes : GitHub, Linear, Sentry, base de données, Figma...
Où se configure un serveur MCP
C'est le piège le plus courant : pas dans settings.json. Trois portées, trois emplacements :
| Portée | Stocké dans | Visible par |
|---|---|---|
local (défaut) | ~/.claude.json | toi, sur ce projet uniquement |
project | .mcp.json à la racine du repo | toute l'équipe, via Git |
user | ~/.claude.json | toi, sur tous tes projets |
Le plus simple est de laisser la CLI écrire le fichier :
# Serveur distant (HTTP/OAuth), partagé avec l'équipe
claude mcp add --transport http --scope project sentry https://mcp.sentry.dev/mcp
# Serveur local en stdio : tout ce qui suit -- est passé au serveur
claude mcp add --scope project my-server -- npx -y @scope/mon-serveur
# Inspecter / diagnostiquer
claude mcp list
Le .mcp.json produit se versionne :
// .mcp.json (racine du projet)
{
"mcpServers": {
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp"
},
"postgres": {
"command": "npx",
"args": ["-y", "@scope/serveur-postgres"],
"env": {
"POSTGRES_CONNECTION_STRING": "${DATABASE_URL}"
}
}
}
}
Deux détails qui font gagner du temps. L'interpolation supporte ${VAR} et ${VAR:-valeur_par_défaut} : une variable non définie et sans défaut ne fait pas échouer le chargement, elle laisse le ${VAR} littéral en place et signale un avertissement dans claude mcp list. Et un serveur venu d'un .mcp.json versionné demande une approbation explicite au premier lancement : cloner un repo ne suffit pas à lui donner tes tokens.
Workflows rendus possibles avec MCP
Workflow 1 : Bug depuis Sentry → Fix automatique
Workflow 2 : Issue GitHub → Implémentation
Workflow 3 : Analyse de la base de données
Règles de sécurité MCP
À privilégier :
- Serveurs MCP officiels et maintenus
- Tokens avec permissions minimales (read-only si lecture seule)
- Variables d'environnement pour les tokens (jamais hardcodés)
À proscrire :
- Serveurs MCP tiers non vérifiés
- Tokens avec permissions complètes si non nécessaire
- MCP connectés à la production sans whitelist d'actions
7. Mode CI/CD et non-interactif
Claude Code peut s'exécuter sans supervision humaine dans les pipelines CI.
Revue de PR : l'action officielle
Pour GitHub Actions, l'action maintenue par Anthropic gère l'authentification, le checkout, le commentaire de PR et la gestion des permissions. C'est le chemin par défaut.
# .github/workflows/ai-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
ai-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: |
Revois le diff de cette PR pour des problèmes de sécurité critiques.
Focus : secrets exposés, injections, auth manquante.
Pour chaque point : fichier:ligne, gravité, correctif concret.
Si rien de critique, dis-le en une ligne.
claude_args: |
--max-turns 10
--model claude-sonnet-5
Deux choses à savoir sur cette action. Elle détecte seule son mode : avec un prompt, elle s'exécute immédiatement ; sans prompt, sur un issue_comment, elle répond aux mentions @claude. Et les options CLI ne sont pas des entrées YAML séparées, elles passent toutes par claude_args. Si tu maintiens un workflow écrit avant la v1, c'est là que ça casse : direct_prompt, model, max_turns et allowed_tools n'existent plus comme entrées.
Une variante qui vaut le détour : prompt accepte l'invocation d'un skill. Ajoute un actions/checkout avant l'étape, passe /audit-security, et ta CI exécute exactement le même skill que celui que ton équipe utilise en local. Un seul fichier à maintenir pour les deux.
Sortie non-interactive brute
Quand tu n'es pas sur GitHub Actions, ou que tu pipes vers ton propre outil :
# Sortie texte sur stdout
claude --print "tâche" > output.txt
# Sortie structurée : un objet enveloppe, le texte est dans le champ `result`
claude --print --output-format json "tâche" | jq -r '.result'
# Sans confirmation de permissions (uniquement en environnement isolé/CI)
claude --print --dangerously-skip-permissions "tâche"
# Interactif normal (développement)
claude
Agent SDK : embarquer Claude dans son propre code
Quand claude --print ne suffit pas (orchestration custom, streaming dans une UI, contrôle fin du contexte), passer par le SDK officiel.
import { query } from '@anthropic-ai/claude-agent-sdk'
// query() renvoie directement un async generator : on itère dessus,
// pas besoin de l'attendre avec await.
for await (const message of query({
prompt: 'Résume ce diff et propose un commit message',
options: {
cwd: process.cwd(),
permissionMode: 'plan', // Ne modifie rien
allowedTools: ['Read', 'Grep'], // Lecture seule
maxTurns: 4,
},
})) {
// Stream des événements (tool calls, texte, fin de session)
console.log(message)
}
À ce niveau, Claude Code devient un runtime d'agent qu'on intègre dans un bot Slack, une route API, un job worker. Le SDK existe en TypeScript et en Python.
8. Gestion de session avancée
Commandes essentielles
| Commande | Action |
|---|---|
/clear | Vide le contexte, nouvelle session propre |
/compact [instructions] | Compresse l'historique en résumé, préserve les instructions |
/resume | Ouvre le sélecteur de sessions passées (les sessions sont auto-sauvegardées) |
/rewind (ou Esc Esc) | Revient à un checkpoint antérieur (code et/ou conversation) |
/context | Visualise ce qui occupe le context window |
/usage (alias /cost) | Consommation et coût, plus le quota restant sur ton plan |
/permissions | Édite les règles d'autorisation sans quitter la session |
Shift+Tab | Cycle entre les modes Plan / Default / Accept-edits (prudence) |
Quand utiliser /compact vs /clear
Faire tourner deux sessions en parallèle : les worktrees
Tu veux lancer un refacto long pendant que tu corriges un bug urgent. Deux sessions Claude dans le même dossier vont se marcher dessus : elles éditent les mêmes fichiers et voient les modifications de l'autre en plein milieu de leur travail.
La réponse est un mécanisme Git standard, git worktree : plusieurs répertoires de travail branchés sur le même dépôt, chacun sur sa branche.
# Un dossier de travail séparé pour le refacto, sur sa propre branche
git worktree add ../projet-refacto -b refacto/extraction-service
# On y lance une session dédiée, isolée de celle du dossier principal
cd ../projet-refacto && claude
# Une fois la branche mergée, on nettoie
git worktree remove ../projet-refacto
Chaque worktree a son propre contexte : son CLAUDE.md est relu, ses fichiers modifiés lui appartiennent, et un /rewind dans l'un ne touche pas l'autre. C'est la forme la plus simple d'isolation (stratégie 4 du Module 5) et elle ne coûte rien : les worktrees partagent l'historique Git, pas une copie du dépôt.
Template de démarrage de session productive
Contexte du projet : @CLAUDE.md
Tâche actuelle : [description précise]
Fichiers concernés : @[fichier1] @[fichier2]
Objectif de cette session : [ce que je veux atteindre]
Critère de succès : [comment savoir qu'on a réussi]
On commence par la phase EXPLORE.
9. Slash commands personnalisés
Au-delà des commandes système (/clear, /compact), tu peux créer tes propres slash commands au niveau projet ou utilisateur. C'est le feature qui transforme un workflow récurrent en un seul /audit, /migrate, /release-notes.
Création
.claude/commands/
audit-security.md → invoqué par /audit-security
release-notes.md → invoqué par /release-notes
refactor-module.md → invoqué par /refactor-module
Anatomie d'un slash command
---
description: Audit sécurité complet du diff courant
argument-hint: [optionnel : chemin spécifique à auditer]
allowed-tools:
- Read
- Grep
- Bash(git diff:*)
---
Tu es expert sécurité applicative (OWASP Top 10).
Si un argument est fourni : audite ce chemin. Sinon : audite `git diff origin/main...HEAD`.
Cherche :
1. Injection (SQL, XSS, command, prompt injection)
2. Auth/authz manquante ou mauvaise
3. Secrets exposés ou loggés
4. Validation des entrées manquante
5. Exposition d'erreurs internes
Pour chaque problème : fichier:ligne, sévérité (Critical/High/Medium/Low), fix concret.
Termine par un score global et une recommandation merge/no-merge.
Commandes utiles à avoir d'office
| Slash command | Usage |
|---|---|
/audit-security | Revue sécurité du diff courant |
/perf-check | Détection de problèmes de performance (N+1, allocations) |
/test-gen | Génération de tests pour le fichier ouvert |
/docs-update | Synchronisation des docs avec le code modifié |
/migrate | Migration de pattern (ex. : class component → hooks) |
/release-notes | Génération des release notes depuis git log |
/explain | Explication d'un fichier ou d'une fonction complexe |
Plugins & marketplaces : partager tout d'un coup
Un slash command se partage bien. Mais quand ton équipe a construit plusieurs commandes, des skills, des hooks et une config MCP, les copier-coller de projet en projet devient vite pénible. Les plugins règlent ça : un plugin regroupe commandes, skills, hooks et serveurs MCP dans un seul paquet qu'on installe et met à jour en une commande.
Et une marketplace, c'est simplement un dépôt Git qui liste des plugins. Ton équipe peut avoir la sienne, en interne.
# Ajouter la marketplace de ton équipe (un repo Git)
/plugin marketplace add mon-org/claude-plugins
# Installer un plugin depuis cette marketplace
/plugin install security-pack@mon-org
L'intérêt concret :
- Un seul point de vérité. Tu corriges un hook une fois dans le plugin, tout le monde reçoit la mise à jour. Fini les copies qui divergent d'un repo à l'autre.
- De l'onboarding en une commande. Un nouvel arrivant installe le plugin de l'équipe et récupère d'un coup les conventions, les commandes et les garde-fous.
- Du versionnage. Un plugin a une version : tu sais qui utilise quoi, et tu peux revenir en arrière.
10. Plan mode, checkpoints et rewind
Plan mode
Active explicitement le mode où Claude ne peut que lire et planifier, pas écrire. Idéal pour la phase EXPLORE.
# Au lancement
claude --permission-mode plan
# Ou dans la session
Shift+Tab → cycle entre Plan / Default / Accept-edits
Checkpoints et rewind
Claude Code prend des checkpoints à chaque modification (write/edit). Tu peux revenir en arrière sans toucher à Git.
/rewind → ouvre le sélecteur de checkpoints (ou double Esc)
Le sélecteur te laisse choisir le point de retour et ce que tu restaures : le code seul, la conversation seule, ou les deux. C'est la différence entre « j'efface tout » et « je rollback proprement à l'avant-dernière étape ». Sur une session d'agent qui part en vrille, ça sauve la mise.
Reprise de session
/resume → sélecteur des sessions précédentes
claude --resume → idem au lancement, depuis le terminal
Les sessions vivent dans ~/.claude/projects/<chemin-projet>/<session-id>.jsonl. Tu peux archiver ces transcripts si tu veux un audit trail (voir Module 9).
11. Construire son MCP server interne
Quand le serveur MCP n'existe pas pour ton SI interne (ton CRM maison, ton wiki Confluence avec une politique d'accès custom, ton outil de tickets), construis le tien. Le SDK MCP est simple, le protocole est stable.
Template minimal Node.js
// my-internal-mcp/server.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { z } from 'zod'
const server = new McpServer({ name: 'internal-tickets', version: '1.0.0' })
// L'API haut niveau `registerTool` déclare le schéma (via zod) et le handler
// en un seul endroit — plus de setRequestHandler(...) bas niveau à câbler.
server.registerTool(
'get_ticket',
{
description: 'Récupère un ticket Jira interne par sa clé',
inputSchema: { key: z.string().describe('Clé du ticket, ex. PROJ-1234') },
},
async ({ key }) => {
const ticket = await fetchTicket(key) // Ton API interne
return { content: [{ type: 'text', text: JSON.stringify(ticket) }] }
},
)
await server.connect(new StdioServerTransport())
Enregistrement dans Claude Code
// .mcp.json (racine du projet, versionné)
{
"mcpServers": {
"internal-tickets": {
"command": "node",
"args": ["${CLAUDE_PROJECT_DIR:-.}/tools/internal-mcp/server.js"],
"env": {
"INTERNAL_API_TOKEN": "${INTERNAL_API_TOKEN}"
}
}
}
}
Chemin relatif au projet plutôt qu'absolu : un /Users/toi/... en dur casse chez tout le monde sauf toi. ${CLAUDE_PROJECT_DIR} a besoin de son défaut :-. dans un .mcp.json, parce que la variable est résolue dans l'environnement du serveur et pas dans celui de Claude Code.
Bonnes pratiques d'entreprise
- Auth par token court dans
env, jamais hardcodé. - Allowlist des actions : un MCP qui lit n'écrit pas, un MCP qui écrit ne supprime pas.
- Rate limiting côté serveur MCP (évite qu'un agent bouclant n'épuise l'API interne).
- Logs structurés côté MCP : tout appel d'outil tracé avec timestamp + session ID Claude.
12. Coûts et quotas
Un agent qui tourne en boucle peut consommer plusieurs millions de tokens en une heure. Un senior pilote son budget.
Un ordre de grandeur pour te repérer
Avant de mesurer, il faut un repère. Voici des fourchettes en tokens (plus stables que les prix, qui bougent tout le temps). Prends-les comme un ordre de grandeur, pas comme une facture.
| Type de tâche | Tokens consommés (ordre de grandeur) |
|---|---|
| Petit fix ciblé (un bug, un fichier connu) | dizaines de milliers |
| Feature moyenne en EPCV (quelques fichiers + tests) | de quelques centaines de milliers à ~1-2 M |
| Exploration ou refacto sur un gros codebase | plusieurs millions |
Pour convertir en euros, une seule règle : va chercher le prix courant du provider (il change trop souvent pour tenir dans un guide) et applique-le au ratio input/output/cache que te donne /cost. Exemple de raisonnement, à recalculer avec les tarifs du jour : une feature moyenne à ~1 M de tokens, majoritairement en input, coûte « quelques euros » sur un modèle Sonnet, sensiblement plus sur un modèle Opus. Le prompt caching (Module 1) peut diviser la part de contexte répété par ~10 : c'est souvent lui qui fait la différence entre une session à quelques centimes et une session à quelques euros.
Mesurer
# Dans la session
/usage → consommation, coût et quota restant sur ton plan (/cost est un alias)
/context → ce qui remplit la fenêtre en ce moment, et ce qui la remplit pour rien
Optimiser
- Prompt caching (voir Module 1) : le CLAUDE.md devient quasi gratuit en cache hit.
- Plan mode pour les phases exploratoires : évite les écritures coûteuses sur des sessions qui auraient dérivé.
- Subagents ciblés : un subagent qui investigue n'a pas besoin du contexte complet du parent.
- Modèle adapté à la tâche : Haiku pour le boilerplate, Sonnet pour la majorité, Opus pour le raisonnement complexe et les architectures.
- Niveau d'effort adapté à la tâche (Module 1) : c'est le levier que presque personne n'utilise. Descendre à
lowoumediumsur du refacto mécanique ou un subagent qui trie des logs coupe la consommation sans rien changer au résultat. Attention en revanche à ne pas le faire varier en cours de session longue : ça casse le cache.
Alertes
Si tu opères Claude Code en équipe, mets en place :
- Un budget mensuel par utilisateur via l'API Anthropic.
- Une alerte Slack quand un utilisateur dépasse un seuil quotidien anormal.
- Un dashboard interne (Anthropic expose les usages par API key) pour repérer les agents qui bouclent.