RunContext : Gérer le Client MCP et l'Agent
Mis à jour le 29 juillet 2026
Le chef d’orchestre de votre agent
Le RunContext est le composant qui fait tenir l’ensemble : c’est lui qui relie votre agent IA aux serveurs MCP et qui gère leur cycle de vie complet — connexion aux serveurs, enregistrement des tools, exécution des conversations, récupération des résultats, puis fermeture propre. Dans le SDK Mistral, il prend la forme d’un context manager asynchrone qui encapsule toute cette logique. Vous ouvrez un bloc, vous déclarez ce que l’agent a le droit d’utiliser, vous discutez, et tout se ferme à la sortie.
Créer l’agent
Le RunContext ne crée pas l’agent, il s’y rattache. La première étape consiste donc à instancier un agent via l’API.
from mistralai import Mistral
# Initialiser le client Mistral
client = Mistral(api_key="VOTRE_CLE_API")
# Créer un agent
agent = client.beta.agents.create(
model="mistral-medium-latest",
name="assistant-mcp",
instructions="Vous êtes un assistant capable d'utiliser des outils MCP.",
)
print(f"Agent créé : {agent.id}")
Cet agent est une entité persistante côté Mistral : il possède un modèle, un nom et des instructions système, et il survit à votre script. Les tools MCP, eux, ne sont pas attachés à l’agent ; ils lui sont fournis dynamiquement par le RunContext, à chaque exécution. C’est ce découplage qui permet de faire tourner le même agent avec des outils différents selon le contexte.
Ouvrir le contexte
Le RunContext s’utilise avec async with, ce qui garantit la libération des ressources même en cas d’exception.
from mistralai.extra.run.context import RunContext
from pydantic import BaseModel
# Optionnel : définir un format de sortie structuré
class WeatherResult(BaseModel):
location: str
temperature: float
description: str
async with RunContext(
agent_id=agent.id,
output_format=WeatherResult, # Format structuré (optionnel)
continue_on_fn_error=True, # Continuer si un tool échoue
) as run_ctx:
# Ici, on enregistre les clients MCP et on lance les conversations
pass
Trois paramètres pilotent ce comportement. agent_id désigne l’agent créé précédemment. output_format accepte un modèle Pydantic et contraint la réponse finale à cette structure — précieux quand la sortie alimente un autre programme plutôt qu’un humain. continue_on_fn_error, enfin, décide du sort de la conversation lorsqu’un tool lève une erreur : à True, le contexte poursuit, et le modèle reçoit le message d’erreur comme il recevrait un résultat.
Enregistrer un client MCP
Le contexte ouvert, vous y déclarez vos clients MCP.
from mcp import StdioServerParameters
from mistralai.extra.mcp.stdio import MCPClientSTDIO
# Configurer le serveur local
server_params = StdioServerParameters(
command="python",
args=["serveur_meteo.py"],
)
mcp_client = MCPClientSTDIO(stdio_params=server_params)
async with RunContext(
agent_id=agent.id,
continue_on_fn_error=True,
) as run_ctx:
# Enregistrer le client MCP
await run_ctx.register_mcp_client(mcp_client=mcp_client)
Cet unique appel à register_mcp_client déclenche une séquence complète : lancement du processus serveur en mode STDIO, négociation des capabilities, récupération de la liste des tools, puis mise à disposition de ces tools au modèle pour les conversations à venir. Rien de tout cela n’est à écrire à la main.
Rien ne vous limite non plus à un seul serveur. Un même RunContext peut agréger plusieurs sources, et le modèle verra l’union de leurs tools comme un catalogue unique :
async with RunContext(agent_id=agent.id) as run_ctx:
await run_ctx.register_mcp_client(mcp_client=mcp_client_meteo)
await run_ctx.register_mcp_client(mcp_client=mcp_client_github)
await run_ctx.register_mcp_client(mcp_client=mcp_client_calendar)
Ajouter des fonctions locales
Toutes vos capacités n’ont pas vocation à devenir des serveurs MCP. Pour une fonction de quelques lignes propre à ce script, le décorateur register_func suffit à l’exposer au modèle comme un tool ordinaire.
import random
async with RunContext(agent_id=agent.id) as run_ctx:
await run_ctx.register_mcp_client(mcp_client=mcp_client)
@run_ctx.register_func
def get_user_location(username: str) -> str:
"""Récupère la localisation d'un utilisateur.
Args:
username: Le nom d'utilisateur
Returns:
La ville de l'utilisateur
"""
locations = {"alice": "Paris", "bob": "Lyon", "charlie": "Marseille"}
return locations.get(username, "Inconnue")
Du point de vue du modèle, la différence est nulle : il voit un tool de plus. La différence est pour vous — ces fonctions s’exécutent dans votre processus Python, sans serveur externe, donc sans réutilisabilité hors de ce script.
Lancer la conversation
Une fois le contexte peuplé, il ne reste qu’à parler.
async with RunContext(agent_id=agent.id) as run_ctx:
await run_ctx.register_mcp_client(mcp_client=mcp_client)
# Exécution synchrone (attend la réponse complète)
run_result = await client.beta.conversations.run_async(
run_ctx=run_ctx,
inputs="Quelle est la météo à Paris ?",
)
print(run_result.output)
Derrière cet appel, le modèle analyse la question, consulte les tools disponibles — ceux des serveurs MCP comme les fonctions locales —, appelle ceux qui lui semblent nécessaires, puis rédige sa réponse à partir des résultats obtenus.
L’ensemble du cycle se lit ainsi :
1. Créer l'agent (client.beta.agents.create)
↓
2. Ouvrir le RunContext (async with RunContext)
↓
3. Enregistrer les clients MCP (register_mcp_client)
↓
4. Enregistrer les fonctions locales (register_func)
↓
5. Lancer les conversations (conversations.run_async)
↓
6. Fermeture automatique (fin du context manager)
À la sortie du bloc, tous les processus serveur STDIO lancés par le contexte sont arrêtés proprement — pas de processus Python orphelin qui traîne après une exception.
Un mot pour finir sur continue_on_fn_error=True, dont la valeur se mesure surtout en production. Sans lui, la moindre erreur dans un tool interrompt la conversation entière et l’utilisateur reste devant une exception. Avec lui, le modèle reçoit l’erreur en clair et dispose d’une marge de manœuvre : reformuler sa requête avec d’autres arguments, se rabattre sur un autre tool, ou simplement expliquer à l’utilisateur ce qui a échoué. Un agent qui dit « le service météo ne répond pas » vaut infiniment mieux qu’un agent qui plante.
Points clés à retenir
- Le RunContext orchestre la communication agent ↔ serveurs MCP
- Il s’utilise comme context manager
async with register_mcp_clientconnecte un serveur MCP et découvre ses toolsregister_funcenregistre des fonctions Python locales comme toolscontinue_on_fn_error=Trueassure la résilience de votre agent- Tout le workflow est asynchrone (async/await)