Utilisation du SDK Python pour le protocole MCP

Dépôt officiel : https://github.com/modelcontextprotocol/python-sdk

Vue d'ensemble

Le protocole MCP (Model Context Protocol) permet aux applications de fournir du contexte aux modèles de langage de manière normalisée. Ce SDK Python implémente les spécifications complètes du MCP, facilitant :

  • La création de clients MCP connectables à n'importe quel serveur MCP
  • Le dévelopement de serveurs exposant des ressources, prompts et outils
  • L'utilisation de transports standards comme stdio et SSE
  • La gestion des messages et événements du protocole MCP

Installation

Pour les projets utilisant uv :

uv add "mcp[cli]"

Avec pip :

pip install mcp

Lancer l'interface de développement MCP :

uv run mcp

Démarrage rapide

Exemple de serveur MCP minimal :

# serveur_demo.py
from mcp.server.fastmcp import FastMCP

# Initialisation du serveur
app = FastMCP("ApplicationDémonstration")

# Définition d'un outil de calcul
@app.tool()
def additionner(val1: int, val2: int) -> int:
    """Additionne deux valeurs entières"""
    return val1 + val2

# Ressource dynamique de salutation
@app.resource("salutations://{identifiant}")
def obtenir_salutation(identifiant: str) -> str:
    """Retourne un message personnalisé"""
    return f"Bonjour, {identifiant}!"

Exécution en mode développement :

mcp dev serveur_demo.py

Concepts fondamentaux du MCP

Le protocole MCP offre une architecture normalisée pour l'exposition de données et fonctionnalités aux LLM, comparable à des APIs web spécialisées. Les serveurs MCP permettent :

  • Resources : Exposition de données (équivalent aux endpoints GET)
  • Tools : Exécution d'actions (équivalent aux endpoints POST)
  • Prompts : Définition de templates d'interaction réutilisables

Implémentation du serveur

Composant central gérant les connexions et le routage des messages :

from contextlib import asynccontextmanager
from collections.abc import AsyncIterator
from dataclasses import dataclass

from mcp.server.fastmcp import Context, FastMCP

# Configuration de base
serveur = FastMCP("MonService")
serveur = FastMCP("MonService", dependencies=["pandas", "numpy"])

# Gestion du cycle de vie avec contexte typé
@dataclass
class EtatApplication:
    base_donnees: object

@asynccontextmanager
async def cycle_vie(serveur: FastMCP) -> AsyncIterator[EtatApplication]:
    """Gestion des ressources avec typage fort"""
    connexion_db = await initialiser_base_donnees()
    try:
        yield EtatApplication(base_donnees=connexion_db)
    finally:
        await connexion_db.fermer()

# Intégration du cycle de vie
serveur = FastMCP("MonService", lifespan=cycle_vie)

# Utilisation dans un outil typé
@app.tool()
def interroger_donnees(ctx: Context) -> str:
    """Outil utilisant des ressources initialisées"""
    base = ctx.request_context.lifespan_context["base_donnees"]
    return base.requete()

Ressources (Resources)

Mécanisme d'exposition de données au LLM, similaire aux endpoints GET :

from mcp.server.fastmcp import FastMCP

app = FastMCP("ServiceDonnées")

# Ressource statique
@app.resource("config://application")
def parametres() -> str:
    """Configuration de l'application"""
    return "Paramètres par défaut"

# Ressource dynamique
@app.resource("utilisateurs://{id_utilisateur}/donnees")
def profil_utilisateur(id_utilisateur: str) -> str:
    """Données utilisateur dynamiques"""
    return f"Informations pour l'utilisateur {id_utilisateur}"

Outils (Tools)

Exécution d'opérations ou génération d'effets de bord :

import httpx
from mcp.server.fastmcp import FastMCP

app = FastMCP("ServiceCalculs")

# Outil synchrone
@app.tool()
def calculer_imc(masse_kg: float, taille_m: float) -> float:
    """Calcule l'indice de masse corporelle"""
    return masse_kg / (taille_m ** 2)

# Outil asynchrone
@app.tool()
async def recuperer_meteo(ville: str) -> str:
    """Récupère la météo actuelle"""
    async with httpx.AsyncClient() as client:
        reponse = await client.get(f"https://api.meteo.com/{ville}")
        return reponse.text

Templates d'interaction (Prompts)

Modèles réutilisables pour structurer les échanges avec le LLM :

from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.prompts import base

app = FastMCP("ServicePrompts")

@app.prompt()
def analyser_code(source_code: str) -> str:
    return f"Analyse demandée pour ce code :\n\n{source_code}"

@app.prompt()
def diagnostiquer_probleme(erreur: str) -> list[base.Message]:
    return [
        base.UserMessage("Message d'erreur rencontré :"),
        base.UserMessage(erreur),
        base.AssistantMessage("Je vais aider à résoudre ce problème. Quelles étapes avez-vous déjà tentées ?"),
    ]

Gestion des images

Traitement d'images via la classe intégrée :

from mcp.server.fastmcp import FastMCP, Image
from PIL import Image as PILImage

app = FastMCP("ServiceImages")

@app.tool()
def generer_apercu(chemin_image: str) -> Image:
    """Crée une miniature à partir d'une image"""
    image_source = PILImage.open(chemin_image)
    image_source.thumbnail((100, 100))
    return Image(data=image_source.tobytes(), format="png")

Objet de contexte (Context)

Fournit l'accès aux fonctionnalités MCP pour les outils :

from mcp.server.fastmcp import FastMCP, Context

app = FastMCP("ServiceTraitement")

@app.tool()
async def traiter_fichiers(chemins: list[str], ctx: Context) -> str:
    """Traite une liste de fichiers avec suivi de progression"""
    for position, chemin in enumerate(chemins):
        ctx.info(f"Traitement de {chemin}")
        await ctx.report_progress(position, len(chemins))
        contenu, type_mime = await ctx.read_resource(f"fichier://{chemin}")
    return "Traitement terminé"

Déploiement

Plusieurs méthodes d'exécution :

  • Mode développement avec inspection : mcp dev serveur.py
  • Intégration Claude Desktop : mcp install serveur.py
  • Exécution directe : python serveur.py
  • Montage ASGI : application = Starlette(routes=[Mount('/', app=serveur.sse_app())])

Éléments fondamentaux du MCP

Composant Contrôleur Description Exemple
Prompts Utilisateur Templates d'interaction Menu contextuel
Resources Applictaion Données de contexte Fichier de configuration
Tools Modèle Exécution d'opérations Appel d'API

Capacités déclarées

Les serveurs MCP déclarent leurs capacités au démarrage : prompts, resources, tools, etc.

Étiquettes: MCP Python LLM protocole serveur

Publié le 17 juin à 19h21