Introduction au Tool Use (Function Calling)

60 minIntermediaire

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.

Workflow Tool Use en 5 etapes
  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

CategorieExemples d'outils
DonneesQuery database, search documents, fetch API
ActionsSend email, create ticket, update record
CalculCalculator, code execution, data analysis
ExterneWeather API, stock prices, web search
SystemeFile operations, process control, monitoring

Quiz

1. Quel est le stop_reason quand Claude veut utiliser un outil ?

end_turn
tool_use
stop_sequence

2. Qui execute reellement la fonction/outil ?

Claude directement
Votre code (vous renvoyez le resultat a Claude)
L'API Anthropic

Definir des Outils avec JSON Schema

60 minIntermediaire

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

Python
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

TypeExempleDescription
string"Paris"Texte libre ou enum
number42.5Nombre decimal
integer42Nombre entier
booleantrue/falseBooleen
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 ?

mandatory: true
required: ["param_name"] dans input_schema
optional: false

Gestion du Flux Tool Use

60 minIntermediaire

Objectifs

  • Implementer la boucle tool_use β†’ tool_result complete
  • Gerer les erreurs d'execution d'outils

Implementation complete en Python

Python - Boucle Tool Use Complete
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).

Python - Tool Result avec erreur
# 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 ?

Ne rien renvoyer
Renvoyer un tool_result avec is_error: true
Relancer l'appel API depuis le debut

Tool Use Avance : Multi-Tools et Parallel

60 minAvance

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.

Python
# 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_choiceComportement
{"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_choice: {"type": "tool", "name": "mon_outil"}
force_tool: "mon_outil"
required_tools: ["mon_outil"]

Tool Search et Programmatic Tool Calling

60 minAvance

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.

Pattern 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
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Python - Tool Routing
# 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)

60 minAvance

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.

Python - Computer Use Setup
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: scroller

Securite 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

60 minPratique

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

30 minEvaluation

Examen Module 2.1 - Tool Use

1. Qui execute la fonction quand Claude fait un tool_use ?

Votre code cote serveur
Claude directement
L'API Anthropic

2. Comment limiter Claude a un outil specifique ?

tool_choice: {"type": "tool", "name": "X"}
only_tool: "X"
tools: [X] avec un seul outil

3. Que faire quand Claude renvoie 3 tool_use blocks en parallele ?

Executer seulement le premier
Executer les 3 et renvoyer 3 tool_results
Renvoyer une erreur

4. Quel champ indique une erreur dans un tool_result ?

error: true
is_error: true
status: "error"

5. Pourquoi utiliser le tool routing ?

Reduire les tokens et ameliorer la precision avec un grand catalogue d'outils
C'est obligatoire pour le Tool Use
Pour securiser les outils

Introduction au Model Context Protocol (MCP)

60 minIntermediaire

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 vs Avec MCP
  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

PrimitiveDescriptionControle parAnalogie
ToolsFonctions executables par le LLMLe modele decidePOST /api/action
ResourcesDonnees exposees au LLML'application decideGET /api/data
PromptsTemplates de prompts reutilisablesL'utilisateur decideGET /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

75 minAvance

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

Architecture MCP complete
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚                    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

Sequence
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).

JSON
{
  "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

90 minAvance

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

Bash
# 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

Python
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

Python
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

JSON - claude_desktop_config.json
{
  "mcpServers": {
    "mon-serveur": {
      "command": "python",
      "args": ["chemin/vers/serveur.py"],
      "env": {
        "API_KEY": "votre-cle"
      }
    }
  }
}

Tester avec MCP Inspector

Bash
# 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

90 minAvance

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

Bash
# 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

TypeScript
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

AspectPython SDKTypeScript SDK
ValidationType hints PythonSchemas Zod
Decorateurs/API@mcp.tool()server.tool()
Asyncasyncio natifPromise/async-await
Resources@mcp.resource(uri)server.resource(name, uri)
Executionpython serveur.pynode dist/index.js
JSON - Configuration Claude Code
// 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

60 minIntermediaire

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

ServeurFonctionsTransportCas d'usage
FilesystemLire/ecrire/rechercher des fichiersstdioGestion de projets, analyse code
GitHubRepos, issues, PRs, searchstdioDev workflow, code review
PostgreSQLRequetes SQL, schemastdioAnalyse donnees, reporting
SlackMessages, channels, usersstdioCommunication, notifications
Google DriveFichiers, recherche, metadatastdioGestion documentaire
PuppeteerNavigation web, screenshotsstdioWeb scraping, tests
GitCommits, branches, diff, logstdioAnalyse de repos
MemoryKnowledge graph persistantstdioMemoire long-terme agents

Installation d'un serveur existant

Bash
# 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

JSON - claude_desktop_config.json
{
  "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

75 minIntermediaire

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

Bash
# 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

ScopeFichierUsage
Projet.mcp.jsonPartage avec l'equipe via git
Utilisateur~/.claude/settings.jsonConfiguration personnelle globale
Sessionclaude mcp add --scope sessionTemporaire, disparait apres la session
JSON - .mcp.json (racine du projet)
{
  "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

Exemple de session Claude Code
$ 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

Bash
# 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

120 minAvance

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

Bash
mkdir mcp-project-manager && cd mcp-project-manager
pip install mcp
touch server.py tasks.json

Etape 2 : Implementer le serveur

Python
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

Bash
# 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://changelog qui 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

30 minIntermediaire

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 ?

Tools, Resources, Prompts
Tools, Functions, Actions
Endpoints, Resources, Schemas

2. Quel transport est recommande pour un serveur MCP local ?

stdio
HTTP/SSE
WebSocket

3. En Python, quel decorateur expose une fonction comme tool MCP ?

@mcp.function()
@mcp.tool()
@mcp.expose()

4. Quelle commande ajoute un serveur MCP a Claude Code ?

claude install mcp-server
claude mcp add nom -- commande args
claude config mcp.servers.add

5. Quel fichier partage la config MCP d'un projet avec l'equipe ?

claude.config.json
CLAUDE.md
.mcp.json

Claude Code CLI : Les Bases

75 minIntermediaire

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

Bash
# 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.

Markdown - CLAUDE.md
# 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

Resolution des instructions 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

CommandeDescription
/helpAide et documentation
/clearReinitialiser la conversation
/compactCompresser l'historique pour liberer du contexte
/costAfficher le cout de la session
/modelChanger de modele (opus, sonnet, haiku)
/permissionsGerer les permissions des outils
/mcpGerer 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

75 minAvance

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

TypeSpecialiteOutils disponibles
BashExecution de commandesBash uniquement
ExploreExploration de codebaseRead, Grep, Glob (pas d'ecriture)
PlanPlanification d'implementationRead, Grep, Glob (pas d'ecriture)
general-purposeTaches complexes multi-etapesTous les outils

Comment Claude Code utilise les subagents

Workflow interne Claude Code
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.

Exemple de session
$ 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

60 minIntermediaire

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

JSON - .claude/settings.json
{
  "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.

JSON - .claude/settings.json (hooks)
{
  "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

HookDeclencheurCas d'usage
PreToolUseAvant l'execution d'un outilValidation, logging, blocage conditionnel
PostToolUseApres l'execution d'un outilLint auto, tests, notifications
NotificationQuand Claude envoie une notificationAlertes systeme, emails
StopQuand Claude termine une tacheRapport 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

75 minAvance

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

Processus 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

Python
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 finale

Budget tokens : combien allouer ?

BudgetUsageExemple
1K-5KReflexion legereQuestions factuelles avec verification
5K-10KReflexion modereeAnalyse de code, debugging
10K-30KReflexion profondeArchitecture systeme, algorithmes complexes
30K+Reflexion extensiveMathematiques 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

60 minAvance

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

NiveauBudgetLatenceUsage
low~1K-3K tokensRapideVerification rapide, taches simples avec filet de securite
medium~3K-10K tokensModereeAnalyse standard, code review, debugging courant
high~10K-30K tokensLenteArchitecture, algorithmes, analyse approfondie
maxTout le budgetTres lenteProblemes mathematiques, recherche exhaustive

Implementation API

Python
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

Python
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 :

Bash
# 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

75 minAvance

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

AspectExtended ThinkingThink Tool
QuandAvant la premiere reponseA tout moment dans la boucle
VisibiliteBloc thinking separeResultat d'un appel tool
ControleBudget tokens fixeClaude decide quand reflechir
CoutTokens de sortieTokens d'entree (recycles)
Cas idealReflexion initiale profondeReflexion en cours de route

Implementer le Think Tool

Python
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

Exemple de reflexion agent
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

120 minAvance

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

Bash
mkdir devops-assistant && cd devops-assistant
mkdir -p .claude src tests
Markdown - CLAUDE.md
# 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

Python - src/mcp_devops.py
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

JSON - .claude/settings.json
{
  "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

Session Claude Code
$ 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

45 minAvance

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 ?

Definir le format de la reponse de l'outil
Definir les parametres attendus par l'outil en JSON Schema
Definir le type de retour de l'outil

2. Dans le flux Tool Use, qui execute reellement la fonction ?

Claude (le modele)
Votre application (le client)
Le serveur Anthropic

3. Que signifie "stop_reason": "tool_use" dans la reponse API ?

Claude veut appeler un outil et attend le resultat
L'outil a ete execute avec succes
L'outil n'est pas disponible

4. Quel protocole sous-jacent utilise MCP ?

GraphQL
REST API
JSON-RPC 2.0

5. Quelle primitive MCP est controlee par le modele (le LLM decide) ?

Tools
Resources
Prompts

6. Comment le SDK Python MCP genere-t-il le JSON Schema d'un tool ?

A partir d'un fichier schema.json
A partir des type hints Python de la fonction
Manuellement dans le decorateur

7. Quel fichier permet de partager la config MCP d'un projet via git ?

CLAUDE.md
.mcp.json
claude_desktop_config.json

8. Quelle est la difference principale entre Extended Thinking et Think Tool ?

Extended Thinking est gratuit, Think Tool est payant
Extended Thinking agit avant la reponse, Think Tool pendant la boucle d'outils
Extended Thinking est pour Opus, Think Tool pour Sonnet

9. Quel hook se declenche avant l'execution d'un outil dans Claude Code ?

BeforeToolUse
PreToolUse
OnToolStart

10. Pour un probleme d'architecture complexe, quel budget de thinking est recommande ?

1K-3K tokens (low)
3K-5K tokens (medium)
10K-30K tokens (high)

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.