Réponse courte
L’appel de fonctions est une fonction de l’API d’un modèle : vous décrivez des outils dans votre requête, le modèle répond avec le nom et les arguments de celui qu’il veut, et votre propre code l’exécute. MCP est un protocole situé un niveau plus haut : il regroupe les outils dans des serveurs distincts que toute application compatible peut découvrir et appeler, si bien qu’un outil écrit une fois fonctionne dans de nombreux assistants.
Question de suivi Quand avez-vous besoin des deux?
Les deux idées permettent à un modèle de langage d’utiliser des outils, et les deux décrivent ces outils de la même façon, avec un nom, une description et une liste d’entrées écrite en JSON Schema (un format standard pour décrire à quoi doivent ressembler des données). C’est pourquoi il est facile de les confondre. La différence tient à qui possède l’outil et à l’endroit où il vit.
Avec l’appel de fonctions (function calling), qu’OpenAI a ajouté à son API en juin 2023 et que d’autres fournisseurs offrent maintenant aussi, l’outil vit dans votre application. Vous l’énumérez dans chaque requête, le modèle répond « appelle get_weather avec ces arguments », et votre code fait le travail. Avec le Model Context Protocol (MCP), publié par Anthropic le 25 novembre, l’outil vit dans un programme distinct appelé serveur. Une application qui parle MCP, comme Claude Desktop, demande au serveur quels outils il a, et les appelle au nom du modèle.
Les deux parcours, en mots
Imaginez une personne qui demande : « Ai-je besoin d’un parapluie à Montréal aujourd’hui? »
Appel de fonctions :
- Votre application envoie la question et la description de l’outil à l’API du modèle.
- Le modèle répond par un appel d’outil :
get_weather,{"city": "Montréal"}. - Votre application exécute son propre code
get_weather, qui interroge un service météo. - Votre application renvoie le résultat; le modèle rédige la réponse.
MCP :
- Quand l’application hôte démarre, elle se connecte à un serveur MCP météo et envoie
tools/list. Le serveur répond avecget_weatheret son schéma d’entrée. - L’hôte transmet cette description d’outil à son modèle avec la question.
- Le modèle demande
get_weather; l’hôte envoietools/callau serveur. - Le serveur exécute le code et renvoie le résultat; l’hôte le donne au modèle, qui rédige la réponse.
À l’intérieur de l’hôte, l’étape 3 du parcours MCP utilise quand même la fonction d’utilisation d’outils du modèle lui-même. MCP ne remplace pas l’appel de fonctions; il normalise la façon dont les outils sont trouvés et exécutés depuis l’extérieur de l’application.
Un outil météo, construit des deux façons
D’abord, l’appel de fonctions avec la bibliothèque Python d’OpenAI. L’outil est décrit dans la liste tools; régler strict à true, une option ajoutée en août, oblige les arguments du modèle à correspondre exactement au schéma.
from openai import OpenAI
client = OpenAI()
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Météo actuelle d’une ville",
"strict": True,
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": False,
},
},
}]
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Ai-je besoin d’un parapluie à Montréal aujourd’hui?"}],
tools=tools,
)
call = response.choices[0].message.tool_calls[0]
print(call.function.name, call.function.arguments) # get_weather {"city":"Montréal"}
Votre code lancerait maintenant sa recherche météo et renverrait le résultat dans un message avec le rôle tool. L’outil n’existe que dans ce programme.
Voici maintenant le même outil sous forme de serveur MCP, selon le modèle de l’exemple Python de la documentation de MCP. Les données météo sont ici fictives, à titre d’illustration.
from mcp.server import Server
import mcp.types as types
app = Server("weather")
@app.list_tools()
async def list_tools() -> list[types.Tool]:
return [types.Tool(
name="get_weather",
description="Météo actuelle d’une ville",
inputSchema={
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
)]
@app.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_weather":
city = arguments["city"]
report = f"{city} : 4 °C, pluie légère" # exemple; appelez ici une vraie API météo
return [types.TextContent(type="text", text=report)]
raise ValueError(f"Outil inconnu : {name}")
Un serveur complet a aussi besoin de quelques lignes pour démarrer sur l’entrée et la sortie standard, ce que fournit la trousse de développement (SDK). Remarquez ce qui manque : aucun modèle, aucune clé d’API, aucune boucle de conversation. Le serveur sait seulement décrire et exécuter son outil. N’importe quel hôte MCP peut s’y connecter et l’offrir au modèle qu’il utilise.
| Appel de fonctions | MCP | |
|---|---|---|
| Où l’outil s’exécute | Dans le code de votre application | Dans un processus serveur distinct |
| Comment le modèle l’apprend | Vous l’énumérez dans chaque requête à l’API | L’hôte le demande au serveur avec tools/list |
| Qui l’exécute | Votre code | Le serveur, quand l’hôte envoie tools/call |
| Réutilisation | Une application, le format d’un seul fournisseur | Tout hôte compatible MCP |
| Idéal pour | Une seule application que vous contrôlez de bout en bout | Des outils à partager entre applications |
À essayer : prenez un outil que vous avez déjà construit avec l’appel de fonctions et notez trois choses : son JSON Schema, le code qui l’exécute et le code qui parle au modèle. Seuls les deux premiers passeraient dans un serveur MCP. Voir quelles lignes vont où rend la séparation claire.
Quand avez-vous besoin des deux?
Chaque fois que vous construisez votre propre application qui doit utiliser des outils partagés. Supposons que votre entreprise écrive un serveur MCP pour sa base de données de commandes, pour que le personnel puisse s’en servir depuis Claude Desktop. Plus tard, vous construisez un robot conversationnel de service à la clientèle sur l’API d’un modèle. Votre robot peut jouer le rôle d’hôte MCP : il se connecte au même serveur, lit la liste des outils, convertit chaque outil dans le format d’appel de fonctions qu’attend son modèle, et transmet au serveur les appels d’outils du modèle. L’appel de fonctions gère la conversation avec le modèle; MCP gère la recherche et l’exécution de l’outil. Personne n’écrit le code de la base de données deux fois.
Si vous construisez une petite application avec deux ou trois outils que personne d’autre n’utilisera, le simple appel de fonctions est plus simple : il n’y a pas de processus supplémentaire à faire tourner. MCP devient rentable à mesure que les outils se multiplient, ou quand plusieurs applications, ou plusieurs équipes, ont besoin des mêmes.
Dans les deux cas, les règles de sécurité sont les mêmes. La documentation de MCP demande aux personnes qui construisent des serveurs de valider chaque entrée par rapport au schéma et de garder une personne dans la boucle pour approuver les actions. Les conseils d’OpenAI sur l’appel de fonctions disent de confirmer avec l’utilisateur les actions qui ont des effets concrets, comme envoyer un courriel ou faire un achat, avant de les exécuter.
Sources
- Tools (Model Context Protocol documentation) — Model Context Protocol / Anthropic (GitHub), 2 décembre 2024
- Introducing Structured Outputs in the API — OpenAI, 6 août 2024
- Function calling and other API updates — OpenAI, 13 juin 2023