Introduction au Tool Use (Function Calling)
Objectifs
- Comprendre le concept de Tool Use / Function Calling
- Savoir quand et pourquoi utiliser des outils
- Connaitre le workflow complet tool_use / tool_result
Le Tool Use est ce qui transforme Claude d'un modele de langage en un veritable agent. Sans outils, Claude ne peut que generer du texte. Avec des outils, il peut interroger des bases de donnees, appeler des APIs, manipuler des fichiers, controler des systemes. C'est le passage du "chatbot" a l'"assistant intelligent".
Qu'est-ce que le Tool Use ?
Le Tool Use (ou Function Calling) permet a Claude d'appeler des fonctions que vous definissez. Au lieu de repondre directement, Claude indique quelle fonction il veut appeler et avec quels parametres. Vous executez la fonction et renvoyez le resultat a Claude, qui formule sa reponse finale.
1. USER 2. CLAUDE 3. VOUS
ββββββββββββ ββββββββββββ ββββββββββββ
β "Quelle ββββββββββββββΊβ Analyse ββββββββββββββΊβ Executez β
β meteo β β et decideβ β la β
β a Paris β β d'appelerβ β fonction β
β ?" β β get_meteoβ β get_meteoβ
ββββββββββββ ββββββββββββ ββββββββββββ
β
5. USER 4. CLAUDE β
ββββββββββββ ββββββββββββ βββββββΌβββββ
β Voit la βββββββββββββββ Formule βββββββββββββββ Renvoyer β
β reponse β β reponse β β "22Β°C β
β finale β β finale β β soleil" β
ββββββββββββ ββββββββββββ ββββββββββββ
stop_reason: stop_reason:
"end_turn" "tool_use"
Pourquoi le Tool Use est essentiel
Claude a ete entraine sur des donnees statiques - il ne connait pas la meteo actuelle, votre base de donnees, ou vos APIs internes. Le Tool Use lui donne des "superpowers" : acces temps reel aux donnees, actions dans vos systemes, et integration dans vos workflows.
Cas d'usage courants
| Categorie | Exemples d'outils |
|---|---|
| Donnees | Query database, search documents, fetch API |
| Actions | Send email, create ticket, update record |
| Calcul | Calculator, code execution, data analysis |
| Externe | Weather API, stock prices, web search |
| Systeme | File operations, process control, monitoring |
Quiz
1. Quel est le stop_reason quand Claude veut utiliser un outil ?
2. Qui execute reellement la fonction/outil ?
Definir des Outils avec JSON Schema
Objectifs
- Definir des outils avec JSON Schema
- Specifier les types, descriptions, parametres requis
- Ecrire des descriptions qui guident Claude
Structure d'une definition d'outil
tools = [
{
"name": "get_weather",
"description": "Obtenir la meteo actuelle d'une ville. Utiliser quand l'utilisateur demande la temperature, les conditions meteo ou les previsions.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Le nom de la ville (ex: Paris, Lyon, New York)"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Unite de temperature"
}
},
"required": ["city"]
}
}
]Types JSON Schema supportes
| Type | Exemple | Description |
|---|---|---|
| string | "Paris" | Texte libre ou enum |
| number | 42.5 | Nombre decimal |
| integer | 42 | Nombre entier |
| boolean | true/false | Booleen |
| array | ["a","b"] | Liste de valeurs |
| object | {"k":"v"} | Objet imbrique |
Regle d'or pour les descriptions
La description de l'outil est cruciale - c'est ce que Claude lit pour decider s'il doit utiliser cet outil. Soyez explicite sur quand l'utiliser et ce qu'il retourne. Une mauvaise description = Claude n'utilisera pas l'outil au bon moment.
Quiz
1. Quel champ rend un parametre obligatoire ?
Gestion du Flux Tool Use
Objectifs
- Implementer la boucle tool_use β tool_result complete
- Gerer les erreurs d'execution d'outils
Implementation complete en Python
import anthropic
import json
client = anthropic.Anthropic()
# Definir les outils
tools = [{
"name": "search_database",
"description": "Recherche dans la base de donnees clients",
"input_schema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Terme de recherche"},
"limit": {"type": "integer", "description": "Nombre max de resultats"}
},
"required": ["query"]
}
}]
# Fonction qui execute l'outil
def execute_tool(name, inputs):
if name == "search_database":
# Votre logique ici (requete DB, API call, etc.)
return json.dumps({"results": [{"id": 1, "name": "Client A"}]})
return json.dumps({"error": f"Outil inconnu: {name}"})
# Boucle conversationnelle avec outils
messages = [{"role": "user", "content": "Trouve le client A dans la base"}]
while True:
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=1024,
tools=tools,
messages=messages
)
# Si Claude a fini de repondre
if response.stop_reason == "end_turn":
print("Reponse:", response.content[0].text)
break
# Si Claude veut utiliser un outil
if response.stop_reason == "tool_use":
# Ajouter la reponse de Claude a l'historique
messages.append({"role": "assistant", "content": response.content})
# Executer chaque outil demande
tool_results = []
for block in response.content:
if block.type == "tool_use":
print(f"Outil: {block.name}({block.input})")
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
# Renvoyer les resultats a Claude
messages.append({"role": "user", "content": tool_results})Gestion d'erreur dans les outils
Si l'execution d'un outil echoue, renvoyez un tool_result avec is_error: true. Claude comprendra l'erreur et adaptera sa reponse (retry, message d'erreur utilisateur, outil alternatif).
# En cas d'erreur d'execution
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": "Erreur: base de donnees indisponible",
"is_error": True # Claude saura que c'est une erreur
})Quiz
1. Que faire si l'execution d'un outil echoue ?
Tool Use Avance : Multi-Tools et Parallel
Objectifs
- Gerer plusieurs outils en parallele
- Controler la selection d'outils avec tool_choice
- Optimiser les performances multi-tools
Parallel Tool Use
Claude peut decider d'appeler plusieurs outils en parallele dans une seule reponse. Par exemple, si l'utilisateur demande "meteo a Paris ET a Lyon", Claude appellera get_weather deux fois simultanement.
# La reponse de Claude peut contenir multiple tool_use blocks:
# response.content = [
# TextBlock("Je vais chercher les deux..."),
# ToolUseBlock(name="get_weather", input={"city": "Paris"}),
# ToolUseBlock(name="get_weather", input={"city": "Lyon"})
# ]
# Vous DEVEZ renvoyer ALL tool_results:
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})Controler la selection avec tool_choice
| tool_choice | Comportement |
|---|---|
| {"type": "auto"} | Claude decide (defaut) |
| {"type": "any"} | Force l'utilisation d'un outil |
| {"type": "tool", "name": "X"} | Force un outil specifique |
| {"type": "none"} | Interdit les outils (texte seulement) |
Quiz
1. Comment forcer Claude a utiliser un outil specifique ?
Tool Search et Programmatic Tool Calling
Objectifs
- Utiliser le lazy loading d'outils pour les grands catalogues
- Implementer des patterns de tool routing
Probleme des grands catalogues d'outils
Quand vous avez 50+ outils, les envoyer tous dans chaque requete consomme beaucoup de tokens et ralentit Claude. La solution : le tool routing.
User Question
β
βΌ
βββββββββββββββ
β ROUTER β Haiku (rapide, pas cher)
β "Quel type β Classifie la question
β d'outil?" β
ββββββββ¬βββββββ
β
ββββββΌβββββ¬βββββββββ
βΌ βΌ βΌ βΌ
[DB] [API] [File] [Calc] Sous-ensemble d'outils
β β β β
βΌ βΌ βΌ βΌ
βββββββββββββββββββββββ
β CLAUDE (Sonnet) β Recoit seulement 2-3 outils
β avec outils cibles β pertinents
βββββββββββββββββββββββ
# Etape 1 : Router avec Haiku (rapide + pas cher)
router_response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=50,
system="Classifie la question: database, api, file, calculation. Reponds UNIQUEMENT le mot.",
messages=[{"role": "user", "content": user_question}]
)
category = router_response.content[0].text.strip()
# Etape 2 : Selectionner les outils pertinents
tool_sets = {
"database": [query_tool, schema_tool],
"api": [http_get_tool, http_post_tool],
"file": [read_file_tool, write_file_tool],
"calculation": [calculator_tool, chart_tool]
}
selected_tools = tool_sets.get(category, all_tools)
# Etape 3 : Appeler Sonnet avec outils cibles
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=2048,
tools=selected_tools, # Seulement 2-3 outils
messages=[{"role": "user", "content": user_question}]
)Avantages du tool routing
Moins de tokens en input = moins cher et plus rapide. Claude est aussi plus precis quand il a moins d'outils a choisir. C'est un pattern essentiel pour les systemes de production avec beaucoup d'outils.
Computer Use (Beta)
Objectifs
- Comprendre le Computer Use et ses capacites
- Configurer l'outil Computer Use
- Connaitre les cas d'usage et limites
Qu'est-ce que Computer Use ?
Computer Use permet a Claude de controler un ecran d'ordinateur : voir l'ecran (screenshot), cliquer, taper du texte, scroller. C'est comme donner a Claude le controle de votre souris et clavier.
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=4096,
tools=[
{
"type": "computer_20241022",
"name": "computer",
"display_width_px": 1920,
"display_height_px": 1080
}
],
messages=[{
"role": "user",
"content": "Ouvre le navigateur et va sur docs.anthropic.com"
}]
)
# Claude repondra avec des actions:
# - screenshot: prendre une capture d'ecran
# - click: cliquer a des coordonnees (x, y)
# - type: taper du texte
# - key: appuyer sur une touche
# - scroll: scrollerSecurite Computer Use
Computer Use est en beta. Ne l'utilisez PAS pour des actions sensibles (operations bancaires, donnees personnelles). Toujours dans un environnement sandboxe (VM, container). Claude peut faire des erreurs de clic.
Cas d'usage
- Tests UI automatises - Tester des interfaces web comme un humain
- Web scraping - Naviguer et extraire des donnees de sites complexes
- Automatisation desktop - Remplir des formulaires, generer des rapports
- Demonstration - Creer des demos interactives
Lab : Agent avec Outils
Objectifs
- Creer un agent complet avec base de donnees et API
Lab - Agent Assistant avec Outils
Etape 1 : Definir 3 outils
Creez les definitions JSON Schema pour : search_products (chercher des produits), get_order_status (statut commande), send_email (envoyer un email).
Etape 2 : Implementer les fonctions
Creez des fonctions Python qui simulent l'execution (retournent des donnees mockees en JSON).
Etape 3 : Boucle agentique
Implementez la boucle while qui gere le flux tool_use/tool_result jusqu'a end_turn.
Etape 4 : Tester
Testez avec : "Cherche des laptops en stock et envoie le resultat par email a admin@company.com". Claude devrait appeler search_products puis send_email.
Bonus : Ajouter le tool routing
Ajoutez un routeur Haiku qui selectionne les outils pertinents avant d'appeler Sonnet.
Quiz - Tool Use
Examen Module 2.1 - Tool Use
1. Qui execute la fonction quand Claude fait un tool_use ?
2. Comment limiter Claude a un outil specifique ?
3. Que faire quand Claude renvoie 3 tool_use blocks en parallele ?
4. Quel champ indique une erreur dans un tool_result ?
5. Pourquoi utiliser le tool routing ?
Introduction au Model Context Protocol (MCP)
Objectifs
- Comprendre ce qu'est MCP et pourquoi il existe
- Connaitre la difference entre Tool Use natif et MCP
- Identifier les cas d'usage ideaux pour MCP
MCP est au Tool Use ce que USB est aux peripheriques. Avant USB, chaque peripherique avait son propre connecteur. MCP standardise la connexion entre les LLMs et les sources de donnees/outils. Un serveur MCP ecrit une fois fonctionne avec n'importe quel client compatible : Claude Desktop, Claude Code, Cursor, Zed, etc.
Le probleme que MCP resout
Avec le Tool Use natif, vous devez recoder chaque integration pour chaque application. Si vous avez 10 outils et 5 applications, cela fait 50 integrations a maintenir. MCP reduit cela a 10 serveurs + 5 clients = 15 composants.
AVANT MCP (N x M integrations) AVEC MCP (N + M composants)
βββββββββββ βββββββββββ
β App 1 ββββ¬βββ¬βββ β App 1 ββββ
βββββββββββ€ β β β βββββββββββ€ β
β App 2 ββββΌβββΌβββ€ β App 2 ββββ€ ββββββββββββ
βββββββββββ€ β β β βββββββββββ€ ββββ€ Protocol β
β App 3 ββββΌβββΌβββ€ β App 3 ββββ€ β MCP β
βββββββββββ β β β βββββββββββ β ββββββββββββ
βββββββββββ β β β β
βΌ βΌ βΌ βΌ β ββββββΌβββββ
βββββββ ββββββββββββββ βββββββ β βΌ βΌ βΌ
βDB β βAPI ββFilesβ βDB ββββββββ ββββββββββββ
βββββββ ββββββββββββββ βAPI β βGit ββSlackβ
βFilesβ ββββββββββββ
βββββββ
Les 3 primitives MCP
| Primitive | Description | Controle par | Analogie |
|---|---|---|---|
| Tools | Fonctions executables par le LLM | Le modele decide | POST /api/action |
| Resources | Donnees exposees au LLM | L'application decide | GET /api/data |
| Prompts | Templates de prompts reutilisables | L'utilisateur decide | GET /templates |
Tool Use natif vs MCP
Tool Use natif : vous definissez les outils dans chaque appel API. Ideal pour les integrations simples et specifiques.
MCP : les outils sont exposes par des serveurs standardises. Ideal pour les ecosystemes multi-applications et la reutilisabilite.
Les deux approches sont complementaires, pas concurrentes.
Historique et adoption
- Nov 2024 : Anthropic publie MCP en open source
- 2025 : Adoption par Claude Desktop, Cursor, Zed, Windsurf, Cline
- 2025-2026 : 100+ serveurs MCP dans le registry officiel
- Spec actuelle : JSON-RPC 2.0 avec transports stdio et HTTP/SSE
Ne construisez pas un serveur MCP pour tout. Si votre outil est utilise par une seule application, le Tool Use natif suffit. MCP brille quand vous voulez partager des outils entre plusieurs clients, ou quand vous utilisez des outils existants du registry.
Architecture MCP : Clients, Serveurs, Transports
Objectifs
- Maitriser l'architecture client-serveur de MCP
- Comprendre les transports stdio et HTTP/SSE
- Savoir choisir le bon transport selon le cas d'usage
L'architecture MCP suit le modele JSON-RPC 2.0. Si vous avez deja travaille avec le Language Server Protocol (LSP) pour les IDE, MCP suit exactement le meme principe : un protocole standardise entre un client (l'application) et un serveur (le fournisseur de capacites).
Architecture globale
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HOST APPLICATION β
β (Claude Desktop, Claude Code, IDE, Custom App) β
β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β MCP Client β β MCP Client β β MCP Client β β
β β #1 β β #2 β β #3 β β
β ββββββββ¬βββββββ ββββββββ¬βββββββ ββββββββ¬βββββββ β
βββββββββββΌβββββββββββββββββΌβββββββββββββββββΌβββββββββββ
β stdio β stdio β HTTP/SSE
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββ βββββββββββββββββββ
β MCP Server β β MCP Server β β MCP Server β
β (Filesystem)β β (PostgreSQL)β β (Remote API) β
β Local β β Local β β Cloud/Remote β
βββββββββββββββ βββββββββββββββ βββββββββββββββββββ
Les transports
stdio (Standard I/O)
- Processus local lance par le client
- Communication via stdin/stdout
- Pas de reseau, pas de ports
- Ideal pour les outils locaux
- Plus simple et plus securise
HTTP + SSE
- Serveur distant accessible via HTTP
- SSE pour les notifications serveurβclient
- Necessite gestion reseau/auth
- Ideal pour les services cloud
- Permet le partage multi-utilisateurs
Cycle de vie d'une connexion
1. INITIALIZATION Client βββΊ initialize(capabilities) βββΊ Server Client βββ initialize_response βββ Server Client βββΊ initialized() βββΊ Server 2. OPERATION (boucle) Client βββΊ tools/list βββΊ Server Client βββ tools: [...] βββ Server Client βββΊ tools/call(name, args) βββΊ Server Client βββ result βββ Server 3. SHUTDOWN Client βββΊ shutdown/close βββΊ Server
Capabilities et negociation
Lors de l'initialisation, le client et le serveur echangent leurs capabilities. Le serveur declare ce qu'il supporte (tools, resources, prompts) et le client indique ce qu'il peut gerer (sampling, roots).
{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"clientInfo": {
"name": "claude-code",
"version": "1.0.0"
},
"capabilities": {
"sampling": {},
"roots": { "listChanged": true }
}
}
}Choisir le bon transport
stdio pour : outils de developpement locaux, acces fichiers, bases de donnees locales, securite maximale.
HTTP/SSE pour : APIs distantes, services partages, microservices, multi-utilisateurs.
En pratique, 90% des serveurs MCP utilisent stdio car ils sont executes localement.
Creer un Serveur MCP en Python
Objectifs
- Installer et configurer le SDK Python MCP
- Creer un serveur avec tools et resources
- Tester avec MCP Inspector
Le SDK Python est le plus populaire pour creer des serveurs MCP. Il utilise des decorateurs elegants qui transforment des fonctions Python ordinaires en outils MCP. Si vous connaissez FastAPI, vous retrouverez la meme philosophie.
Installation
# Installation du SDK pip install mcp # Ou avec les extras pour le serveur HTTP pip install "mcp[cli]" # Verifier l'installation python -c "import mcp; print(mcp.__version__)"
Serveur MCP minimal
from mcp.server.fastmcp import FastMCP
# Creer le serveur
mcp = FastMCP("mon-serveur")
# Definir un tool
@mcp.tool()
def calculer_prix(
prix_ht: float,
tva: float = 20.0
) -> str:
"""Calcule le prix TTC a partir du prix HT et du taux de TVA."""
ttc = prix_ht * (1 + tva / 100)
return f"Prix TTC : {ttc:.2f} EUR (TVA {tva}%)"
# Definir une resource
@mcp.resource("config://taux-tva")
def get_taux_tva() -> str:
"""Retourne les taux de TVA en vigueur."""
return """
Taux normal : 20%
Taux intermediaire : 10%
Taux reduit : 5.5%
Taux super-reduit : 2.1%
"""
# Definir un prompt template
@mcp.prompt()
def analyser_facture(contenu: str) -> str:
"""Analyse une facture et extrait les informations cles."""
return f"Analyse cette facture et extrait : montant HT, TVA, TTC, date, fournisseur.\n\nFacture:\n{contenu}"
# Lancer le serveur
if __name__ == "__main__":
mcp.run(transport="stdio")Ajouter des Resources dynamiques
import json
from datetime import datetime
@mcp.resource("data://clients/{client_id}")
def get_client(client_id: str) -> str:
"""Recupere les informations d'un client par son ID."""
# Simuler une base de donnees
clients = {
"C001": {"nom": "Acme Corp", "ca": 150000},
"C002": {"nom": "TechStart", "ca": 45000},
}
client = clients.get(client_id, {"error": "Client non trouve"})
return json.dumps(client, ensure_ascii=False, indent=2)
@mcp.resource("data://stats/today")
def get_stats_today() -> str:
"""Statistiques du jour."""
return json.dumps({
"date": datetime.now().isoformat(),
"commandes": 42,
"ca_jour": 12500.00
}, indent=2)Configuration dans Claude Desktop
{
"mcpServers": {
"mon-serveur": {
"command": "python",
"args": ["chemin/vers/serveur.py"],
"env": {
"API_KEY": "votre-cle"
}
}
}
}Tester avec MCP Inspector
# Lancer l'Inspector npx @modelcontextprotocol/inspector python serveur.py # Ouvre un navigateur a http://localhost:5173 # Vous pouvez tester tools, resources et prompts visuellement
Erreurs courantes
Le serveur ne repond pas : verifiez que vous utilisez transport="stdio" et que votre script ne print() rien sur stdout.
Tool non visible : le decorateur @mcp.tool() necessite un docstring. Sans docstring, l'outil n'aura pas de description.
Type errors : MCP utilise les type hints Python pour generer le JSON Schema. Annotez toujours vos parametres.
Creer un Serveur MCP en TypeScript
Objectifs
- Configurer un projet TypeScript pour MCP
- Creer un serveur avec le SDK officiel
- Gerer les schemas Zod pour la validation
Le SDK TypeScript est le premier SDK cree pour MCP et reste le plus mature. Si votre ecosysteme est Node.js/TypeScript, c'est le choix naturel. Il offre un typage fort et une integration excellente avec Zod pour la validation des parametres.
Setup du projet
# Initialiser le projet mkdir mon-mcp-server && cd mon-mcp-server npm init -y npm install @modelcontextprotocol/sdk zod npm install -D typescript @types/node # tsconfig.json npx tsc --init --target es2022 --module nodenext \ --moduleResolution nodenext --outDir dist
Serveur MCP TypeScript complet
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Creer le serveur
const server = new McpServer({
name: "analyse-code",
version: "1.0.0",
});
// Definir un tool avec schema Zod
server.tool(
"analyser_complexite",
"Analyse la complexite cyclomatique d'un fichier",
{
code: z.string().describe("Le code source a analyser"),
langage: z.enum(["python", "javascript", "typescript"])
.describe("Le langage du code"),
},
async ({ code, langage }) => {
// Compter les points de decision
const patterns = {
python: /\b(if|elif|for|while|except|and|or)\b/g,
javascript: /\b(if|else if|for|while|catch|&&|\|\|)\b/g,
typescript: /\b(if|else if|for|while|catch|&&|\|\|)\b/g,
};
const matches = code.match(patterns[langage]) || [];
const complexity = matches.length + 1;
return {
content: [{
type: "text",
text: JSON.stringify({
complexite: complexity,
niveau: complexity <= 5 ? "Simple" :
complexity <= 10 ? "Moderee" : "Elevee",
points_decision: matches.length,
}, null, 2),
}],
};
}
);
// Definir une resource
server.resource(
"docs://bonnes-pratiques",
"bonnes-pratiques://guide",
async (uri) => ({
contents: [{
uri: uri.href,
mimeType: "text/markdown",
text: "# Bonnes pratiques\n- Max 10 de complexite\n..."
}],
})
);
// Lancer avec transport stdio
const transport = new StdioServerTransport();
await server.connect(transport);Differences Python vs TypeScript
| Aspect | Python SDK | TypeScript SDK |
|---|---|---|
| Validation | Type hints Python | Schemas Zod |
| Decorateurs/API | @mcp.tool() | server.tool() |
| Async | asyncio natif | Promise/async-await |
| Resources | @mcp.resource(uri) | server.resource(name, uri) |
| Execution | python serveur.py | node dist/index.js |
// Dans .claude/settings.json ou via CLI
{
"mcpServers": {
"analyse-code": {
"command": "node",
"args": ["dist/index.js"],
"cwd": "/chemin/vers/projet"
}
}
}Astuce TypeScript
Utilisez z.describe() sur chaque champ Zod. Ces descriptions sont envoyees au LLM et l'aident a comprendre comment utiliser vos outils. Des descriptions claires = moins d'erreurs d'utilisation.
Serveurs MCP Populaires : Ecosysteme et Registry
Objectifs
- Connaitre les serveurs MCP les plus utiles
- Savoir installer et configurer des serveurs existants
- Combiner plusieurs serveurs pour des workflows puissants
Vous n'avez pas besoin de tout coder. L'ecosysteme MCP contient deja des dizaines de serveurs prets a l'emploi. Connaitre ce qui existe vous fera gagner des heures de developpement.
Serveurs officiels Anthropic
| Serveur | Fonctions | Transport | Cas d'usage |
|---|---|---|---|
| Filesystem | Lire/ecrire/rechercher des fichiers | stdio | Gestion de projets, analyse code |
| GitHub | Repos, issues, PRs, search | stdio | Dev workflow, code review |
| PostgreSQL | Requetes SQL, schema | stdio | Analyse donnees, reporting |
| Slack | Messages, channels, users | stdio | Communication, notifications |
| Google Drive | Fichiers, recherche, metadata | stdio | Gestion documentaire |
| Puppeteer | Navigation web, screenshots | stdio | Web scraping, tests |
| Git | Commits, branches, diff, log | stdio | Analyse de repos |
| Memory | Knowledge graph persistant | stdio | Memoire long-terme agents |
Installation d'un serveur existant
# Serveur GitHub via npx (aucune installation permanente) npx -y @modelcontextprotocol/server-github # Serveur Filesystem npx -y @modelcontextprotocol/server-filesystem /chemin/autorise # Serveur PostgreSQL npx -y @modelcontextprotocol/server-postgres \ "postgresql://user:pass@localhost/mydb"
Configuration multi-serveurs
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem",
"/Users/dev/projects"],
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "ghp_xxx" }
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres",
"postgresql://user:pass@localhost/analytics"]
}
}
}Composition de serveurs
La puissance de MCP est dans la composition. Avec les 3 serveurs ci-dessus, Claude peut :
- Lire du code source (Filesystem) β analyser les issues (GitHub) β verifier les donnees (PostgreSQL)
- Creer un workflow complet : "Regarde les fichiers modifies, cree une issue GitHub, et verifie l'impact en base de donnees"
Serveurs communautaires notables
- Brave Search : Recherche web via l'API Brave
- Notion : Pages, databases, blocks Notion
- Linear : Issues, projets, cycles Linear
- Sentry : Erreurs, performances, alertes
- Docker : Containers, images, volumes
- Raycast : Integration avec Raycast
Avant de coder votre propre serveur MCP, verifiez toujours le registry officiel et les awesome lists GitHub. Il y a de fortes chances qu'un serveur existe deja pour votre cas d'usage.
MCP et Claude Code : Integration Complete
Objectifs
- Configurer des serveurs MCP dans Claude Code
- Utiliser les outils MCP dans des sessions Claude Code
- Debugger les problemes de connexion MCP
Claude Code est l'un des clients MCP les plus puissants. Il peut se connecter a plusieurs serveurs MCP simultanement et utiliser leurs outils directement dans le terminal. L'integration est transparente : les outils MCP apparaissent comme des outils natifs.
Configuration MCP dans Claude Code
# Methode 1 : via la commande claude claude mcp add mon-serveur -- python serveur.py claude mcp add github -- npx -y @modelcontextprotocol/server-github # Methode 2 : via le fichier de configuration # Editer .claude/settings.json # Lister les serveurs configures claude mcp list # Tester un serveur claude mcp test mon-serveur
Niveaux de configuration
| Scope | Fichier | Usage |
|---|---|---|
| Projet | .mcp.json | Partage avec l'equipe via git |
| Utilisateur | ~/.claude/settings.json | Configuration personnelle globale |
| Session | claude mcp add --scope session | Temporaire, disparait apres la session |
{
"mcpServers": {
"project-db": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres",
"postgresql://localhost/monprojet"],
"env": {}
},
"project-files": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
"env": {}
}
}
}Utilisation en session
$ claude > Montre-moi les tables de la base de donnees # Claude utilise automatiquement le tool MCP "query" du serveur postgres # Resultat : liste des tables avec schemas > Quelles sont les issues ouvertes sur ce repo ? # Claude utilise le tool MCP "list_issues" du serveur GitHub # Resultat : liste des issues > Cree une migration SQL pour ajouter un champ email a la table users # Claude combine : lecture schema (MCP postgres) + ecriture fichier (natif) # Resultat : fichier migration cree
Debugging MCP
# Voir les logs de connexion MCP claude --mcp-debug # Tester la connexion a un serveur specifique claude mcp test mon-serveur # Inspector pour debug detaille npx @modelcontextprotocol/inspector python serveur.py
Problemes courants
"Server not found" : Verifiez le chemin de la commande (python vs python3, node vs npx).
"Connection timeout" : Le serveur met trop de temps a demarrer. Augmentez le timeout ou optimisez l'initialisation.
"Tool not available" : Le serveur MCP est connecte mais le tool n'est pas expose. Verifiez la liste des tools avec claude mcp list.
Lab : Construire un Pipeline MCP Complet
Objectifs
- Construire un serveur MCP from scratch
- L'integrer avec Claude Code
- Creer un pipeline multi-tools fonctionnel
Projet : Serveur MCP "Project Manager"
Vous allez creer un serveur MCP qui gere des taches de projet. Claude pourra creer, lister, modifier et supprimer des taches, generer des rapports, et analyser la charge de travail.
Etape 1 : Structure du projet
mkdir mcp-project-manager && cd mcp-project-manager pip install mcp touch server.py tasks.json
Etape 2 : Implementer le serveur
from mcp.server.fastmcp import FastMCP
import json
from datetime import datetime
from pathlib import Path
mcp = FastMCP("project-manager")
TASKS_FILE = Path(__file__).parent / "tasks.json"
def load_tasks():
if TASKS_FILE.exists():
return json.loads(TASKS_FILE.read_text())
return []
def save_tasks(tasks):
TASKS_FILE.write_text(json.dumps(tasks, indent=2, ensure_ascii=False))
@mcp.tool()
def creer_tache(titre: str, description: str, priorite: str = "moyenne",
assignee: str = "") -> str:
"""Cree une nouvelle tache dans le projet."""
tasks = load_tasks()
tache = {
"id": len(tasks) + 1,
"titre": titre,
"description": description,
"priorite": priorite,
"assignee": assignee,
"statut": "a_faire",
"cree_le": datetime.now().isoformat()
}
tasks.append(tache)
save_tasks(tasks)
return f"Tache #{tache['id']} creee : {titre}"
@mcp.tool()
def lister_taches(statut: str = "tous", assignee: str = "") -> str:
"""Liste les taches filtrees par statut et/ou assignee."""
tasks = load_tasks()
if statut != "tous":
tasks = [t for t in tasks if t["statut"] == statut]
if assignee:
tasks = [t for t in tasks if t["assignee"] == assignee]
if not tasks:
return "Aucune tache trouvee."
return json.dumps(tasks, indent=2, ensure_ascii=False)
@mcp.tool()
def modifier_statut(task_id: int, nouveau_statut: str) -> str:
"""Modifie le statut d'une tache (a_faire, en_cours, terminee)."""
tasks = load_tasks()
for t in tasks:
if t["id"] == task_id:
t["statut"] = nouveau_statut
save_tasks(tasks)
return f"Tache #{task_id} : statut -> {nouveau_statut}"
return f"Tache #{task_id} non trouvee."
@mcp.tool()
def rapport_projet() -> str:
"""Genere un rapport de synthese du projet."""
tasks = load_tasks()
total = len(tasks)
par_statut = {}
for t in tasks:
par_statut[t["statut"]] = par_statut.get(t["statut"], 0) + 1
return json.dumps({
"total_taches": total,
"par_statut": par_statut,
"priorites_hautes": [t["titre"] for t in tasks if t["priorite"] == "haute"],
"genere_le": datetime.now().isoformat()
}, indent=2, ensure_ascii=False)
@mcp.resource("project://resume")
def resume_projet() -> str:
"""Resume du projet en cours."""
tasks = load_tasks()
return f"Projet : {len(tasks)} taches au total"
if __name__ == "__main__":
mcp.run(transport="stdio")Etape 3 : Tester et integrer
# 1. Tester avec l'Inspector npx @modelcontextprotocol/inspector python server.py # 2. Ajouter a Claude Code claude mcp add project-manager -- python server.py # 3. Tester dans Claude Code claude > Cree 3 taches pour un sprint : API auth, tests unitaires, documentation > Passe "API auth" en cours > Genere un rapport du projet
Etape 4 : Exercices d'extension
- Ajoutez un tool
supprimer_tache(task_id) - Ajoutez une resource
project://changelogqui retourne l'historique des modifications - Ajoutez un prompt template
planifier_sprint(objectifs) - Combinez avec le serveur MCP GitHub pour synchroniser les taches avec des issues
Quiz : Model Context Protocol
Objectifs
- Valider vos connaissances sur MCP
- Verifier votre comprehension de l'architecture
- Tester vos competences pratiques
Quiz Module 2.2 - MCP
1. Quelles sont les 3 primitives de MCP ?
2. Quel transport est recommande pour un serveur MCP local ?
3. En Python, quel decorateur expose une fonction comme tool MCP ?
4. Quelle commande ajoute un serveur MCP a Claude Code ?
5. Quel fichier partage la config MCP d'un projet avec l'equipe ?
Claude Code CLI : Les Bases
Objectifs
- Installer et configurer Claude Code
- Maitriser les commandes essentielles
- Comprendre CLAUDE.md et la configuration
Claude Code est bien plus qu'un simple CLI. C'est un agent de developpement complet qui peut lire votre code, le modifier, executer des commandes, et meme utiliser des serveurs MCP. Le fichier CLAUDE.md est la cle : c'est la que vous donnez des instructions persistantes a Claude sur votre projet.
Installation
# Installation globale npm install -g @anthropic-ai/claude-code # Verifier l'installation claude --version # Premier lancement (authentification requise) claude # Lancer en mode non-interactif claude -p "Explique ce projet"
CLAUDE.md : Le fichier de configuration projet
CLAUDE.md est un fichier Markdown place a la racine de votre projet. Claude le lit automatiquement au demarrage de chaque session. C'est votre moyen de donner des instructions persistantes.
# Mon Projet ## Stack technique - Frontend : React 18 + TypeScript - Backend : FastAPI + PostgreSQL - Tests : pytest + vitest ## Conventions - Utiliser snake_case pour Python, camelCase pour TypeScript - Toujours ecrire des tests pour les nouvelles fonctionnalites - Commits en francais au format : "type: description" ## Architecture - /src/api : Routes FastAPI - /src/models : Models SQLAlchemy - /src/frontend : Application React - /tests : Tests unitaires et integration ## Commandes utiles - `make test` : Lancer les tests - `make lint` : Verifier le code - `make dev` : Lancer en developpement
Hierarchie des CLAUDE.md
Priorite (du plus haut au plus bas) βββββββββββββββββββββββββββββββββββ β .claude/settings.json β Configuration utilisateur βββββββββββββββββββββββββββββββββββ€ β CLAUDE.md (racine projet) β Instructions projet (git) βββββββββββββββββββββββββββββββββββ€ β src/CLAUDE.md β Instructions sous-dossier βββββββββββββββββββββββββββββββββββ€ β ~/.claude/CLAUDE.md β Instructions globales user βββββββββββββββββββββββββββββββββββ
Commandes slash essentielles
| Commande | Description |
|---|---|
/help | Aide et documentation |
/clear | Reinitialiser la conversation |
/compact | Compresser l'historique pour liberer du contexte |
/cost | Afficher le cout de la session |
/model | Changer de modele (opus, sonnet, haiku) |
/permissions | Gerer les permissions des outils |
/mcp | Gerer les serveurs MCP |
Bonnes pratiques CLAUDE.md
Gardez CLAUDE.md concis et factuel. Decrivez la stack, les conventions, et les commandes. Evitez les instructions contradictoires ou trop longues. Claude lit ce fichier a chaque session, donc chaque mot compte en termes de tokens.
Subagents et Parallelisme dans Claude Code
Objectifs
- Comprendre le systeme de subagents de Claude Code
- Utiliser le parallelisme pour accelerer les taches
- Connaitre les differents types d'agents specialises
Les subagents sont la fonctionnalite la plus puissante de Claude Code. Au lieu de tout faire sequentiellement, Claude peut lancer des agents specialises en parallele. Un agent explore le code, un autre execute les tests, un troisieme ecrit la documentation. C'est l'equivalent de diviser le travail dans une equipe.
Types de subagents
| Type | Specialite | Outils disponibles |
|---|---|---|
| Bash | Execution de commandes | Bash uniquement |
| Explore | Exploration de codebase | Read, Grep, Glob (pas d'ecriture) |
| Plan | Planification d'implementation | Read, Grep, Glob (pas d'ecriture) |
| general-purpose | Taches complexes multi-etapes | Tous les outils |
Comment Claude Code utilise les subagents
Vous : "Refactore le module auth et mets a jour les tests" Claude Code (agent principal) : βββ Lance Explore agent : "Trouve tous les fichiers auth" βββ Lance Explore agent : "Trouve tous les tests lies a auth" β (ces 2 agents s'executent en PARALLELE) β βββ Recoit les resultats des 2 agents βββ Planifie les modifications β βββ Edite les fichiers auth (sequentiellement) βββ Edite les fichiers tests (sequentiellement) β βββ Lance Bash agent : "npm test" (verification) βββ Presente le resultat
Le mode Plan
Claude Code peut entrer en "mode plan" pour analyser une tache complexe avant de l'executer. En mode plan, il explore le code, identifie les fichiers a modifier, et propose un plan d'action pour votre approbation.
$ claude > Ajoute l'authentification JWT a l'API Claude entre en mode plan... - Explore la structure du projet - Identifie les fichiers de routes existants - Analyse les dependances actuelles Plan propose : 1. Installer pyjwt et python-dotenv 2. Creer src/auth/jwt_handler.py 3. Creer src/auth/middleware.py 4. Modifier src/api/routes.py pour proteger les endpoints 5. Ajouter les tests dans tests/test_auth.py 6. Mettre a jour .env.example Approuvez-vous ce plan ? [Y/n]
Parallelisme automatique
Quand Claude Code parallelise
Claude Code lance des agents en parallele quand les taches sont independantes :
- Rechercher dans plusieurs repertoires simultanement
- Lire plusieurs fichiers en meme temps
- Executer des commandes independantes (lint + tests)
Il reste sequentiel quand les taches ont des dependances : le resultat de l'etape 1 influence l'etape 2.
Optimiser le parallelisme
Pour aider Claude Code a paralleliser, formulez vos demandes avec des taches clairement independantes : "Recherche les usages de X dans le frontend ET les tests en parallele" plutot que "Trouve X puis regarde les tests".
Hooks et Permissions dans Claude Code
Objectifs
- Configurer les modes de permission
- Creer des hooks pour automatiser des actions
- Securiser l'utilisation de Claude Code
Les permissions et les hooks sont les gardes-fous qui rendent Claude Code utilisable en equipe et en production. Sans eux, un agent pourrait faire n'importe quoi. Avec eux, vous gardez le controle tout en beneficiant de l'autonomie de l'agent.
Modes de permission
Mode par defaut
- Demande confirmation pour les actions sensibles
- Lecture de fichiers : autorisee
- Ecriture de fichiers : demande
- Commandes bash : demande
- Ideal pour l'apprentissage
Mode autonome (--dangerously-skip-permissions)
- Aucune confirmation demandee
- Toutes les actions autorisees
- Uniquement en environnement sandbox
- Utilise en CI/CD avec precaution
Configuration fine des permissions
{
"permissions": {
"allow": [
"Read",
"Glob",
"Grep",
"Bash(npm test)",
"Bash(npm run lint)",
"Bash(git status)",
"Bash(git diff)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force)",
"Bash(docker rm)"
]
}
}Hooks : automatiser des actions
Les hooks sont des commandes shell executees automatiquement en reponse a des evenements Claude Code. Ils permettent d'ajouter des validations, des notifications, ou des transformations.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"command": "echo 'Modification de fichier detectee'"
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "npm run lint --fix $(cat $CLAUDE_TOOL_INPUT | jq -r '.file_path')"
}
],
"Notification": [
{
"matcher": "",
"command": "notify-send 'Claude Code' '$CLAUDE_NOTIFICATION'"
}
]
}
}Types de hooks disponibles
| Hook | Declencheur | Cas d'usage |
|---|---|---|
| PreToolUse | Avant l'execution d'un outil | Validation, logging, blocage conditionnel |
| PostToolUse | Apres l'execution d'un outil | Lint auto, tests, notifications |
| Notification | Quand Claude envoie une notification | Alertes systeme, emails |
| Stop | Quand Claude termine une tache | Rapport final, nettoyage |
Securite des hooks
Les hooks s'executent avec vos permissions systeme, pas celles de Claude. Un hook malveillant dans un CLAUDE.md telecharge pourrait compromettre votre systeme. Ne faites confiance qu'aux hooks que vous avez ecrits ou audites.
Extended Thinking : La Reflexion Profonde
Objectifs
- Comprendre le fonctionnement de l'Extended Thinking
- Configurer le budget de tokens de reflexion
- Savoir quand activer ou non le thinking
L'Extended Thinking est comme donner a Claude un brouillon avant de repondre. Au lieu de repondre immediatement, Claude reflechit d'abord en interne, structure sa pensee, explore des pistes, puis formule sa reponse. Pour les problemes complexes, cette reflexion ameliore considerablement la qualite des reponses.
Comment fonctionne l'Extended Thinking
Sans Thinking Avec Extended Thinking
ββββββββββββ ββββββββββββ
β Question β β Question β
ββββββ¬ββββββ ββββββ¬ββββββ
β β
β ββββββΌββββββββββββββ
β β THINKING BLOCK β
β β (reflexion interneβ
β β non visible) β
β β - Analyse β
β β - Exploration β
β β - Verification β
β ββββββ¬βββββββββββββββ
β β
ββββββΌββββββ ββββββΌββββββ
β Reponse β β Reponse β
β directe β β reflechieβ
ββββββββββββ ββββββββββββ
Activation via l'API
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=16000,
thinking={
"type": "enabled",
"budget_tokens": 10000 # Budget pour la reflexion
},
messages=[{
"role": "user",
"content": "Analyse cette architecture microservices et identifie "
"les points de defaillance potentiels..."
}]
)
# La reponse contient 2 types de blocs
for block in response.content:
if block.type == "thinking":
print("REFLEXION:", block.thinking) # Processus interne
elif block.type == "text":
print("REPONSE:", block.text) # Reponse finaleBudget tokens : combien allouer ?
| Budget | Usage | Exemple |
|---|---|---|
| 1K-5K | Reflexion legere | Questions factuelles avec verification |
| 5K-10K | Reflexion moderee | Analyse de code, debugging |
| 10K-30K | Reflexion profonde | Architecture systeme, algorithmes complexes |
| 30K+ | Reflexion extensive | Mathematiques avancees, analyse exhaustive |
Modeles compatibles
L'Extended Thinking est disponible sur :
- Claude Sonnet 4.5 (
claude-sonnet-4-5-20250929) : Le plus polyvalent pour le thinking - Claude Opus 4.6 (
claude-opus-4-6) : Reflexion la plus profonde et la plus precise
Haiku ne supporte pas l'Extended Thinking.
Quand utiliser l'Extended Thinking ?
A activer
- Problemes mathematiques
- Analyse de code complexe
- Architecture systeme
- Decisions avec trade-offs
- Debugging delicat
A eviter
- Questions simples / factuelles
- Generation de texte standard
- Reformulation / traduction
- Quand la latence compte
- Budget tokens serre
Attention aux couts
Les tokens de thinking sont factures comme des tokens de sortie. Avec un budget de 10K tokens de thinking, le cout est significatif. Utilisez le thinking de maniere ciblee, pas systematiquement.
Adaptive Thinking Controls
Objectifs
- Comprendre les 4 niveaux d'Adaptive Thinking
- Choisir le bon niveau selon le cas d'usage
- Implementer des strategies de thinking dynamiques
L'Adaptive Thinking est l'evolution naturelle de l'Extended Thinking. Au lieu de simplement activer/desactiver la reflexion, vous pouvez maintenant doser finement l'effort de reflexion. C'est comme passer de l'interrupteur ON/OFF au variateur de lumiere.
Les 4 niveaux
| Niveau | Budget | Latence | Usage |
|---|---|---|---|
| low | ~1K-3K tokens | Rapide | Verification rapide, taches simples avec filet de securite |
| medium | ~3K-10K tokens | Moderee | Analyse standard, code review, debugging courant |
| high | ~10K-30K tokens | Lente | Architecture, algorithmes, analyse approfondie |
| max | Tout le budget | Tres lente | Problemes mathematiques, recherche exhaustive |
Implementation API
import anthropic
client = anthropic.Anthropic()
# Niveau bas : verification rapide
response_quick = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=8000,
thinking={
"type": "enabled",
"budget_tokens": 2000 # ~low
},
messages=[{"role": "user", "content": "Ce code a-t-il un bug ?"}]
)
# Niveau haut : analyse approfondie
response_deep = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=16000,
thinking={
"type": "enabled",
"budget_tokens": 25000 # ~high
},
messages=[{"role": "user", "content": "Concois une architecture de cache distribue..."}]
)Strategie de thinking dynamique
def get_thinking_budget(task_type: str, complexity: str) -> int:
"""Determine le budget de thinking optimal."""
budgets = {
("chat", "simple"): 0, # Pas de thinking
("chat", "complex"): 3000, # Low
("code", "simple"): 2000, # Low
("code", "complex"): 10000, # Medium-High
("architecture", "simple"): 5000, # Medium
("architecture", "complex"): 25000, # High
("math", "simple"): 5000, # Medium
("math", "complex"): 50000, # Max
}
return budgets.get((task_type, complexity), 5000)
# Usage
budget = get_thinking_budget("architecture", "complex")
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=16000,
thinking={"type": "enabled", "budget_tokens": budget},
messages=[{"role": "user", "content": prompt}]
)Regle pratique
Commencez par le niveau medium pour vos taches habituelles. Augmentez si les reponses manquent de profondeur. Diminuez si les reponses sont bonnes mais trop lentes. Le thinking n'est pas "plus = mieux" : parfois un budget plus petit force une reflexion plus focalisee.
Dans Claude Code
Claude Code gere automatiquement le thinking en fonction de la complexite des taches. Vous pouvez influencer le niveau via le mode utilise :
# Mode rapide (thinking reduit) # Commande /fast dans la session Claude Code # Mode par defaut (thinking adaptatif) claude # Choix du modele pour plus de reflexion # /model opus dans la session pour utiliser Opus 4.6
Think Tool et Agents Reflexifs
Objectifs
- Comprendre la difference entre Extended Thinking et Think Tool
- Implementer le Think Tool dans les boucles agentiques
- Creer des agents reflexifs qui planifient avant d'agir
Le Think Tool est un outil "factice" qui donne a Claude un espace de reflexion explicite pendant les boucles d'outils. Quand Claude enchaine 5-6 appels d'outils, il peut perdre le fil. Le Think Tool lui permet de s'arreter, reflechir sur ce qu'il a appris, et planifier ses prochaines actions. C'est la metacognition appliquee aux agents IA.
Extended Thinking vs Think Tool
| Aspect | Extended Thinking | Think Tool |
|---|---|---|
| Quand | Avant la premiere reponse | A tout moment dans la boucle |
| Visibilite | Bloc thinking separe | Resultat d'un appel tool |
| Controle | Budget tokens fixe | Claude decide quand reflechir |
| Cout | Tokens de sortie | Tokens d'entree (recycles) |
| Cas ideal | Reflexion initiale profonde | Reflexion en cours de route |
Implementer le Think Tool
import anthropic
client = anthropic.Anthropic()
# Definir le Think Tool
think_tool = {
"name": "think",
"description": (
"Utilisez cet outil pour reflechir sur un probleme. "
"Appelez-le quand vous devez analyser des informations "
"recueillies, planifier vos prochaines actions, ou "
"verifier votre raisonnement. Le contenu n'est pas "
"visible par l'utilisateur."
),
"input_schema": {
"type": "object",
"properties": {
"thought": {
"type": "string",
"description": "Votre reflexion interne"
}
},
"required": ["thought"]
}
}
# Boucle agentique avec Think Tool
def agent_loop(user_query, other_tools):
tools = [think_tool] + other_tools
messages = [{"role": "user", "content": user_query}]
while True:
response = client.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=4096,
tools=tools,
messages=messages
)
if response.stop_reason == "end_turn":
# Claude a termine, extraire la reponse finale
return [b.text for b in response.content if b.type == "text"]
# Traiter les appels d'outils
tool_results = []
for block in response.content:
if block.type == "tool_use":
if block.name == "think":
# Think Tool : pas d'execution, juste retourner OK
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": "Reflexion enregistree."
})
else:
# Executer les vrais outils
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": result
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})Quand Claude utilise le Think Tool
Agent recoit : "Trouve et corrige le bug dans le module de paiement"
1. tool_use: search_files("paiement")
β Resultat : 5 fichiers trouves
2. tool_use: think({
thought: "J'ai trouve 5 fichiers lies au paiement :
payment.py, payment_api.py, payment_test.py,
payment_models.py, payment_utils.py.
Les bugs sont souvent dans la logique metier
(payment.py) ou les appels API (payment_api.py).
Je vais commencer par lire ces deux fichiers."
})
3. tool_use: read_file("payment.py")
4. tool_use: read_file("payment_api.py")
β Resultats recus
5. tool_use: think({
thought: "J'ai identifie le probleme dans payment.py
ligne 42 : la conversion de devise utilise une
division au lieu d'une multiplication. Cela
explique les montants incorrects signales.
Je vais corriger et verifier avec un test."
})
6. tool_use: edit_file("payment.py", ...)
7. tool_use: run_tests("payment_test.py")
Think Tool + Extended Thinking
Les deux peuvent etre utilises ensemble. L'Extended Thinking fournit la reflexion initiale profonde, et le Think Tool permet des reflexions intermediaires pendant la boucle agentique. C'est la combinaison recommandee pour les agents complexes.
Lab : Projet Claude Code + MCP
Objectifs
- Creer un projet complet utilisant Claude Code
- Integrer un serveur MCP personnalise
- Combiner Extended Thinking et Tool Use
Projet : Assistant DevOps avec Claude Code + MCP
Vous allez configurer un environnement Claude Code complet avec un serveur MCP personnalise, un CLAUDE.md detaille, des hooks, et des permissions adaptees pour un workflow DevOps.
Etape 1 : Creer le projet et le CLAUDE.md
mkdir devops-assistant && cd devops-assistant mkdir -p .claude src tests
# DevOps Assistant ## Objectif Cet assistant aide l'equipe DevOps a gerer les deployments, monitorer les services, et diagnostiquer les incidents. ## Stack - Infrastructure : Docker + Kubernetes - Monitoring : Prometheus + Grafana - CI/CD : GitHub Actions - Base de donnees : PostgreSQL ## Regles - Toujours verifier l'etat des services avant un deployment - Logger toutes les actions dans le fichier operations.log - Ne jamais supprimer de ressources sans confirmation - Utiliser les tags semantiques pour les images Docker ## Commandes autorisees - docker ps, docker logs, docker stats - kubectl get, kubectl describe, kubectl logs - psql pour les requetes SELECT uniquement
Etape 2 : Creer le serveur MCP DevOps
from mcp.server.fastmcp import FastMCP
import json
from datetime import datetime
from pathlib import Path
mcp = FastMCP("devops-assistant")
LOG_FILE = Path(__file__).parent.parent / "operations.log"
def log_operation(action: str, details: str):
"""Log une operation dans le fichier."""
with open(LOG_FILE, "a") as f:
f.write(f"[{datetime.now().isoformat()}] {action}: {details}\n")
@mcp.tool()
def check_service_health(service_name: str) -> str:
"""Verifie l'etat de sante d'un service."""
# Simulation - en production, appeler l'API monitoring
services = {
"api-gateway": {"status": "healthy", "uptime": "99.9%", "latency_ms": 45},
"auth-service": {"status": "healthy", "uptime": "99.8%", "latency_ms": 12},
"payment-service": {"status": "degraded", "uptime": "98.2%", "latency_ms": 230},
"notification-service": {"status": "healthy", "uptime": "99.7%", "latency_ms": 8},
}
result = services.get(service_name, {"status": "unknown", "error": "Service non trouve"})
log_operation("HEALTH_CHECK", f"{service_name}: {result['status']}")
return json.dumps(result, indent=2)
@mcp.tool()
def get_recent_errors(service_name: str, limit: int = 10) -> str:
"""Recupere les erreurs recentes d'un service."""
# Simulation
errors = [
{"timestamp": "2026-02-10T10:23:00", "level": "ERROR",
"message": f"Connection timeout to database from {service_name}"},
{"timestamp": "2026-02-10T10:21:00", "level": "WARN",
"message": f"High memory usage detected in {service_name}"},
]
log_operation("ERROR_QUERY", f"{service_name}: {limit} errors requested")
return json.dumps(errors[:limit], indent=2, ensure_ascii=False)
@mcp.tool()
def deployment_checklist(service_name: str, version: str) -> str:
"""Genere une checklist de deployment pour un service."""
checklist = {
"service": service_name,
"version": version,
"checks": [
{"step": "Tests unitaires", "status": "required"},
{"step": "Tests integration", "status": "required"},
{"step": "Health check pre-deploy", "status": "required"},
{"step": "Backup database", "status": "recommended"},
{"step": "Notify team on Slack", "status": "required"},
{"step": "Canary deployment (10%)", "status": "required"},
{"step": "Monitor 15 min", "status": "required"},
{"step": "Full rollout", "status": "final"},
]
}
log_operation("DEPLOY_CHECKLIST", f"{service_name} v{version}")
return json.dumps(checklist, indent=2, ensure_ascii=False)
@mcp.resource("infra://services")
def list_services() -> str:
"""Liste tous les services de l'infrastructure."""
return json.dumps([
"api-gateway", "auth-service", "payment-service",
"notification-service", "user-service", "search-service"
])
if __name__ == "__main__":
mcp.run(transport="stdio")Etape 3 : Configurer les permissions et hooks
{
"permissions": {
"allow": ["Read", "Glob", "Grep", "Bash(docker ps)", "Bash(docker logs *)"],
"deny": ["Bash(docker rm *)", "Bash(rm -rf *)"]
},
"hooks": {
"PostToolUse": [{
"matcher": "Edit|Write",
"command": "echo '[HOOK] Fichier modifie' >> operations.log"
}]
},
"mcpServers": {
"devops": {
"command": "python",
"args": ["src/mcp_devops.py"]
}
}
}Etape 4 : Tester le workflow complet
$ cd devops-assistant && claude > Verifie l'etat de tous les services # Claude utilise check_service_health pour chaque service > Le payment-service est degrade. Diagnostique le probleme. # Claude utilise get_recent_errors + think pour analyser > Prepare le deployment du payment-service v2.1.0 # Claude utilise deployment_checklist + genere un plan
Etape 5 : Extensions
- Ajoutez un tool
rollback_service(service, version)avec confirmation - Ajoutez une resource
infra://metrics/{service}pour les metriques temps reel - Combinez avec Extended Thinking pour l'analyse de root cause
- Ajoutez un hook PostToolUse qui envoie une notification Slack
Examen Final : Phase 2 - Outils Avances & MCP
Objectifs
- Valider toutes les competences de la Phase 2
- Demontrer votre maitrise du Tool Use, MCP et Claude Code
- Obtenir votre certification Phase 2
Examen Phase 2 - 10 Questions
1. Quel est le role du champ "input_schema" dans une definition d'outil ?
2. Dans le flux Tool Use, qui execute reellement la fonction ?
3. Que signifie "stop_reason": "tool_use" dans la reponse API ?
4. Quel protocole sous-jacent utilise MCP ?
5. Quelle primitive MCP est controlee par le modele (le LLM decide) ?
6. Comment le SDK Python MCP genere-t-il le JSON Schema d'un tool ?
7. Quel fichier permet de partager la config MCP d'un projet via git ?
8. Quelle est la difference principale entre Extended Thinking et Think Tool ?
9. Quel hook se declenche avant l'execution d'un outil dans Claude Code ?
10. Pour un probleme d'architecture complexe, quel budget de thinking est recommande ?
Felicitations ! Si vous avez obtenu 8/10 ou plus, vous maitrisez les outils avances de Claude. La Phase 3 vous attend avec les architectures RAG, les agents autonomes et les design patterns avances. Vous avez maintenant les fondations pour construire des systemes IA de production.