All articles
Créez vos propres serveurs MCP

Créez vos propres serveurs MCP

Découvrez comment concevoir et construire des serveurs MCP sécurisés en TypeScript ou en Python.

Résumer avec l'IA :

AM
Antonin Marxer
· 17 min read10

Il existe beaucoup de ressources sur le sujet, mais je n’ai pas trouvé de vue d’ensemble claire des serveurs MCP ni de méthode standard pour en construire un, à part des Redditors qui conseillent de « demander à Claude ou Windsurf ». J’ai regroupé une perspective DevOps, des tutoriels et des listes curatées dans ce guide, en espérant clarifier le concept de MCP et vous aider à construire des serveurs MCP conformes aux standards.

Dans cet article, je passe en revue :

  1. Architecture et design d’un MCP :
    Comprendre l’architecture de communication client-serveur d’un MCP et savoir comment en concevoir un (avis personnel)

  2. Construire et déployer des serveurs MCP TypeScript pour Cloudflare Workers

  3. Construire des serveurs MCP Python avec fastmcp

  4. Transformer des agents existants en serveurs MCP avec auto-mcp

Architecture et design d’un MCP

Comme je le disais dans mon précédent article Comment utiliser les serveurs MCP, le standard Model Context Protocol (MCP) définit un cadre d’interaction entre un outil et un agent IA. Un MCP expose à l’agent une liste d’outils qu’il peut utiliser et il n’a plus qu’à choisir le bon pour accomplir sa tâche.

Exemple : vous voulez que votre agent gère vos PR GitHub et récupère vos dépôts.
→ Le GitHub MCP Server enveloppe les fonctionnalités de GitHub et les rend accessibles à l’agent de votre IDE

Comment concevoir son MCP ? Pas comme une API.

Les agents qui utilisent des MCP sont des généralistes. Si vous calez votre MCP sur une spec d’API, les outils disponibles deviennent atomiques, granulaires, et il faut les appeler dans un ordre précis pour qu’ils fonctionnent ensemble.

Prenons l’exemple d’une API de tickets de support client qui expose les endpoints suivants :

  • createTicket

  • addMessage

  • assignAgent

  • updateStatus

  • closeTicket

Pour un LLM, c’est comme recevoir tous les vis, les fils et les circuits imprimés au lieu d’un bouton « résoudre le problème du client ». Il doit deviner dans quel ordre procéder (faut-il assigner le ticket avant d’ajouter une réponse ?), quelles transitions de statut sont valides (open → pending → resolved ou open → closed) et quand s’arrêter.

En design MCP, on expose plutôt des outils de plus haut niveau, comme :

  • resolveTicket : gère l’assignation, les messages et la clôture

  • escalateTicket : gère le routage et la notification des superviseurs

  • summarizeConversation : fournit une vue condensée à l’agent

Le poids quitte la logique d’orchestration pour retomber côté accomplissement de l’objectif. Le LLM n’a plus à jouer l’ingénieur support qui jongle avec les API, il choisit simplement le bon outil pour le travail.

Une API reste toutefois un excellent point de départ.

Comment communiquent les agents IA et les serveurs MCP ?

Une communication MCP fait intervenir trois composants :

  • Host : environnement d’exécution des tâches IA, comme un IDE ou une application propulsée par l’IA (Claude Desktop).

  • Client : intermédiaire qui gère la communication entre l’hôte et les serveurs MCP. Il traite les requêtes, récupère les capacités du serveur et gère les notifications.

  • Server : donne accès aux outils, ressources et prompts externes. Il permet au modèle IA de faire des opérations comme la récupération de données, l’appel d’API ou l’optimisation de workflows.

![MCP workflow](https://cdn.prod.website-files.com/6321a7346f73799791d41a39/67f760d5fa47b33e78f7a1c0_AD_4nXdUTtXUiCEJDVbmTV71N740IUTqi7qd06Ih1xOCnhTYa11lh58btM-KqLDuyuabJQUkzpjqY3DpJHzcpSMiy09fL8lOoxJk1RdM-6zVuejkC6cdwFMmFctDExuckhRVnk8Evpw2.avif align="left")

Processus MCP

Votre IDE joue le rôle d’hôte MCP (MCP Host) : il héberge des clients MCP qui interrogent les serveurs.
À l’initialisation, l’agent de votre IDE interroge les serveurs MCP pour découvrir les outils disponibles, via les messages ListToolsRequest/ListToolsResult. Il appelle ensuite ces outils avec les messages CallToolRequest/CallToolResult.

Hébergement d’un MCP

Les serveurs MCP peuvent être déployés en local comme à distance.
Local : une approche privacy-first, qui passe par le protocole de transport Standard IO.

Un serveur MCP distant apporte :

  • Cohérence : une seule version du serveur, le même comportement pour tous les clients.

  • Intégration d’équipe : un outil ajouté une fois, disponible immédiatement pour tout le monde.

  • Centralisation : pas de configuration dupliquée sur chaque machine de dev.

  • Scalabilité : les grosses charges sont absorbées par l’infra distante et un grand nombre de clients peut être supporté.

  • Isolation : le serveur n’expose que les ressources et les fichiers qui doivent l’être.

Si votre MCP touche à des fichiers locaux sensibles ou exige une très faible latence, je vous suggère de le garder seulement en local.

Vous verrez plus bas comment héberger un serveur MCP avec Cloudflare Workers.
J’en dirai plus sur l’hébergement MCP dans un article dédié
→ à suivre

Protocoles MCP

MCP est agnostique au transport : le client et le serveur peuvent communiquer via différents protocoles selon votre configuration.

Il suit en revanche toujours un schéma de type RPC (Remote Procedure Call). Pensez à des requêtes « à la demande » : le client invoque des méthodes sur des serveurs distants comme s’il s’agissait d’appels de fonctions locaux. La complexité de l’hébergement du modèle, de la gestion des ressources et du traitement des requêtes reste masquée.

Dans votre serveur MCP, les réponses doivent suivre la spécification JSON-RPC 2.0.

![Architecture diagram showing the communication flow from Tools to Client applications](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*17aHWZr0VGP7EGwbzB2QXw.png align="center")

Passons en revue les protocoles disponibles :

  • Standard IO (Stdio) : communication locale bidirectionnelle courante, simple, typique des processus CLI ou des conteneurs.

  • HTTP, avec deux sous-types :

    1. SSE (Server-Sent Events) : communication unidirectionnelle serveur → client. Push temps réel via HTTP, texte seul, via le type MIME text/event-stream.

      Il ouvre une session longue durée sur l’endpoint /sse.

      Il reçoit les messages sur l’endpoint /messages et répond via la session SSE.

      C’est désormais déprécié : le protocole maintient la session SSE ouverte, ce qui ne convient pas aux serveurs éphémères (serverless).
      Utilisez plutôt Streamable HTTP, via l’endpoint /mcp ⬇️

    2. Streamable HTTP : communication HTTP unidirectionnelle ou bidirectionnelle avec transfert en bloc (chunked transfer encoding). Il utilise un endpoint unique : /mcp

  • WebSocket : un protocole dédié (ws:// ou wss://) qui permet une communication bidirectionnelle interactive : on écoute les changements et on est notifié à chaque arrivée.

Les problèmes des connexions distantes

Pour pousser des données vers les clients quand il le faut, les connexions SSE et WebSocket sont longues. Si vous hébergez votre serveur MCP à distance, une connexion peut rester ouverte très longtemps.

Les problèmes classiques avec HTTP et WebSocket :

  • connexion qui tombe au milieu d’une réponse sans raison

  • la plupart des navigateurs limitent à 6 connexions SSE (EventSource) simultanées par domaine, ce qui peut gêner quand on l’utilise plusieurs fois.

  • difficile de savoir d’où vient le problème : du client MCP, du serveur ou du réseau.

En guise de solution :

  • utiliser le protocole /mcp Streamable HTTP.

  • nommer les outils MCP en snake_case ou en tirets pour rester compatible avec les clients et éviter des échecs de requête subtils.

  • valider les payloads entrants et sortants contre des schémas JSON stricts, pour attraper les erreurs avant traitement.

Renvoyez les codes d’erreur courants du JSON-RPC 2.0

Des retours d’erreur explicites aident le client MCP à gérer proprement les échecs.

Code Description Cause courante Comment réagir
-32000 Erreur d’authentification Jeton manquant ou invalide Renvoyer un header WWW-Authenticate
-32001 Session invalide Session introuvable Le client doit se réinitialiser
-32002 Méthode inconnue Le client a appelé une méthode inconnue Vérifier le nom de la méthode
-32003 Paramètres invalides Paramètres manquants ou invalides Valider les paramètres
-32004 Erreur interne Exception côté serveur Journaliser les détails pour le debug
-32005 Erreur de parsing JSON invalide Valider le format de la requête

Mettre en place ces stratégies de gestion d’erreur garantit que les clients reçoivent un retour exploitable quand quelque chose se passe mal.

Observabilité et dépannage

  • Journaliser en détail et de façon structurée, avec un ID de corrélation unique, pour tracer requêtes, réponses et erreurs.

  • Exposer des endpoints de health check et mettre en place du monitoring et des alertes sur les erreurs de connexion et les métriques anormales.

Risques de sécurité MCP et bonnes pratiques

Un serveur MCP lancé en local, c’est comme n’importe quel autre logiciel : accès illimité à tous vos fichiers. Pour le faire tourner en sécurité, passez par Docker. Je prépare d’ailleurs un guide là-dessus.
Pour les serveurs distants, il faut aussi restreindre les ressources accessibles, surtout en self-hosting.

Les frameworks distants intègrent des contraintes de sécurité liées à ces risques :

  • Prompt injection et empoisonnement d’outils : des prompts malveillants peuvent déclencher des outils MCP dangereux.
    → certains IDE permettent de mettre des outils MCP sur liste noire, ou demandent une confirmation avant l’action

  • Injection de code : un serveur MCP qui exécute des commandes (le serveur filesystem, par exemple) peut lancer un rm -rf / au lieu de lister les fichiers, parce qu’une chaîne n’a pas été validée.
    → assainir les chaînes

  • Fuite de credentials : le jeton que vous passez à votre serveur MCP peut fuiter, et se retrouver exposé dans un log de debug.
    → utiliser des frameworks MCP qui supportent OAuth 2.1, les jetons JWT, les signatures HMAC.

    → journaliser les événements d’authentification, d’autorisation et d’activité pour garder une trace.

  • Trop de permissions : appliquer le principe du moindre privilège : aucune ressource ne devrait avoir plus d’accès que nécessaire pour accomplir sa tâche.
    → utiliser le contrôle d’accès par rôle (RBAC)
    → limiter les ressources accessibles

  • Garantir l’intégrité des outils : des serveurs MCP légitimes peuvent être usurpés. Sans validation d’intégrité, vos données peuvent être envoyées à des serveurs MCP malveillants de substitution.
    → notifier les utilisateurs dès qu’un outil est mis à jour ou remplacé.
    → exiger le certificate pinning sur toutes les connexions TLS.
    → bloquer les endpoints qui ne passent pas la vérification TLS ou des métadonnées.

Dans la suite de l’article, nous verrons quels frameworks respectent ces exigences.

Cas d’usage des MCP

Les bases sont posées : passons aux principaux cas d’usage des serveurs MCP :

  1. Envelopper une API existante : exposer des services tiers (GitHub, Jira, Slack, AWS).

    Nous passerons chaque étape avec Tadata, qui génère des serveurs MCP à partir de fichiers de spécification OpenAPI.

  2. Adaptateur de framework : faire le pont avec un framework d’orchestration ou d’agents (CrewAI, LangGraph, LlamaIndex, OpenAI).
    Nous utiliserons auto-mcp pour ce cas.

  3. Se connecter à un hôte distant depuis un client MCP local :
    Utilisez mcp-remote, un outil CLI qui permet à des clients MCP existants, comme Cursor ou Windsurf, de se connecter à des serveurs distants.

    Comme je le disais, Streamable HTTP est à préférer au protocole SSE. C’est exactement ce que fait mcp-remote :
    quand on lance mcp-remote https://my-mcp.example.com, il essaie d’abord l’endpoint /mcp. S’il reçoit une 404, il retombe sur l’endpoint /sse.

  4. Logique métier sur mesure : implémenter des workflows ou des règles métier spécifiques à votre domaine, à partir de zéro. Autant ne pas réinventer la roue et utiliser des frameworks qui embarquent le support d’OAuth 2.1 :

    • Le SDK TypeScript officiel pour MCP : typescript-sdk

    • Le framework TypeScript FastMCP : punkpeye/fastmcp

    • La façon pythonique de construire des serveurs et clients MCP : jlowin/fastmcp

    Pour un démarrage rapide en TypeScript, je recommande les templates de serveurs MCP de Cloudflare, voir cloudflare/ai/demos. Nous y reviendrons dans la section suivante.

  5. Utiliser des MCP dans une app Python : il vous faut appeler des MCP existants depuis votre app Python.

  6. Utiliser des MCP dans une app TypeScript : vous pouvez utiliser mcp-client pour brancher n’importe quel serveur MCP dans votre app JS.

typescript
1
2
3
4
5
6
7
import { MCPConnectionManager } from 'mcp-client';
const manager = new MCPConnectionManager();
await manager.initialize('./mcp-config.json');
const client = manager.getClient('memory');
const tools = await client?.listTools();
const result = await client?.callTool('toolName', { /* params */ });
await manager.cleanup();
  1. Proxy/gateway : agréger plusieurs services ou imposer des politiques d’accès. Les principales solutions de gateway MCP :
  • Unla MCP Gateway : un service de gateway léger qui transforme à la volée des serveurs et API MCP existants en serveurs MCP, sans toucher au code. Déploiement Docker et UI de gestion inclus, sans modification de l’infra.

  • Microsoft MCP gateway : reverse proxy et couche de gestion pour les serveurs MCP, qui permet un routage évolutif conscient de la session et la gestion du cycle de vie des serveurs MCP sous Kubernetes.

Vous avez maintenant une vue d’ensemble de l’écosystème MCP. Place à votre premier serveur MCP ⬇️

Construire et déployer des serveurs MCP sur Cloudflare Workers

Je vous conseille les templates de serveurs MCP de Cloudflare, qui supportent OAuth et Streamable HTTP. Ils existent en TypeScript et en Python, mais la version Python dépasse la limite de taille du plan Free et ne peut pas y être déployée. Dans la section suivante, on verra une autre approche pythonique pour partager un serveur MCP.

Streamable HTTP vient d’arriver dans les templates Cloudflare, via l’endpoint /mcp :

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1756814384051/a51232e7-4183-4225-9a92-fce9539e0e09.png align="center")

L’endpoint /sse est conservé en repli, mais si des clients s’y connectent via mcp-outline —sse-first <your_mcp_server_url>, vos coûts peuvent grimper vite. Je suggère donc de le supprimer carrément : il renverra une 404 tout seul.

Démarrer avec un serveur MCP TypeScript sur Cloudflare Wokers

Disons que vous voulez que les membres de votre organisation se connectent à votre MCP maison. Avec Google Workspace, il vous faut Google OAuth ; avec Auth0, Auth0 OAuth ; et ainsi de suite.

Choisissez le template qui correspond à votre cas d’usage, puis lancez :

bash
1
npm create cloudflare@latest -- my-mcp-server-google-auth --template=cloudflare/ai/demos/remote-mcp-google-oauth cd my-mcp-server-google-auth npx wrangler@latest deploy

La différence principale entre les templates Google et GitHub se trouve en fait dans le fichier src/index.ts, où le defaultHandler pointe sur le GithubHandler :

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
import GitHubHandler from "./github-handler";
export default new OAuthProvider({
apiHandlers: {
// Deprecated SSE protocol - use /mcp instead
"/sse": MyMCP.serveSSE("/sse"),
"/mcp": MyMCP.serve("mcp") // Streamable-HTTP protocol
},
defaultHandler: GitHubHandler,
authorizeEndpoint: "/authorize",
tokenEndpoint: "/token",
clientRegistrationEndpoint: "/register"
});

Pour utiliser Google comme IdP (fournisseur d’identité), il faut créer une app Google OAuth : une pour le développement local, une pour la production.

  1. Allez sur Google Cloud Console

  2. Puis APIs & Services → OAuth consent screen → configurez nom, email, scopes.

  3. Allez dans Credentials → Create Credentials → OAuth Client ID.

  4. Définissez les secrets en local :

    .dev.vars
    typescript
    1
    2
    GOOGLE_CLIENT_ID="your-client-id"
    GOOGLE_CLIENT_SECRET="your-client-secret"
  5. Lancez et testez en local

    bash
    1
    npm start

    Votre serveur MCP tourne alors sur http://localhost:8788/sse

  6. Déboguez le serveur MCP (local et distant)

    Utilisez MCP Inspector, un client MCP interactif qui liste les outils découverts et permet de les invoquer depuis un navigateur.

    bash
    1
    npx @modelcontextprotocol/inspector@latest

    Rendez-vous sur http://localhost:5173. Dans l’inspecteur, entrez l’URL de votre serveur MCP, http://localhost:8788/sse, puis cliquez sur Connect.
    Une page d’autorisation GitHub devrait s’afficher. Une fois autorisé, vous êtes renvoyé vers l’inspecteur et pouvez lister et invoquer les outils.

  7. Déploiement à distance

    Sans compte Cloudflare, créez-en un. Utilisez le plan gratuit.
    Installez ensuite wrangler et connectez-vous.
    Configurez les secrets puis déployez votre serveur MCP sur Cloudflare Workers (serverless) :

    bash
    1
    2
    3
    4
    5
    # Configure global secrets
    wrangler secret put -e production HCAPTCHA_SITE_KEY
    wrangler secret put -e production GITHUB_CLIENT_SECRET
    # Deploy
    wrangler deploy -e production
  8. Configurez votre IDE pour utiliser le serveur MCP distant

    claude_desktop_config.json
    bash
    1
    2
    3
    4
    5
    6
    7
    8
    {
    "mcpServers": {
    "my_cloudflare_worker_mcp": {
    "command": "npx",
    "args": ["mcp-remote","https://worker-name.account-name.workers.dev"]
    }
    }
    }

Construire des serveurs MCP Python avec FastMCP

Pour une expérience plus riche, vous pouvez utiliser jlowin/fastmcp, qui apporte des fonctionnalités supplémentaires et une approche plus pythonique.

Commencez par ajouter FastMCP comme dépendance :

bash
1
2
uv add fastmcp
# or use uv pip install fastmcp

Créez un serveur FastMCP en instanciant la classe FastMCP, dans un fichier server.py :

python
1
2
3
from fastmcp import FastMCP, Tool # FastMCP 2.0 syntax
mcp = FastMCP("DocumentMCP")

Pour ajouter un outil, écrivez une fonction et décorez-la avec @mcp.tool pour l’enregistrer auprès du serveur MCP.
Implémentons un outil qui lit un document à partir d’un paramètre doc_id, validé avec pydantic :

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from fastmcp import FastMCP, Tool # FastMCP 2.0 syntax
from pydantic import BaseModel, Field
class DocumentQuery(BaseModel):
doc_id: str = Field(description="ID of the document to retrieve")
mcp = FastMCP("DocumentMCP")
@mcp.tool
def read_document(query: DocumentQuery) -> str:
"""
Read the contents of a document and return it as a string.
"""
# Implementation here
return f"Content of document {query.doc_id}"
if __name__ == "__main__":
mcp.run() # Uses STDIO transport by default

Utiliser Streamable HTTP

Par défaut, votre serveur MCP est seulement local : il utilise le protocole Standard IO. Remplacez-le par Streamable HTTP :

python
1
mcp.run(transport="http", host="127.0.0.1", port=8000)

Lancez votre application avec la CLI FastMCP :

bash
1
fastmcp run server.py

Votre serveur est maintenant accessible sur http://localhost:8000/mcp/.

Utiliser run_async() dans les fonctions async

mcp.run() n’est en réalité qu’un wrapper synchrone autour de la logique asynchrone.
Si votre application tourne déjà dans un contexte async, utilisez run_async() :

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from fastmcp import FastMCP
import asyncio
mcp = FastMCP(name="MyServer")
@mcp.tool
def hello(name: str) -> str:
return f"Hello, {name}!"
async def main():
# Use run_async() in async contexts
await mcp.run_async(transport="http", port=8000)
if __name__ == "__main__":
asyncio.run(main())

Ajouter des tests unitaires

Pour tester votre serveur MCP, créez un fichier de tests pytest dans tests/test_server.py qui :

  • instancie un Client depuis votre MCP. Les clients étant asynchrones, il faut passer par asyncio.run pour les lancer.

  • pour utiliser le client, il faut entrer dans un contexte avec async with client:

Lancez les tests avec pytest.

python
1
2
3
4
5
6
7
8
9
10
11
import pytest
import asyncio
from fastmcp import Client
from server import mcp
@pytest.mark.asyncio
async def test_read_document():
client = Client(mcp)
async with client:
result = await client.call_tool("read_document", {"doc_id": "123"})
assert "Content of document 123" in result

Ajouter des retours d’erreur explicites

Gérez les erreurs en renvoyant des codes d’erreur JSON-RPC :

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@mcp.tool
def update_document(
doc_id: str = Field(description="ID of the document to update"),
content: str = Field(description="New content for the document")
):
try:
# Implementation here
return {"success": True, "message": f"Document {doc_id} updated successfully"}
except KeyError:
# Return a structured error response
return {
"error": {
"code": -32003,
"message": f"Document with ID {doc_id} not found",
"data": {"requested_id": doc_id}
}
}

Packager votre serveur MCP Python

Pour partager facilement votre serveur MCP, vous pouvez le packager en paquet Python :

  1. Créez un module __init__.py :
  • src/my_custom_mcp/__init__.py
    python
    1
    from .server import mcp
  • Définissez les métadonnées du paquet dans pyproject.toml

  • Buildez et publiez :

  • python
    1
    2
    3
    4
    5
    6
    pip install build
    python -m build
    # Use Twine, a utility to publish to PyPI
    pip install twine
    # Publish to PyPI (this will ask for a PyPI API token)
    twine upload dist/*
  • Les utilisateurs peuvent ensuite brancher votre paquet dans leur IDE :

    claude_desktop_config.json
    python
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "mcpServers": {
    "my_custom_mcp": {
    "command": "uvx",
    "args": [
    "server"
    ]
    }
    }
    }

Ajouter des health checks

Pour surveiller votre serveur MCP, ajoutez des endpoints de santé via les routes custom de FastMCP :

python
1
2
3
4
5
from starlette.responses import JSONResponse
@mcp.custom_route("/health", methods=["GET"])
async def health_check(request):
return JSONResponse({"status": "healthy", "service": "mcp-server"})

L’endpoint de santé est servi sur http://localhost:8000/health et peut servir à redémarrer votre serveur en cas de panne.

Ajouter l’authentification

Si votre serveur MCP est accessible à distance, l’authentification est obligatoire. FastMCP la rend très simple : il supporte OAuth, les Bearer tokens et JWT.

Pour implémenter OAuth 2.1, on va utiliser RemoteAuthProvider pour s’authentifier sur Auth0. Ça va :

  • ajouter les endpoints well known /{ISSUER}/.well-known/jwks.json

  • appliquer une configuration CORS adaptée au fournisseur OAuth

Note : j’ai vu que tadata a sorti la bibliothèque fastapi_mcp pour implémenter ces changements.
Restez sur fastmcp, en suivant les standards du framework.

Une implémentation minimale ressemble à ça :

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from fastmcp import FastMCP
from fastmcp.server.auth import RemoteAuthProvider
from fastmcp.server.auth.providers.jwt import JWTVerifier
from pydantic import AnyHttpUrl
import os
AUTH0_DOMAIN = os.getenv("AUTH0_DOMAIN", "your-tenant.us.auth0.com")
AUTH0_AUDIENCE = os.getenv("AUTH0_AUDIENCE", "https://your-api-identifier")
RESOURCE_SERVER_URL = os.getenv("RESOURCE_SERVER_URL", "https://your-domain.example.com/mcp")
# Configure JWT verification
token_verifier = JWTVerifier(
jwks_uri=f"https://{AUTH0_DOMAIN}/.well-known/jwks.json",
issuer=f"https://{AUTH0_DOMAIN}/",
audience=AUTH0_AUDIENCE
)
# Wire OAuth to MCP
auth = RemoteAuthProvider(
token_verifier=token_verifier,
authorization_servers=[AnyHttpUrl(f"https://{AUTH0_DOMAIN}/")],
resource_server_url=RESOURCE_SERVER_URL
)
mcp = FastMCP(name="Protected MCP Server", auth=auth)
@mcp.tool
def hello(name: str) -> str:
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run(transport="http", host="0.0.0.0", port=8000)

Configurer une application Auth0

  1. Créez une application dans le dashboard Auth0.

  2. Enregistrez une API (votre serveur MCP) dont l’identifiant correspond à AUTH0_AUDIENCE.

  3. Activez l’enregistrement dynamique de client OIDC.

  4. Positionnez la Default Audience sur l’identifiant de votre API.

Ainsi, n’importe quel client MCP peut obtenir des jetons et s’authentifier correctement.

Depuis Auth0, vous pouvez aussi activer Google OAuth.

  • Dans le dashboard Auth0 : Authentication → Social → Google OAuth.

  • Dans Applications, activez le toggle pour votre application.

  • Enregistrez les changements.

Déployer votre serveur FastMCP

Une fois Auth0 configuré :

  • Déployez le serveur chez votre hébergeur (Render, Fly.io ou votre propre infrastructure).
    Sur Render, par exemple : créez une web app et utilisez son intégration GitHub en connectant votre dépôt.

  • Définissez les variables d’environnement (AUTH0_DOMAIN, AUTH0_AUDIENCE, RESOURCE_SERVER_URL).

Votre serveur MCP protégé par OAuth est en ligne. Tout client MCP qui s’y connecte passe par le flux OAuth, récupère un access token et peut ensuite appeler outils et ressources en sécurité.

Transformer des agents existants en serveurs MCP avec auto-mcp

Si vous avez construit une app avec un framework d’agents (CrewAI, OpenAI…), vous pouvez utiliser Naphta auto-mcp pour créer un adaptateur pour vos classes d’agents existantes.

Note : si vous êtes sur CrewAI, ils proposent une intégration MCP directe avec l’MCPServerAdapter des crewai-tools, voir cet article de Plaban Nayak.

Laissez automcp générer un fichier run_mcp.py pour configurer votre agent :

bash
1
2
3
uv add naptha-automcp
automcp init -f <framework>
# expected agent flag: crewai, langgraph, llamaindex, openai, pydantic, mcp_agent

Mettez à jour le fichier run_mcp.py généré pour utiliser votre classe d’agent :

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Replace these imports with your actual agent classes
from your_module import YourCrewClass
# Define the input schema
class InputSchema(BaseModel):
parameter1: str
parameter2: str
# Set your agent details
name = "<YOUR_AGENT_NAME>"
description = "<YOUR_AGENT_DESCRIPTION>"
# For CrewAI projects
mcp_crewai = create_crewai_adapter(
orchestrator_instance=YourCrewClass().crew(),
name=name,
description=description,
input_schema=InputSchema,
)

Installez les dépendances puis lancez votre serveur MCP :

python
1
automcp serve -t sse

Votre serveur MCP tourne et n’expose qu’un seul outil MCP : votre agent.

Conclusion

On a fait le tour des fondamentaux du Model Context Protocol (MCP) et de son écosystème.
Il fait passer d’une approche centrée API à une approche interactive avec l’agent, dans un paradigme orienté objectif.
C’est moins granulaire, mais plus guidé par le but : les outils atomiques laissent place à des méta-outils « recette ».

Les serveurs MCP peuvent s’écrire dans n’importe quel langage : c’est juste l’implémentation d’un protocole. Cherchez des frameworks pour faire le gros du travail, par exemple les templates Cloudflare Workers pour TypeScript et FastMCP pour Python.

Sécurité et observabilité ne sont pas un plus. Les frameworks aident à mettre en place l’authentification, mais il faut gérer les erreurs explicitement et ajouter de la traçabilité dès que votre MCP est distant.

Quelques mots sur l’évolution des MCP

De nouveaux outils apparaissent sans arrêt, et les ressources curatées n’en finissent plus de s’allonger.

Les bonnes pratiques émergent et les frameworks évoluent : la qualité générale des serveurs MCP s’améliore et les standards se resserrent. La plupart des plugins MCP sont pourtant codés sans framework, sur des stacks qui ne tiennent qu’à « Claude » ou « Windsurf », ce qui expose des communautés entières. Voir l’article « We Urgently Need Privilege Management in MCP: A Measurement of API Usage in MCP Ecosystems ».

J’adorerais savoir comment vous construisez vos serveurs MCP, et quand ils sont distants, comment vous les partagez pour que votre équipe les utilise.

Sources

Comments (0)

Log in to leave a comment.

No comments yet. Be the first!

0

Launcher