Tutoriel : le sampling en pratique
Sur cette page
Mise à jour du 2 novembre 2026 — sampling. La spécification MCP 2026-07-28 déprécie le Sampling. Il fonctionne encore pendant la période de dépréciation, mais la recommandation officielle pour une nouvelle implémentation est d’appeler directement l’API du fournisseur de modèle depuis le serveur. Ce que vous apprenez ici reste utile pour maintenir des serveurs existants. SDK Python v2 : le code de ce tutoriel suit la branche 1.x ; en v2, la forme recommandée est le résolveur
Sample(...)reçu parAnnotated[CreateMessageResult, Resolve(fonction)]. Source : Sampling and roots (SDK Python v2).
Ce tutoriel vous guide pas à pas dans l’implémentation du sampling, en expliquant chaque étape du code. À la fin, vous aurez un outil qui résume des articles en empruntant le modèle du client, et un client qui sait répondre à cette demande.
Étape 1 : Initier le sampling côté serveur
Sur le serveur, pendant un appel d’outil, vous lancez le sampling en appelant la méthode create_message() via le contexte. Vous lui passez les messages que vous souhaitez envoyer au modèle de langage.
# Dans votre fonction d'outil
@mcp.tool()
async def research_and_summarize(topic: str, ctx: Context):
# 1. Faire la recherche
articles = await fetch_wikipedia(topic)
# 2. Initier le sampling pour résumer
result = await ctx.session.create_message(
messages=[
SamplingMessage(
role="user",
content=TextContent(
type="text",
text=f"Résume ces articles en un rapport concis : {articles}"
)
)
],
max_tokens=2000,
system_prompt="Tu es un assistant de recherche expert.",
)
return result.content.text
Étape 2 : Callbacks de sampling
Le callback de sampling est la fonction côté client qui sera appelée quand le serveur demande une génération de texte. Elle reçoit :
context: le contexte de la requêteparams: les paramètres incluant les messages à envoyer au LLM
async def sampling_callback(
context: RequestContext,
params: CreateMessageRequestParams
):
# Votre logique pour appeler Claude
text = await appeler_claude(params.messages, params.system)
return CreateMessageResult(
role="assistant",
model="claude-opus-5",
content=TextContent(type="text", text=text),
)
Étape 3 : Formats de messages
Les messages envoyés via sampling suivent le même format que l’API Claude standard :
role:"user"ou"assistant"content: un objetTextContentavectype="text"et le texte du message
Vous pouvez aussi inclure des messages multi-tours pour fournir du contexte :
messages=[
SamplingMessage(role="user", content=TextContent(type="text", text="Question initiale")),
SamplingMessage(role="assistant", content=TextContent(type="text", text="Réponse précédente")),
SamplingMessage(role="user", content=TextContent(type="text", text="Question de suivi"))
]
Étape 4 : Retourner le texte généré
Le callback doit retourner un CreateMessageResult. Assurez-vous de toujours vérifier que le type de contenu est bien "text" :
if result.content.type == "text":
return result.content.text
else:
raise ValueError("Type de contenu inattendu dans la réponse de sampling")
Étape 5 : Connecter le callback
Passez le callback lors de la création de la session client :
async with ClientSession(
read,
write,
sampling_callback=sampling_callback # ← ici
) as session:
await session.initialize()
Étape 6 : Obtenir le résultat
Une fois tout connecté, le flux complet fonctionne automatiquement :
Utilisateur → "Recherche et résume Python"
↓
Outil research_and_summarize appelé
↓
fetch_wikipedia("Python") → données brutes
↓
ctx.session.create_message() → requête sampling au client
↓
sampling_callback → appel Claude → texte résumé
↓
Résultat retourné au serveur → retourné à l'utilisateur
À vous de jouer
- Implémentez
research_and_summarizeavec une fausse fonctionfetch_wikipediaqui renvoie trois paragraphes fixes, et lesampling_callbackcôté client avec le SDK Anthropic. Lancez l’outil depuis votre CLI. - Faites échouer le callback (clé absente) et observez ce que reçoit le serveur : d’où vient le message d’erreur, et qui doit le gérer ?
- Ajoutez un message
assistantd’amorce dans la listemessageset comparez le style du résumé.
Sources officielles : Sampling walkthrough (Claude Academy) · Sampling (spécification 2026-07-28) · Sampling and roots (SDK Python v2)
Points clés à retenir
- Le callback est défini côté client, pas côté serveur ; il reçoit
params.messageset renvoie unCreateMessageResult. - Le serveur ne connaît pas quelle implémentation ni quel modèle le client utilise ; plusieurs clients peuvent se brancher sur le même serveur avec des implémentations différentes.
- Les messages suivent le format de l’API Claude (rôles
user/assistant,TextContent) ; vérifiez toujoursresult.content.type == "text". - Idéal pour les serveurs publics existants ; sur une connexion 2026-07-28, le même besoin passe par un résolveur v2.