Comment implémenter le Model Context Protocol (MCP) en Python

Publié le 08/04/2026 par Cédric Martin

Comment implémenter le Model Context Protocol (MCP) en Python

Qu’est-ce que le Model Context Protocol (MCP) et pourquoi c’est utile en Python

Le Model Context Protocol (MCP) est un protocole standardisé qui permet à une application d’exposer des outils, des ressources et des prompts à un modèle (via un client compatible), de manière structurée et contrôlée. L’objectif est de sortir d’une intégration “ad hoc” où chaque LLM consomme des API propriétaires, pour passer à une couche d’outillage uniforme.

Concrètement, MCP sert à centraliser l’accès à des capacités (lecture de fichiers, requêtes SQL, accès à un CRM, recherche interne) tout en réduisant les risques via des permissions et validations strictes. En Python, c’est particulièrement puissant grâce à la richesse de l’écosystème data et API.

Checklist de prérequis avant d’implémenter MCP en Python

Avant d’écrire du code, clarifiez le rôle de votre composant : serveur MCP (exposer des outils) ou client MCP (consommer des outils). Côté technique, prévoyez :

Guide étape par étape : comment implémenter MCP en Python

Étape 1 : cadrer le contexte et les permissions

Un outil MCP n’est pas une simple fonction utilitaire : c’est une capacité potentiellement dangereuse. Définissez les scopes (lecture seule vs écriture) et les allowlists (chemins autorisés, domaines d'API).

Étape 2 : définir les “tools” et leurs schémas d’entrée

Un bon outil MCP a un nom stable et un schéma d’arguments explicite. Utilisez des paramètres typés et des descriptions opérationnelles pour aider le modèle à comprendre quand et comment appeler l'outil.

Étape 3 : implémenter le serveur MCP

En Python, vous allez instancier un serveur, enregistrer des tools, puis lancer une boucle d’écoute. STDIO est souvent le transport privilégié pour les intégrations desktop locales.

Étape 4 : connecter un client compatible et tester en “boîte noire”

Testez les appels avec des paramètres valides ET invalides. La majorité des problèmes MCP viennent de schémas incomplets ou de retours non sérialisables en JSON.

Étape 5 : ajouter observabilité et robustesse

Instrumentez avec des logs structurés et des métriques de latence. Préférez l’idempotence pour les actions d'écriture afin d'éviter les duplications en cas de retry.

Exemple concret en Python : un mini serveur MCP avec deux tools

Voici un serveur minimal qui expose une recherche documentaire et une lecture de fichier sécurisée.

import os import json from pathlib import Path from typing import Any, Dict, List from mcp.server import Server from mcp.types import Tool, ToolResult BASE_DIR = Path(os.environ.get("MCP_BASE_DIR", "./allowed")).resolve() DOCUMENTS = [ {"id": "doc_001", "title": "Guide Python", "body": "Python pour APIs, data et automatisation."}, {"id": "doc_002", "title": "MCP en pratique", "body": "Exposez des tools avec schémas et permissions."}, {"id": "doc_003", "title": "Sécurité", "body": "Validation stricte, allowlist, secrets et audit."}, ] def _safe_path(user_path: str) -> Path: candidate = (BASE_DIR / user_path).resolve() if not str(candidate).startswith(str(BASE_DIR)): raise ValueError("Chemin refusé.") return candidate server = Server(name="demo-mcp-python") @server.tool( name="search_docs", description="Recherche dans les documents locaux.", input_schema={ "type": "object", "properties": { "query": {"type": "string", "minLength": 1}, "limit": {"type": "integer", "default": 5} }, "required": ["query"] } ) def search_docs(query: str, limit: int = 5) -> ToolResult: q = query.lower() hits = [d for d in DOCUMENTS if q in (d["title"] + d["body"]).lower()] return ToolResult(content=json.dumps({"hits": hits[:limit]})) @server.tool( name="read_file", description="Lit un fichier texte dans BASE_DIR.", input_schema={ "type": "object", "properties": { "path": {"type": "string"}, "max_bytes": {"type": "integer", "default": 50000} }, "required": ["path"] } ) def read_file(path: str, max_bytes: int = 50000) -> ToolResult: p = _safe_path(path) if not p.exists() or not p.is_file(): raise FileNotFoundError("Fichier introuvable.") text = p.read_bytes()[:max_bytes].decode("utf-8", errors="replace") return ToolResult(content=json.dumps({"path": str(p), "content": text})) if __name__ == "__main__": server.run_stdio()

Erreurs fréquentes et pièges à éviter

Le piège le plus critique est de transformer MCP en “exécution de code arbitraire”. N'exposez jamais de shell brut. Un autre point de friction est la sérialisation : renvoyez toujours des types JSON simples (pas de datetime ou d'objets complexes).

Déboguer une implémentation MCP Python

En STDIO, le problème majeur est souvent un process qui écrit des logs sur stdout au lieu de stderr, polluant ainsi le protocole. Redirigez systématiquement vos logs techniques vers stderr.

Table de contrôle rapide : prérequis et garde-fous

Point Ce que vous devez verrouiller Symptôme si mal fait
Transport Logs sur stderr uniquement Erreurs de parsing client
Schémas Types stricts et bornes (maxLength) Appels incohérents de l'IA
Sécurité Allowlists et chemins sécurisés Fuites de données / incidents
Sérialisation Réponses JSON 100% compatibles Erreurs client mystérieuses

Prêt à booster votre visibilité ?

Besoin d'aide pour intégrer l'IA ou optimiser votre SEO ? Discutons de votre projet.

Demander un devis
← Retour aux articles

Plus de conseils en IA...

Transformer un texte en vidéo IA
IA

Transformer un texte en vidéo IA

Défis et limites du Model Context Protocol pour les IA génératives
IA

Défis et limites du Model Context Protocol pour les IA génératives

Exemples d'applications concrètes d'agents conversationnels IA
IA

Exemples d'applications concrètes d'agents conversationnels IA