Hébergement MCP sur Cloudflare : Code Mode, Server Portals et installation
Déployez un serveur MCP distant sur Cloudflare Workers avec McpAgent et OAuth, réduisez le contexte des outils grâce au schéma recherche et exécution de Code Mode, puis regroupez vos serveurs derrière un MCP Server Portal avec des politiques Zero Trust Access, un filtrage des outils et des journaux d’accès.
Votre serveur Model Context Protocol (MCP) fonctionne très bien sur votre ordinateur portable. Puis un collègue vous demande l’URL, un second éditeur doit l’utiliser sur une autre machine, et quelqu’un de la sécurité demande qui peut appeler quel outil. Un processus local ne peut répondre à aucune de ces questions. Cloudflare vous propose trois briques pour ce cas : Workers pour héberger le serveur, Code Mode pour réduire ce que le modèle doit lire, et MCP Server Portals pour placer chaque serveur derrière une porte unique et contrôlée. Vous trouverez ci-dessous chaque brique dans l’ordre, avec les commandes, la configuration et les pièges qui comptent, afin de passer d’un dossier vide à une installation gouvernée sans avancer à l’aveugle.
Pourquoi héberger MCP sur Cloudflare
Les serveurs locaux atteignent un plafond
Un serveur stdio est un processus enfant d’un seul client, sur une seule machine. Cela fonctionne pour un projet de week-end. Cela cesse de fonctionner dès qu’une deuxième personne arrive : chacun installe sa propre copie, les secrets restent dans des fichiers de configuration locaux, et personne ne voit quels outils sont appelés. Un serveur distant règle chacun de ces problèmes. Vous disposez d’une seule URL, d’un seul déploiement et d’un seul endroit où lire les journaux.
Le local reste préférable dans un cas : un outil qui touche aux fichiers de la machine d’une seule personne, comme un dossier de notes privées. L’hébergement distant est destiné aux outils que plusieurs personnes ou plusieurs agents partagent.
Ce qu’apportent Workers
Workers exécute votre code sur le réseau edge de Cloudflare, au plus près de celui qui appelle. Pour MCP en particulier, Cloudflare fournit trois briques :
McpAgent, une classe du SDK Agents qui gère le transport distant. Le SDK sert Streamable HTTP à votre place.
workers-oauth-provider, une bibliothèque OAuth 2.1 qui enveloppe votre Worker et ajoute l’autorisation à ses points de terminaison, y compris les points de terminaison MCP.
mcp-remote, un adaptateur qui permet aux clients ne parlant que stdio de se connecter à un serveur distant.
Besoin
Serveur stdio local
Serveur distant sur Workers
Qui peut l’utiliser
Une seule machine
Toute personne disposant de l’URL et d’un identifiant
Mise à jour
Réinstallation sur chaque machine
Un seul wrangler deploy
Secrets
Fichiers de configuration locaux
Secrets de Worker
État par session
Mémoire du processus
Durable Objects
Visibilité
Aucune intégrée
Journaux d’accès du portail
💡 À retenir : distant ne veut pas dire public. Traitez l’URL comme une API exposée sur Internet dès le premier déploiement.
Déployer votre premier serveur distant
Démarrer à partir du modèle
Cloudflare maintient un modèle pour un serveur sans connexion, qui est le moyen le plus rapide de voir les pièces en mouvement :
npm create cloudflare@latest -- my-mcp-server --template=cloudflare/ai/demos/remote-mcp-authless
cd my-mcp-server
npm start
Votre serveur écoute désormais localement à l’adresse http://localhost:8788/mcp. Rien d’autre à installer.
Écrire la classe McpAgent
Le cœur du projet est une classe qui étend McpAgent. Vous enregistrez les outils dans init(), exactement comme avec le SDK TypeScript officiel :
import { McpAgent } from "agents/mcp";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
export class MyMCP extends McpAgent {
server = new McpServer({ name: "math", version: "1.0.0" });
async init() {
this.server.tool("add", { a: z.number(), b: z.number() }, async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }],
}));
}
}
export default MyMCP.serve("/mcp");
Cette classe est aussi un Durable Object, ce qui explique pourquoi la configuration du projet déclare un binding et une migration pour elle. Les Durable Objects donnent à chaque session MCP son propre état, sans base de données de votre côté. Si vos outils ne renvoient que des résultats purs, vous n’aurez jamais à toucher à cet état. Dès que vous suivez un panier, un brouillon ou une longue conversation, vous serez content qu’il existe.
Tester et mettre en production
Lancez le MCP Inspector dans un second terminal et pointez-le vers l’URL locale :
npx @modelcontextprotocol/inspector@latest
Appelez votre outil depuis son interface web. Quand il se comporte correctement, déployez :
npx wrangler@latest deploy
Votre serveur est alors en ligne à l’adresse https://my-mcp-server.<your-account>.workers.dev/mcp. Les clients qui ne parlent que stdio, comme Claude Desktop, se connectent via l’adaptateur :
Vous pouvez aussi coller l’URL dans le Cloudflare AI Playground ou dans l’Inspector pour tester la version déployée.
Ajouter une connexion avec OAuth
Un serveur sans authentification convient à une démonstration, mais c’est une mauvaise idée dès qu’il touche à de vraies données. Le second modèle de Cloudflare intègre GitHub comme fournisseur d’identité :
La mise en place tient en une courte liste de contrôle :
Enregistrez deux applications OAuth GitHub, une pour le développement local et une pour la production, afin qu’un secret de développement divulgué ne touche jamais la production.
Stockez les identifiants comme secrets de Worker avec npx wrangler secret put GITHUB_CLIENT_ID et npx wrangler secret put GITHUB_CLIENT_SECRET, ainsi que le secret de chiffrement des cookies indiqué dans le README du modèle.
Créez le magasin de sessions avec npx wrangler kv namespace create "OAUTH_KV".
Collez l’identifiant de namespace renvoyé dans wrangler.jsonc, puis déployez.
En coulisses, workers-oauth-provider enveloppe votre Worker, si bien que vos outils reçoivent des informations d’utilisateur déjà authentifiées sous forme de paramètre. Vous n’écrivez pas vous-même les vérifications de jetons, et c’est tout l’intérêt.
💡 Astuce : GitHub n’est qu’une option. La même bibliothèque peut se placer devant n’importe quel fournisseur d’identité OAuth, ce qui compte dès que vous prévoyez de placer le serveur derrière un portail.
Comment Code Mode réduit les coûts en tokens
De longues listes d’outils consomment le contexte
Chaque définition d’outil que vous exposez est un texte que le modèle doit lire avant de faire quoi que ce soit d’utile. C’est gérable avec dix outils. Cela s’effondre avec une plateforme entière. Cloudflare indique que l’exposition de son API, qui compte plus de 2 500 points de terminaison, sous forme d’outils MCP classiques représenterait plus de 1,17 million de tokens. Avec Code Mode, la même couverture tient en environ 1 000 tokens.
Il existe un second coût, moins souvent mentionné. Dans une boucle classique d’appels d’outils, chaque résultat intermédiaire repasse par le modèle. Si l’étape deux a besoin de la sortie de l’étape un, le modèle la lit, la reformule et la transmet. Code Mode permet au modèle d’écrire à la place un court programme. Les appels dépendants s’exécutent dans le sandbox, les données intermédiaires y restent, et seule la réponse finale revient dans la conversation. Moins d’allers-retours signifie moins de texte à lire et moins de risques de recopier une valeur de travers.
Recherche et exécution en pratique
Le modèle pour les grandes API, openApiMcpServer(), n’expose que deux outils :
search exécute un code écrit par le modèle sur un document OpenAPI, dans un sandbox, et ne renvoie que les opérations, paramètres ou schémas nécessaires à la tâche.
execute exécute un code écrit par le modèle avec une fonction de requête authentifiée que fournit votre Worker.
Comme l’indique la documentation, seul le sous-ensemble renvoyé entre dans le contexte du modèle. Le modèle pose une question précise, obtient une réponse précise, puis agit.
Prenons une demande du type liste les enregistrements DNS de ma zone. Le modèle écrit d’abord un petit extrait pour search qui filtre les chemins OpenAPI jusqu’aux opérations DNS, et obtient une poignée de correspondances au lieu de milliers. Il écrit ensuite un extrait pour execute qui appelle la bonne opération via votre fonction de requête et ne renvoie que les champs dont il a besoin. Deux courts allers-retours remplacent une liste d’outils de la taille d’un annuaire téléphonique.
Pour en créer un, il vous faut un projet Workers, un document OpenAPI 3.x et une méthode côté hôte pour authentifier les requêtes.
Le sandbox contient le code
Le code écrit par le modèle s’exécute dans un Worker isolé, et l’accès réseau sortant direct est bloqué par défaut. Le code généré ne peut atteindre le monde extérieur que via les outils MCP en amont ou la fonction de rappel de requête que vous fournissez. C’est une valeur par défaut solide, mais elle ne gère pas l’autorisation à votre place :
Appliquez les permissions dans vos gestionnaires d’outils ou dans la fonction de rappel de requête, avant tout effet de bord.
Ne placez jamais d’identifiants dans les résultats d’outils ni dans le document OpenAPI.
Considérez la fonction de rappel comme le seul endroit où une mauvaise requête peut réellement causer des dégâts.
Choisir le bon schéma
codeMcpServer()
openApiMcpServer()
Idéal pour
Envelopper un serveur MCP existant avec un ensemble d’outils gérable
Les grands catalogues d’API
Ce que voit le modèle
Un seul outil code avec les définitions TypeScript de chaque opération en amont
Deux outils : search et execute
Comment les appels ont lieu
Via un namespace codemode, si bien que les appels dépendants se composent dans le sandbox
Les opérations sélectionnées sont appelées via une fonction de requête fournie par l’hôte
Coût en contexte
Augmente avec le nombre d’outils en amont
Borné, car seuls les résultats de search reviennent
💡 Règle empirique : enveloppez ce que vous avez déjà avec codeMcpServer(). Tournez-vous vers openApiMcpServer() lorsque votre liste d’outils ressemble à un catalogue plutôt qu’à une boîte à outils.
Mettre en place un MCP Server Portal
Les MCP Server Portals sont sortis en bêta ouverte en août 2025, dans le cadre de Cloudflare One. L’idée est simple : faire passer chaque requête MCP par un point de terminaison de portail unique, y appliquer des politiques Zero Trust, et tout journaliser.
Vérifier d’abord les prérequis
Avant d’ouvrir le tableau de bord, vérifiez trois points :
Vous disposez d’un domaine Cloudflare actif, avec une configuration complète ou partielle (CNAME).
Un fournisseur d’identité est configuré dans Cloudflare Zero Trust.
Vos serveurs sont accessibles en HTTP. Les serveurs uniquement stdio ne sont pas pris en charge, sauf si vous les enveloppez. Un portail accepte jusqu’à 80 serveurs.
Ajouter les serveurs, puis créer le portail
Dans le tableau de bord, allez dans Zero Trust > Access controls > MCP Portals et ouvrez l’onglet MCP servers.
Sélectionnez Add MCP server. Saisissez un nom, un Server ID personnalisé facultatif, l’URL HTTP complète du serveur et les politiques Access qui déterminent qui le voit.
Pour les serveurs compatibles OAuth, utilisez l’enregistrement dynamique de client automatique (recommandé) ou saisissez les identifiants manuellement. Ajoutez l’URL de rappel du tableau de bord à la liste d’autorisation de votre fournisseur OAuth.
De retour sur la page MCP Portals, sélectionnez Add MCP server portal. Définissez un nom, un domaine personnalisé avec un sous-domaine facultatif, les serveurs à rattacher et les politiques d’accès pour les utilisateurs.
Connectez les clients à https://<subdomain>.<domain>/mcp.
Un serveur n’apparaît dans le portail que pour les personnes qui correspondent à une politique Allow. Les intitulés des menus peuvent changer pendant qu’une fonctionnalité est en bêta, alors fiez-vous au tableau de bord actuel plutôt qu’à une capture d’écran.
Réduire les outils et définir l’authentification
Dans les paramètres du portail, vous pouvez désactiver le bouton à côté de n’importe quel outil ou prompt que vous voulez masquer. Chaque serveur affiche un compteur Tools authorized qui vous indique combien d’outils vous exposez. Quelques contrôles méritent d’être connus :
Require user auth détermine si les personnes se connectent avec leurs propres identifiants ou si l’identifiant administrateur gère l’accès.
Namespacing affiche les outils sous la forme {server_id}_{tool_name}, si bien que deux serveurs peuvent avoir chacun un outil search sans conflit.
Aliases renomme les outils et les prompts au niveau du portail ou du serveur.
Code Mode peut être activé pour le portail afin de réduire la consommation de tokens.
Gateway routing peut ajouter une inspection DLP facultative pour les données sensibles.
Lire les journaux d’accès
Les journaux du portail enregistrent l’heure, le statut, le nom du serveur, la capacité et la durée, par portail ou par serveur. Ils peuvent être exportés avec Logpush vers un stockage tiers ou un SIEM. Pour un déploiement en équipe, c’est là que vous répondez à la question posée par la sécurité dans le premier paragraphe : qui a appelé quoi, et quand.
Un ordre de déploiement qui limite les mauvaises surprises :
Déployez un serveur avec OAuth et testez-le dans l’Inspector.
Ajoutez-le à un portail avec une politique Allow réservée à un groupe pilote.
Désactivez tout outil dont le groupe pilote n’a pas besoin.
Vérifiez les journaux après quelques jours, à la recherche d’appelants inattendus ou d’appels en échec.
Élargissez la politique, puis rattachez le serveur suivant.
Les erreurs qui coûtent des heures
Partager l’URL workers.dev sans connexion. Elle fonctionne, et c’est précisément le danger. Ajoutez OAuth avant que quiconque en dehors de votre machine ne voie l’adresse.
Une politique Allow vide. Les utilisateurs qui se connectent au portail et voient le message « No allowed servers available, check your Zero Trust Policies » n’ont presque toujours pas de politique Allow correspondante sur le portail ou sur le serveur.
Oublier l’URL de rappel. Les serveurs compatibles OAuth ne se connectent pas tant que l’URL de rappel du tableau de bord n’est pas dans la liste d’autorisation de votre fournisseur.
Placer des identifiants là où le modèle peut les lire. Avec Code Mode, tout ce qui se trouve dans un résultat d’outil ou dans le document OpenAPI est visible par le code écrit par le modèle.
Compter sur stdio dans un portail. Enveloppez d’abord le serveur derrière HTTP, ou hébergez-le sur Workers.
Sauter l’étape de l’Inspector. Un outil qui fonctionne dans votre éditeur peut encore échouer sur l’URL déployée. Testez le point de terminaison /mcp en production avant de l’ajouter à un portail.
💡 Test rapide : ouvrez le portail en tant qu’utilisateur qui ne figure pas dans votre politique Allow. Si vous voyez un serveur, votre politique est incorrecte.
Associer le tout aux modèles PicassoIA
Choisir un modèle pour le client
Quel que soit le client qui appelle votre serveur, il lui faut un modèle performant derrière. Ces modèles de langage PicassoIA valent tous la peine d’être testés avec vos outils :
Ils sont aussi utiles avant tout déploiement : demandez à l’un d’eux de rédiger les descriptions d’outils, d’écrire le TypeScript que vous fourniriez à Code Mode, ou de relire votre document OpenAPI pour repérer les opérations que vous préféreriez ne pas exposer.
Ajouter des outils d’image à votre serveur
Un Worker peut appeler n’importe quelle API HTTP, donc un outil MCP peut appeler celle de PicassoIA. La PicassoIA API se trouve à https://api.picassoia.com/v1, accepte un jeton d’accès (bearer) qui commence par pia_sk_, et suit un modèle inspiré de Replicate : POST /v1/models/{owner}/{name}/predictions crée une tâche et GET /v1/predictions/{id} lit son statut. Les tâches sont asynchrones, et un compte peut lancer jusqu’à 5 prédictions simultanément.
Cette structure se traduit naturellement en deux outils : l’un qui lance une génération et renvoie un identifiant, et l’autre qui interroge le résultat. Stockez le jeton avec npx wrangler secret put PICASSOIA_API_TOKEN, et ne l’affichez jamais dans un résultat d’outil. Si vous préférez ne rien construire, PicassoIA propose aussi sa propre connexion MCP, qui donne directement à votre client les mêmes modèles d’image et de vidéo.
Essayez-le sur PicassoIA dès aujourd’hui
Vous avez maintenant le parcours complet : un Worker qui sert MCP, OAuth devant lui, Code Mode pour garder un contexte réduit, et un portail pour tout gouverner. La récompense la plus rapide consiste à faire faire quelque chose de visuel à votre serveur.
Ouvrez Seedream 5 Pro, GPT Image 2 ou FLUX 2 Pro et rédigez un prompt pour la photo que vous auriez voulu avoir pour votre dernier projet. Poussez ensuite plus loin avec Seedance 2.0 ou Veo 3.1 Fast pour transformer l’image fixe en mouvement. Expérimentez la lumière, l’objectif et l’angle jusqu’à ce que le résultat ressemble à un vrai tournage.
Chaque modèle est listé à l’adresse picassoia.com/en/all-models. Choisissez-en un, lancez un prompt et voyez ce qui en ressort.