Aller au contenu
>_ developpeur-python
Tous les articles
MCPLLMPythonLiteLLM

MCP en Python : connecter ses outils à un LLM avec LiteLLM

Sébastien Mizrahi ,
MCP en Python : connecter ses outils à un LLM avec LiteLLM

Le Model Context Protocol, ou MCP, est un standard ouvert qui permet à un modèle de langage d'appeler vos outils et d'accéder à vos données de façon uniforme. Concrètement, vous exposez une fonction Python (interroger une base, appeler une API, lire un fichier) une seule fois, et n'importe quel LLM compatible peut s'en servir. Dans cet article, je montre comment créer un serveur MCP en Python et comment y brancher un modèle grâce à LiteLLM, sans se lier à un fournisseur d'IA particulier.

MCP, qu'est-ce que c'est ?

Avant MCP, chaque intégration entre un LLM et un outil métier était du cas par cas. On écrivait un bout de code pour décrire la fonction à OpenAI, un autre légèrement différent pour un modèle Anthropic, encore un autre pour un modèle local. À chaque nouveau modèle ou nouvel outil, tout était à refaire.

MCP règle ce problème en posant un protocole commun entre deux rôles. D'un côté, un serveur MCP publie des capacités : des outils (des actions que le modèle peut déclencher), des ressources (des données qu'il peut lire) et des prompts réutilisables. De l'autre, un client MCP, généralement l'application qui pilote le LLM, se connecte à ce serveur et découvre automatiquement ce qu'il propose. On écrit l'outil une fois, on le réutilise partout.

Le problème que MCP résout

L'intérêt devient évident dès qu'on a plusieurs outils et plusieurs modèles. Sans MCP, le nombre d'intégrations à maintenir grandit vite : cinq outils et trois modèles, cela fait potentiellement quinze branchements à écrire et à garder à jour. Avec MCP, chaque outil est décrit une seule fois par son serveur, et chaque modèle sait le consommer via le même protocole. La maintenance devient linéaire au lieu d'exploser.

C'est aussi un gain d'autonomie. Vos serveurs MCP décrivent votre métier ; ils ne dépendent pas du modèle que vous utiliserez demain. Si vous changez de fournisseur, vos outils ne bougent pas.

Exposer un outil : un serveur MCP en Python

Le SDK Python officiel fournit FastMCP, qui rend la création d'un serveur très directe. Un décorateur suffit à transformer une fonction en outil, et sa signature typée plus sa docstring servent de description au modèle.

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("business-tools")

@mcp.tool()
def client_balance(client_id: str) -> float:
    """Return a client's current balance from their identifier."""
    return read_balance_from_db(client_id)

if __name__ == "__main__":
    mcp.run()  # stdio transport by default

C'est tout ce qu'il faut pour publier un premier outil. Le nom, les paramètres attendus et la description sont exposés automatiquement au client, qui les transmettra au modèle. Vous vous concentrez sur la logique métier, pas sur la plomberie.

Côté LLM : brancher les outils avec LiteLLM

Reste à laisser un modèle utiliser cet outil. LiteLLM sait charger les outils d'un serveur MCP et les convertir au format attendu par le mécanisme de function calling, puis exécuter l'outil que le modèle demande. Le déroulé se fait en trois temps : on découvre les outils, on laisse le modèle décider, puis MCP exécute l'appel.

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from litellm import experimental_mcp_client
import litellm

server = StdioServerParameters(command="python", args=["mcp_server.py"])

async with stdio_client(server) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()

        # 1. Discover the MCP tools, in OpenAI format
        tools = await experimental_mcp_client.load_mcp_tools(session=session, format="openai")

        # 2. Let the model decide whether it needs a tool (any provider)
        messages = [{"role": "user", "content": "Quel est le solde du client 4271 ?"}]
        response = await litellm.acompletion(
            model="gpt-4o",   # or an Anthropic model, or ollama/llama3 locally
            messages=messages,
            tools=tools,
        )

        # 3. If the model asks for a tool, MCP runs it and returns the result
        tool_call = response.choices[0].message.tool_calls[0]
        result = await experimental_mcp_client.call_openai_tool(
            session=session, openai_tool=tool_call
        )

Le point important : le modèle ne connaît que la description de l'outil, jamais son implémentation. Il décide qu'il faut appeler client_balance avec l'identifiant 4271, et c'est votre code, via MCP, qui exécute réellement l'appel et rend le résultat. Le LLM oriente, il n'exécute pas.

Pourquoi passer par LiteLLM

LiteLLM est une couche d'abstraction qui expose une interface unique pour plus de cent fournisseurs de modèles. Dans l'exemple ci-dessus, remplacer gpt-4o par un modèle Anthropic ou par un modèle local servi par Ollama ne change rien au reste du code. Vos serveurs MCP restent identiques, votre logique d'appel aussi.

Cette combinaison est intéressante parce qu'elle sépare proprement trois préoccupations : le catalogue d'outils (MCP), le choix du modèle (LiteLLM) et la logique métier (vos fonctions Python). C'est exactement l'approche que j'utilise dans Alfred, ma plateforme de chatbot IA, où les serveurs MCP se branchent comme backend d'action et où le modèle est interchangeable depuis un back-office.

Les transports : stdio, SSE et HTTP

MCP ne suppose pas que le serveur et le client tournent au même endroit. Trois modes de transport couvrent les cas courants. Le transport stdio lance le serveur en processus local et communique par les entrées et sorties standard : parfait pour un outil qui vit sur la même machine. Les transports SSE et HTTP passent par le réseau, ce qui permet d'exposer un serveur MCP distant, partagé entre plusieurs applications, avec une authentification à la clé.

Le choix dépend de votre architecture. Un outil interne et léger se contente de stdio ; un service métier réutilisé par plusieurs équipes gagne à être exposé en HTTP derrière une authentification.

MCP en production : sécurité et confidentialité

Donner à un modèle la capacité de déclencher des actions demande de la rigueur. Quelques principes que j'applique systématiquement. D'abord, chaque outil sensible mérite une confirmation avant exécution, surtout s'il écrit ou supprime des données. Ensuite, le résultat d'un outil n'a pas besoin de repasser par le modèle : il peut être renvoyé directement à l'application, ce qui évite d'exposer une donnée confidentielle à un fournisseur d'IA tiers. Enfin, un serveur MCP exposé sur le réseau doit être authentifié et cloisonné comme n'importe quelle API métier.

Ces garde-fous ne sont pas propres à MCP, ce sont ceux de toute intégration d'IA sérieuse. J'en détaille d'autres dans mon guide sur l'intégration d'un LLM dans une application Python.

Ce qu'il faut retenir

MCP transforme l'intégration d'outils dans un LLM en un travail propre et réutilisable : on décrit une capacité une seule fois, côté serveur, et n'importe quel modèle sait s'en servir. Associé à LiteLLM, le tout devient indépendant du fournisseur, ce qui protège votre code des changements de modèle. Le modèle se contente d'orchestrer, votre code garde la main sur l'exécution et la donnée.

Vous avez un projet d'assistant, d'agent ou d'intégration d'outils métier à un LLM ? Voyez mes expertises IA et LLM ou parlons-en directement.

Un projet Python ou IA à concrétiser ?

Discutons de votre besoin.

Me contacter