Outils & Modèles Par

Serveur MCP : ouvrir votre logiciel à Claude et ChatGPT

Un serveur MCP est un service que l'éditeur publie à côté de son API pour que Claude, ChatGPT et les autres assistants compatibles puissent lire et agir dans son logiciel, au nom de l'utilisateur et avec ses droits. Il expose trois types d'éléments définis par le Model Context Protocol : des outils (tools), des ressources (resources) et des modèles de requêtes (prompts). Quand l'API existe, le branchement se fait vite ; le travail porte sur le choix des outils, l'authentification OAuth, l'isolation entre clients, les écritures et les tests du tool calling.

Cet article s'adresse aux équipes produit et techniques d'éditeurs (CTO, lead dev, product managers) qui construisent leur propre serveur. Pour brancher un agent interne sur un logiciel, la comparaison entre API directe et MCP est traitée dans connecter un agent IA à votre logiciel. Pour voir le résultat côté utilisateur, l'exemple de Pennylane MCP avec Claude montre ce que vos clients auront entre les mains.

Les exemples de code sont en Python avec FastMCP, que nous utilisons en production. Les points sur le protocole renvoient à la révision de la spécification datée du 28 juillet 2026.

Points clés à retenir

  • Un serveur MCP expose des tools (actions), des resources (données en lecture) et des prompts (modèles de requêtes) ; pour un éditeur, l'essentiel du travail porte sur les tools
  • Un outil par endpoint donne une liste longue et confuse : on part des tâches des utilisateurs et on garde peu d'outils, bien décrits, aux résultats bornés
  • Le serveur appelle votre API avec le jeton OAuth de l'utilisateur, jamais avec un compte de service ; le compte client (tenant) est lu dans le jeton, pas fourni par le modèle
  • Les écritures arrivent après une période en lecture seule, en deux temps : un outil prépare et montre, l'utilisateur confirme, un second outil exécute
  • Un serveur destiné aux clients d'un SaaS est distant, en HTTP streamable derrière OAuth ; stdio sert aux usages locaux et aux tests
  • Un benchmark du tool calling, rejoué à chaque changement de description, de modèle ou d'API, permet de faire évoluer le serveur sans régression

Ce qu'un serveur MCP expose : tools, resources, prompts

Le Model Context Protocol définit trois primitives côté serveur. Elles ne sont pas déclenchées par le même acteur, et c'est ce critère qui guide les choix d'un éditeur.

Primitive Qui la déclenche Exemple pour un logiciel de facturation Place dans un serveur d'éditeur
Tools Le modèle, quand il juge qu'il en a besoin Lister les factures en retard d'un client, préparer un avoir L'essentiel du serveur, pris en charge par tous les clients
Resources L'application cliente ou l'utilisateur, qui les joint au contexte La grille tarifaire, les conditions générales de vente Utile pour des documents de référence ; support variable selon les clients
Prompts L'utilisateur, souvent par une commande « Préparer la relance mensuelle des impayés » Pratique pour standardiser une tâche fréquente ; support variable

Dans la pratique, un serveur d'éditeur est d'abord une liste de tools. Un utilisateur qui écrit dans Claude « quelles factures de ce client sont en retard ? » déclenche un appel d'outil ; il ne va pas chercher une ressource dans un menu. Les resources et les prompts viennent en complément, une fois les outils stabilisés.

Côté vocabulaire, serveur MCP et MCP server désignent la même chose, et le client MCP est l'application qui s'y connecte : Claude, ChatGPT, Copilot, un IDE ou votre propre agent. Le protocole a été publié par Anthropic en novembre 2024, adopté depuis par OpenAI, Google et Microsoft, et sa gouvernance a été confiée en décembre 2025 à l'Agentic AI Foundation, hébergée par la Linux Foundation. Pour situer MCP parmi les autres briques d'un agent (modèle, mémoire, orchestration), voyez notre guide des agents IA en entreprise.

Quels outils exposer, et à quelle granularité ?

La liste d'outils d'un serveur MCP part des tâches que vos utilisateurs font dans le logiciel, pas de la liste des routes de l'API. Un outil par endpoint donne vite trente ou quarante outils proches (get_invoice, get_invoice_lines, get_invoice_status...), et plus la liste est longue et ressemblante, plus le modèle se trompe d'outil ou en enchaîne trois là où un seul suffisait.

Partir des demandes réelles, puis regrouper

On récupère ce que les utilisateurs demandent vraiment : tickets de support, questions posées aux chargés de compte, exports que les clients font à la main pour retravailler leurs données dans Excel. Chaque tâche fréquente donne un outil, qui peut appeler plusieurs routes en interne et renvoyer un résultat déjà filtré.

  • lister_factures_en_retard(client, depuis_jours) plutôt qu'une liste complète des factures que le modèle filtrerait lui-même
  • resume_compte_client(client), qui assemble contrat, encours et dernières factures en un seul appel
  • rechercher_documentation(question) pour les questions d'usage, qui renvoie des extraits de votre documentation avec leur lien

Les résultats doivent être bornés : pagination, nombre de lignes maximum, champs utiles seulement. Un outil qui renvoie 5 000 lignes de JSON remplit le contexte du modèle et ralentit la réponse sans l'améliorer.

Ce qu'on n'expose pas, au moins au début

  • L'administration : gestion des utilisateurs, des rôles, de l'abonnement
  • Les actions irréversibles ou massives : suppression, envoi groupé, clôture de période
  • Les exports complets, qui feraient du serveur un canal d'extraction de données
  • Les routes internes ou non documentées, dont le comportement change sans préavis

Un premier serveur en lecture seule couvre déjà une bonne part de l'usage : retrouver, croiser, résumer. Les écritures arrivent ensuite, une par une.

Décrire l'outil pour le modèle

Le modèle choisit un outil à partir de trois informations : son nom, sa description et le schéma de ses paramètres. La description est donc du texte de production, à écrire comme une documentation d'API pour un lecteur pressé : ce que fait l'outil, quand l'utiliser, quand ne pas l'utiliser, ce qu'il renvoie. Avec FastMCP, la docstring et les types Python suffisent à générer ce schéma.

from typing import Annotated
from pydantic import BaseModel, Field
from fastmcp import FastMCP

mcp = FastMCP("facturation")

class FactureEnRetard(BaseModel):
    numero: str
    montant_ttc: float
    echeance: str
    jours_de_retard: int

@mcp.tool(annotations={"readOnlyHint": True})
async def lister_factures_en_retard(
    client_id: Annotated[str, Field(description="Identifiant renvoyé par rechercher_client")],
    depuis_jours: Annotated[int, Field(ge=1, le=365)] = 30,
) -> list[FactureEnRetard]:
    """Liste les factures impayées d'un client dont l'échéance est dépassée
    d'au moins `depuis_jours` jours, de la plus en retard à la moins en retard
    (50 au maximum). À utiliser pour les questions sur les retards de paiement
    d'un client précis. Pour le chiffre d'affaires, utiliser resume_compte_client."""
    ...

L'annotation readOnlyHint indique au client que l'outil ne modifie rien, ce qui lui permet d'alléger la demande de confirmation. La spécification précise que ces annotations sont des indications, qu'un client ne doit pas croire sur parole venant d'un serveur qu'il ne connaît pas. Votre serveur ne doit donc pas s'en servir comme contrôle de sécurité : le contrôle, c'est votre API qui le fait.

Authentification et droits : OAuth, périmètre par utilisateur, multi-tenant

Un serveur MCP distant authentifie chaque utilisateur avec OAuth et appelle votre API avec le jeton de cet utilisateur : l'assistant ne peut alors rien faire que l'utilisateur ne pourrait faire lui-même dans l'interface. Cette règle répond à la plupart des questions de sécurité que posent les clients d'un éditeur.

OAuth au nom de l'utilisateur

La spécification décrit l'autorisation des serveurs MCP en HTTP à partir d'OAuth 2.1. Le serveur MCP est un serveur de ressources : il indique quel serveur d'autorisation utiliser, le client (Claude, ChatGPT...) y envoie l'utilisateur se connecter, puis présente un jeton d'accès à chaque requête. Ce serveur d'autorisation peut être celui que vous utilisez déjà : Keycloak, Auth0, Microsoft Entra ID, Amazon Cognito ou votre propre fournisseur OpenID Connect. FastMCP sait déléguer cette partie à un fournisseur existant.

Un point a bougé récemment : la révision du 28 juillet 2026 privilégie les Client ID Metadata Documents pour l'enregistrement des clients et passe l'enregistrement dynamique (Dynamic Client Registration, RFC 7591) au statut déprécié, tout en le gardant pour la compatibilité. Si vous démarrez un serveur maintenant, c'est à vérifier avec votre fournisseur d'identité.

Le compte client vient du jeton, jamais du modèle

Dans un SaaS multi-clients, l'identifiant du compte (le tenant) ne doit jamais être un paramètre que le modèle remplit. Il est lu dans le jeton, et l'API filtre en fonction. Un modèle peut se tromper d'identifiant, ou être poussé à en essayer un autre par un texte malveillant glissé dans une donnée qu'il lit (injection de prompt) ; si le cloisonnement dépend de lui, il cédera un jour.

from fastmcp.server.dependencies import get_access_token

@mcp.tool(annotations={"readOnlyHint": True})
async def resume_compte_client(client_id: str) -> ResumeCompte:
    """Résumé d'une fiche client : contrat, encours, dernières factures."""
    jeton = get_access_token()
    # Le compte (tenant) et les droits sont déduits du jeton par l'API,
    # exactement comme pour une requête venue de l'interface web.
    return await api.get(f"/clients/{client_id}/resume", bearer=jeton.token)

Le serveur MCP ne garde pas de super-clé capable de tout lire. S'il est compromis, il ne donne accès qu'à ce que les jetons en cours autorisent.

Des droits par outil, pas seulement par compte

Le même principe s'applique aux rôles. Sur l'agent orchestrateur que nous avons développé pour ModelRH, les 23 outils sont typés et chargés selon les droits de l'utilisateur, et les calculs lourds passent par une validation humaine avant d'être lancés. Pour un serveur MCP, on applique ce principe à deux niveaux : la liste d'outils présentée tient compte du rôle, et le contrôle est refait à chaque appel. La révision de juillet 2026 rend le protocole sans état (plus de session ni de poignée de main initiale) : chaque requête porte son jeton et se vérifie seule.

Écrire dans le logiciel : la validation humaine avant l'action

Un serveur MCP peut créer, modifier ou supprimer des données, mais une écriture doit être confirmée par l'utilisateur avant d'être exécutée, pas seulement journalisée après coup. Claude et ChatGPT proposent une confirmation avant d'appeler un outil, mais ce réglage appartient à l'utilisateur, qui peut l'assouplir : le serveur ne doit pas en dépendre.

Le schéma que nous utilisons tient en deux outils :

  1. preparer_avoir(facture, montant, motif) vérifie les droits et les règles métier, n'écrit rien, et renvoie un aperçu lisible avec un identifiant d'opération, créé et stocké par le serveur, à durée de vie courte.
  2. confirmer_operation(operation_id) exécute l'opération préparée, telle quelle, après accord explicite de l'utilisateur. Le modèle ne transmet que l'identifiant : il ne peut pas changer le montant entre les deux étapes.

Ce motif correspond à ce que demande la révision de juillet 2026 : un serveur qui a besoin d'un état entre deux appels passe des identifiants explicites, créés par lui, en argument des outils. Quand une information manque (quel compte bancaire, quelle date d'effet), le protocole prévoit aussi l'élicitation : le serveur demande la précision à l'utilisateur par l'intermédiaire du client, au lieu de laisser le modèle deviner. Les annotations destructiveHint et idempotentHint complètent le tableau, avec la même réserve que plus haut : ce sont des indications, pas des garde-fous.

Ce qui reste dans l'interface du logiciel

  • Les suppressions et les opérations en masse
  • Ce qui engage un tiers sans relecture : envoi d'un email à un client, paiement, signature
  • Les réglages du compte, des utilisateurs et des droits

Chaque écriture est journalisée avec l'utilisateur, le client MCP utilisé, les arguments, l'aperçu montré, la confirmation et le résultat. Le jour où un client conteste une modification, cette trace répond à la question « qui a validé quoi », et elle rend l'annulation possible. Notre article sur les agents IA qui bouclent ou dérapent en production détaille ce qui arrive quand ces garde-fous manquent.

stdio ou HTTP streamable : où tourne le serveur ?

Un serveur MCP destiné aux clients d'un SaaS est un serveur distant, joignable en HTTP streamable et protégé par OAuth ; le transport stdio sert quand le serveur tourne sur la machine de l'utilisateur. Le choix dépend de qui installe le serveur, et où.

Critère stdio HTTP streamable
Où tourne le serveur Sur le poste, lancé par le client (Claude Desktop, Claude Code, un IDE) Sur votre infrastructure, à une URL publique
Pour qui Développeurs, tests, outils internes, accès à des fichiers locaux Les clients de votre SaaS, depuis Claude, ChatGPT ou Copilot
Authentification Clé ou jeton dans la configuration locale OAuth 2.1 au nom de l'utilisateur
Mises à jour Chaque utilisateur met à jour son installation Vous déployez, tout le monde a la nouvelle version
Observabilité Logs sur le poste, hors de votre portée Logs et traces centralisés chez vous

L'ancien transport HTTP+SSE, remplacé par le HTTP streamable dans la révision de mars 2025, est désormais formellement déprécié. Si un serveur ou un exemple que vous reprenez l'utilise encore, il est à migrer. Avec FastMCP, le même code peut tourner dans l'un ou l'autre transport, ce qui permet de tester en local avant de déployer.

Pour l'hébergement, un serveur HTTP sans état se déploie comme n'importe quel service web, derrière votre reverse proxy, avec plusieurs instances si besoin. Depuis la révision de juillet 2026, il n'y a plus d'identifiant de session à partager entre instances, et la reprise d'un flux interrompu a été retirée : le client relance simplement la requête.

Tester, observer et maintenir un serveur MCP en production

Un serveur MCP se teste à deux niveaux : le code (chaque outil renvoie le bon résultat, avec les bons droits) et le tool calling (le modèle choisit le bon outil, avec les bons arguments). Le second niveau est souvent oublié, et c'est lui qui casse quand on modifie une description ou qu'on change de modèle.

Un benchmark du tool calling

Pour un éditeur de plateforme IA, nous avons développé des serveurs MCP avec FastMCP, des agents Pydantic AI qui les appellent, et un benchmark du tool calling. Le principe : une liste de demandes réalistes, chacune avec la trace attendue.

  • La demande : « quelles factures de Dupont SA ont plus de 60 jours de retard ? »
  • La trace attendue : rechercher_client("Dupont SA"), puis lister_factures_en_retard(client_id, 60)
  • Les cas sans appel : une question hors périmètre, une action que l'utilisateur n'a pas le droit de faire

On note chaque scénario de façon binaire sur trois critères : le bon outil, les bons arguments, aucun appel inutile. On rejoue le jeu sur les modèles que vos clients utilisent, car une même liste d'outils n'est pas lue de la même façon par tous, et à chaque modification d'une description. C'est la méthode que nous appliquons aussi aux RAG : sans mesure posée dès le départ, impossible de savoir si une modification améliore ou dégrade le système.

Observer chaque appel

Chaque appel d'outil est tracé : client MCP, utilisateur, outil, arguments, durée, résultat ou erreur. Sur ce projet, nous avons utilisé Logfire, qui repose sur OpenTelemetry ; la révision de juillet 2026 documente d'ailleurs la propagation du contexte de trace OpenTelemetry dans les métadonnées des requêtes MCP. Notre comparatif des outils d'évaluation et d'observabilité des LLM présente les autres options.

Une limite à connaître : votre serveur voit les appels d'outils, pas la conversation de l'utilisateur dans Claude ou ChatGPT. Les traces disent quel outil a été appelé, pas pourquoi. Elles servent quand même à trois choses : comprendre une réponse contestée, repérer les outils jamais appelés (souvent mal décrits) et alimenter le benchmark avec les vraies demandes.

Quand l'API évolue

Le serveur MCP est un client de votre API, et ses outils forment un contrat avec les modèles et avec les utilisateurs qui les ont autorisés. Les règles qui évitent les régressions :

  • des noms d'outils stables : un outil renommé est un nouvel outil pour le modèle comme pour l'utilisateur
  • des paramètres ajoutés en optionnel plutôt que modifiés
  • les tests du serveur MCP dans la CI de l'API, pour qu'une route modifiée casse le build et pas la conversation d'un client
  • le benchmark rejoué avant chaque déploiement du serveur
  • une liste d'outils renvoyée dans un ordre stable, ce que recommande la révision de juillet 2026 pour faciliter le cache côté client et le cache de prompt des modèles

Le protocole lui-même bouge : quatre révisions entre mars 2025 et juillet 2026 (2025-03-26, 2025-06-18, 2025-11-25, 2026-07-28), que le changelog officiel détaille. Un framework maintenu comme FastMCP absorbe une partie de ces changements, mais la mise à jour des dépendances fait partie de la maintenance du serveur.

Si vous voulez publier un serveur MCP pour votre produit, c'est ce que couvre notre offre pour ajouter l'IA à un logiciel : liste d'outils, OAuth, isolation entre clients, journalisation, benchmark et documentation d'installation, avec le code livré dans votre dépôt. Si le besoin est un agent qui orchestre plusieurs outils de votre côté, voyez notre développement d'agents IA sur mesure.

Vous préparez un serveur MCP pour votre logiciel ?

Montrez-nous votre API et les demandes de vos clients : nous vous disons quels outils exposer en premier, comment les sécuriser et comment les tester, sur devis.

Prendre un rendez-vous

Questions fréquentes sur le serveur MCP d'un éditeur de logiciel

C'est un service que l'éditeur publie à côté de son API et qui décrit, au format du Model Context Protocol, les actions (tools), les données (resources) et les modèles de requêtes (prompts) qu'un assistant IA peut utiliser dans son produit. Une fois le serveur ajouté dans Claude, ChatGPT ou un autre client compatible, l'utilisateur interroge ou pilote le logiciel depuis son assistant, avec ses propres droits. Le serveur appelle en général l'API existante : il ne la remplace pas.
Non. Un outil par endpoint donne vite plusieurs dizaines d'outils proches les uns des autres, et le modèle choisit moins bien. On part des questions et des tâches réelles des utilisateurs, puis on regroupe : un outil peut appeler plusieurs routes et renvoyer un résultat déjà filtré. Une dizaine d'outils bien décrits couvre souvent mieux le besoin qu'une copie de l'API.
La spécification MCP s'appuie sur OAuth 2.1 pour les serveurs distants : le serveur MCP joue le rôle de serveur de ressources et l'utilisateur s'authentifie auprès d'un serveur d'autorisation, souvent celui que l'éditeur utilise déjà pour son application. Le serveur MCP reçoit ensuite un jeton au nom de l'utilisateur et appelle l'API avec ce jeton, ce qui applique les droits existants. Une clé API partagée par tous les utilisateurs est à éviter.
stdio sert quand le serveur tourne sur le poste de l'utilisateur, lancé par le client (Claude Desktop, Claude Code, un IDE) : c'est pratique pour un outil développeur ou un test. Pour un éditeur qui veut que ses clients branchent son produit depuis Claude ou ChatGPT sur le web, le serveur est distant, donc en HTTP streamable, derrière OAuth. L'ancien transport HTTP+SSE est déprécié depuis la révision de mars 2025.
Oui, un outil peut écrire, créer ou supprimer, avec les droits de l'utilisateur. On le fait en deux temps : un outil prépare l'action et renvoie un aperçu, l'utilisateur confirme, puis un second outil l'exécute. On n'expose les écritures qu'après une période en lecture seule, on journalise chaque appel, et les actions irréversibles ou massives restent dans l'interface du logiciel.
FastMCP est un framework Python qui transforme une fonction typée en outil MCP, avec la génération du schéma, les transports et l'authentification. Sa première version a été intégrée au SDK Python officiel, et le projet indépendant a continué d'évoluer. Pour un serveur Python, c'est le choix le plus direct. Le SDK officiel reste pertinent si vous voulez coller au plus près de la spécification ou si vous travaillez dans un autre langage, avec le SDK TypeScript par exemple.
Avec un jeu de scénarios écrits à partir de demandes réelles, chacun associé à la trace attendue : quel outil, avec quels arguments, et parfois aucun appel. On rejoue ce jeu sur plusieurs modèles et à chaque modification des descriptions d'outils, en mesurant le taux d'outil correct, d'arguments corrects et d'appels inutiles. Sans ce banc de test, on ne sait pas si un changement de description améliore ou dégrade le serveur.
Le serveur MCP est un client de votre API : une route renommée ou un champ supprimé casse l'outil qui l'utilise. Les noms, descriptions et schémas des outils forment aussi un contrat avec les modèles. On garde donc des noms stables, on ajoute des paramètres optionnels plutôt que de modifier les existants, on fait tourner les tests du serveur dans la CI de l'API, et on rejoue le banc de tool calling avant chaque mise en production.

Pour aller plus loin

Formation

Pour que vos équipes appliquent ces usages sur leurs propres documents, voir notre formation agents IA, construite sur vos cas.

IA dans votre logiciel

Vous voulez brancher l'IA sur votre logiciel ou vos API ?

On conçoit l'intégration avec vos développeurs : serveur MCP, appels API aux modèles, agents qui agissent dans votre produit, avec droits d'accès, journalisation et tests sur vos vrais cas avant la mise en production.

Anas Rabhi, ingénieur IA et data scientist, fondateur de Tensoria
Anas R. Ingénieur IA, fondateur de Tensoria ianas.fr

Je suis ingénieur IA et data scientist, fondateur de Tensoria. Depuis plus de 6 ans, je conçois et développe des systèmes IA pour les entreprises : assistants internes basés sur RAG, agents IA en production, automatisations sur mesure, traitement intelligent de documents. Je prends le projet en charge du cadrage à la mise en production, sur les modèles du marché (Mistral, Claude, GPT) ou sur des modèles ouverts hébergés chez le client quand la confidentialité l'exige.