Tunnel MCP ChatGPT : connecter un serveur MCP local à ChatGPT
ChatGPT ne peut pas joindre localhost : un serveur MCP local a donc besoin d’un tunnel. Voici les commandes exactes pour ngrok et Cloudflare, le formulaire de connecteur en mode développeur, les erreurs qui bloquent un premier appel d’outil, les bonnes habitudes pour protéger une URL publique, et les cas où un serveur hébergé vaut mieux qu’un tunnel.
Votre serveur MCP fonctionne parfaitement sur localhost:3000. Puis vous collez cette adresse dans ChatGPT et une erreur apparaît. Rien ne cloche dans votre code. ChatGPT vit dans le cloud d’OpenAI, et votre ordinateur portable se trouve derrière un routeur qui ne l’a jamais invité. Un tunnel MCP ChatGPT comble ce fossé : un petit programme sur votre machine ouvre une connexion sortante vers un relais, le relais vous fournit une adresse HTTPS publique, et chaque requête envoyée par ChatGPT à cette adresse redescend par la connexion jusqu’à votre serveur local.
Cet article suit l’ordre dans lequel vous travaillerez réellement : ce que ChatGPT exige d’un serveur MCP distant, un petit serveur qui vaut la peine d’être testé, deux options de tunnel avec les commandes exactes, le formulaire de connecteur dans ChatGPT, les erreurs qui font perdre un après-midi, et les habitudes qui empêchent une URL publique de devenir un risque. Il vous faut au plus un compte de tunnel gratuit, et rien de plus qu’un ordinateur portable ordinaire.
💡 En bref : servez votre point de terminaison MCP en Streamable HTTP, dirigez un tunnel vers ce port, collez https://<your-tunnel-host>/mcp dans le formulaire de connecteur du mode développeur de ChatGPT, et gardez les deux processus actifs pendant que vous discutez.
Pourquoi ChatGPT ne peut pas atteindre localhost
Uniquement des serveurs distants
Les connecteurs ChatGPT sont conçus pour des serveurs accessibles sur l’internet public. Un serveur qui parle stdio, le transport où un client de bureau lance votre programme comme processus enfant, ne peut pas fonctionner ici, car ChatGPT n’a aucun moyen de démarrer un processus sur votre ordinateur. Ce qu’il peut faire, c’est appeler un point de terminaison HTTPS, et la documentation d’OpenAI cite à la fois Server-Sent Events et Streamable HTTP comme protocoles pris en charge. Choisissez Streamable HTTP, sauf raison particulière : il a remplacé l’ancien transport HTTP plus SSE dans la spécification du Model Context Protocol, et c’est ce que recommandent les SDK actuels.
Il existe une seconde raison, plus simple, à l’échec de localhost. Ce mot désigne « cette machine » pour celui qui le lit. Quand ChatGPT tente http://localhost:3000, il regarde ses propres serveurs, ne trouve rien sur le port 3000, et abandonne.
Ce que fait réellement un tunnel
Un tunnel inverse le sens de la connexion. Votre machine appelle le fournisseur de tunnel, ce que tous les routeurs domestiques et la plupart des pare-feux d’entreprise autorisent, et maintient cette connexion ouverte. Le fournisseur possède un nom d’hôte public avec un certificat TLS valide et fait descendre les requêtes entrantes par la connexion ouverte. En pratique, une requête suit cinq étapes :
ChatGPT envoie une requête à https://abc123.ngrok-free.app/mcp.
Le point d’entrée du fournisseur la reçoit et trouve votre session ouverte.
La requête descend jusqu’au client de tunnel sur votre ordinateur portable.
Le client la transmet à http://localhost:3000/mcp.
La réponse de votre serveur revient par le même chemin.
Par rapport à la redirection de ports classique, vous évitez les réglages du routeur, le DNS dynamique et le renouvellement des certificats. Vous gagnez aussi un interrupteur : fermez le tunnel et l’adresse publique cesse immédiatement de fonctionner.
Ce qu’il faut préparer en premier
Forfait et mode développeur
Les connecteurs personnalisés pour serveurs MCP distants se trouvent derrière le mode développeur. La documentation d’OpenAI le réserve aux comptes Plus, Pro, Business, Enterprise et Education sur le web. Sur les forfaits d’espace de travail, un administrateur doit parfois l’autoriser au préalable, donc vérifiez cela avant de blâmer votre serveur.
Les noms des menus changent d’une version à l’autre. Aujourd’hui, l’interrupteur se trouve dans Paramètres, dans la section Apps, sous la forme d’un bouton Mode développeur situé vers le bas. Les anciennes versions le plaçaient sous Connecteurs. Si vous ne le trouvez pas, cherchez le mot « développeur » dans le panneau des paramètres.
Exigence
Ce que cela signifie en pratique
Forfait ChatGPT
Plus, Pro, Business, Enterprise ou Education, utilisé sur le web
URL HTTPS publique qui se termine par la route MCP, généralement /mcp
Authentification
OAuth, ou aucune authentification pour un test jetable
Tunnel
ngrok, Cloudflare Tunnel ou Tailscale Funnel
Processus actifs
Votre serveur et le tunnel, tous deux actifs pendant la conversation
Un serveur Streamable HTTP minimal
Il vous faut quelque chose de petit pour tester le tunnel. Ce serveur TypeScript expose un seul outil, en mode sans état, donc il n’y a aucune session à perdre lorsque vous le redémarrez. Installez d’abord les dépendances :
import express from "express";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { z } from "zod";
const app = express();
app.use(express.json());
function buildServer() {
const server = new McpServer({ name: "local-notes", version: "1.0.0" });
server.tool(
"add_numbers",
"Use this when the user asks to add two numbers together.",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({ content: [{ type: "text", text: String(a + b) }] })
);
return server;
}
app.post("/mcp", async (req, res) => {
const server = buildServer();
const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
res.on("close", () => {
transport.close();
server.close();
});
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
app.listen(3000, "127.0.0.1", () => console.log("MCP on http://127.0.0.1:3000/mcp"));
Lancez-le avec npx tsx server.ts. Trois détails comptent. D’abord, la route est /mcp, et ce chemin exact se retrouve dans le formulaire de ChatGPT. Ensuite, sessionIdGenerator: undefined rend chaque requête indépendante, ce qui convient à un tunnel susceptible de redémarrer. Enfin, la description de l’outil commence par « Use this when », une habitude qui aide ChatGPT à choisir le bon outil, puisqu’il les sélectionne en lisant ces phrases.
Avant même qu’un tunnel existe, vérifiez que le serveur répond à une poignée de main :
Vous devez voir un HTTP 200 et une réponse mentionnant local-notes. Si cela échoue en local, aucun tunnel ne le corrigera.
Ouvrir le tunnel
ngrok en deux commandes
Installez ngrok avec brew install ngrok sur macOS, ou utilisez l’installateur du site de ngrok sous Windows et Linux. Ajoutez ensuite le token de votre tableau de bord et lancez le tunnel :
Le terminal affiche une ligne de redirection telle que https://abc123.ngrok-free.app -> http://localhost:3000. Ajoutez /mcp et vous obtenez l’URL de votre connecteur. ngrok propose aussi un inspecteur local à http://127.0.0.1:4040 qui répertorie chaque requête et chaque réponse, le moyen le plus rapide de voir ce que ChatGPT a réellement envoyé.
Par défaut, l’adresse change à chaque redémarrage du tunnel. Réservez un domaine statique gratuit dans le tableau de bord ngrok, puis lancez ngrok http --url=your-name.ngrok-free.app 3000 (les anciennes versions du client utilisent --domain) : l’URL du connecteur survit aux redémarrages et vous cessez de la modifier chaque matin.
Cloudflare Quick Tunnel
Si vous préférez Cloudflare, installez cloudflared et lancez une seule commande :
cloudflared tunnel --url http://localhost:3000
Il affiche une adresse du type https://random-words.trycloudflare.com. Les quick tunnels ne demandent aucun compte, et c’est à la fois leur atout et leur limite : le nom d’hôte change à chaque exécution, donc vous le recollez dans ChatGPT à chaque fois. Des développeurs signalent aussi que les quick tunnels peuvent peiner avec Server-Sent Events, ce qui fait de Streamable HTTP le couple le plus sûr. Pour une adresse permanente, créez un tunnel nommé rattaché à un domaine que vous possédez.
Choisir le bon tunnel
Option
Effort de configuration
Stabilité de l’adresse
Idéal pour
Compte gratuit ngrok
Compte plus token
Aléatoire, sauf si vous réservez un domaine statique
Un premier test rapide
Cloudflare quick tunnel
Une commande, sans connexion
Nouvelle à chaque exécution
Démos jetables
Cloudflare tunnel nommé
Domaine plus connexion
Stable
Usage quotidien
Tailscale Funnel
Tailscale installé
Nom d’hôte stable sous votre tailnet
Configurations déjà sur Tailscale
Pour un premier test, prenez ngrok ou un quick tunnel. Pour un usage quotidien, une adresse stable compte davantage que n’importe quelle fonctionnalité de ce tableau.
Ajouter le connecteur dans ChatGPT
Activer le mode développeur
Ouvrez ChatGPT dans un navigateur et allez dans Paramètres.
Repérez l’interrupteur Mode développeur et activez-le.
Lisez l’avertissement. Un connecteur peut lire vos données et, si vous l’autorisez, modifier des éléments : ne connectez que des serveurs en lesquels vous avez confiance.
Créer l’application
À côté de l’interrupteur, cliquez sur Créer une application. Les anciennes versions nomment ce bouton Créer sous Connecteurs.
Saisissez un nom, par exemple « Notes locales ».
Rédigez une courte description de la situation dans laquelle le modèle doit l’utiliser.
Collez votre adresse publique dans URL du serveur MCP, avec la route incluse : https://abc123.ngrok-free.app/mcp. Le nom d’hôte nu sans /mcp est l’erreur la plus fréquente.
Réglez Authentification sur Aucune authentification pour un test jetable, ou sur OAuth si votre serveur l’implémente.
Cochez la case confirmant que vous faites confiance à l’application, puis cliquez sur Créer.
ChatGPT contacte maintenant votre URL, effectue la poignée de main MCP et liste les outils qu’il trouve. Voir add_numbers sur cet écran signifie que toute la chaîne fonctionne : ChatGPT, le tunnel et votre serveur.
Lancer votre premier appel d’outil
Démarrez une nouvelle conversation, ouvrez le menu +, choisissez Plus, sélectionnez Mode développeur, puis activez votre application. Posez ensuite une question qui en a besoin : « Utilisez Notes locales pour additionner 19 et 23. »
ChatGPT affiche l’appel d’outil qu’il souhaite effectuer. Les outils en lecture seule peuvent s’exécuter librement, tandis que les outils qui écrivent des données demandent une confirmation explicite. Approuvez donc l’appel et surveillez trois endroits à la fois :
La conversation : la réponse 42, avec l’appel d’outil dépliable au-dessus.
Le terminal de votre serveur : la requête entrante.
L’inspecteur ngrok : le JSON brut envoyé par ChatGPT et renvoyé par votre serveur.
Lorsque les trois concordent, vous disposez d’un tunnel MCP ChatGPT fonctionnel et d’un modèle pour chaque outil que vous ajouterez ensuite.
Corriger les erreurs que vous rencontrerez
Erreurs de connexion et chemin /mcp
Lorsque ChatGPT refuse d’enregistrer l’application ou signale qu’il n’a pas pu joindre le serveur, parcourez cette liste avant de modifier le moindre code :
Le serveur tourne-t-il ? Ouvrez le terminal où il a démarré et vérifiez qu’il est toujours actif.
Le tunnel pointe-t-il vers le même port ?ngrok http 3000 ne fonctionne que si votre serveur écoute sur le port 3000.
Le chemin correspond-il ? L’URL dans ChatGPT doit se terminer par la même route que celle enregistrée dans votre code.
Le tunnel a-t-il redémarré ? Un nouveau nom d’hôte aléatoire signifie que l’ancienne URL du connecteur ne fonctionne plus.
L’adresse est-elle en HTTPS ? ChatGPT n’accepte pas le HTTP simple.
Refaites ensuite votre test de poignée de main en local, cette fois sur l’adresse publique. S’il échoue là mais réussit sur localhost, la panne se situe entre le tunnel et votre serveur, jamais à l’intérieur de ChatGPT :
Deux problèmes ressemblent à des bogues, mais n’en sont pas.
Outils obsolètes. ChatGPT conserve la liste des outils au moment où vous créez l’application. Si vous ajoutez, renommez ou reformulez un outil, la conversation continue d’afficher l’ancienne version tant que vous n’actualisez pas le connecteur depuis sa page de réglages ou que vous ne le recréez pas. Chaque fois qu’un nouvel outil refuse d’apparaître, actualisez d’abord.
Vérifications de l’en-tête Host. Certains frameworks, et certains utilitaires des SDK MCP, valident l’en-tête Host pour bloquer les attaques par DNS rebinding. Une requête qui arrive par le tunnel transporte le nom d’hôte du tunnel à la place de localhost, si bien que votre serveur peut répondre 403 ou 421. Ajoutez le nom d’hôte du tunnel à vos hôtes autorisés. Les quick tunnels changent de nom d’hôte à chaque exécution : autorisez donc un suffixe, tel que .trycloudflare.com, plutôt que de désactiver la vérification.
Symptôme
Cause probable
Correction
Erreur à l’enregistrement de l’application
Mauvais chemin ou serveur arrêté
Lancez le test curl de la poignée de main sur l’URL publique
Fonctionnait hier, mort aujourd’hui
Nom d’hôte du tunnel modifié
Mettez à jour le connecteur ou réservez un domaine fixe
403 ou 421 de votre serveur
Validation de l’en-tête Host
Autorisez le nom d’hôte du tunnel
Nouvel outil absent de la conversation
Liste d’outils en cache
Actualisez ou recréez le connecteur
Délai dépassé lors d’un appel d’outil
Outil lent derrière le tunnel
Répondez tôt et limitez les appels à quelques secondes
Sécuriser l’ensemble
Considérer l’URL comme publique
Quiconque met la main sur l’adresse de votre tunnel peut appeler votre serveur, sauf si quelque chose l’en empêche. Un nom d’hôte aléatoire repose sur l’obscurité, pas sur une protection, et il apparaît dans les journaux, les captures d’écran et l’historique du navigateur. Utilisez OAuth sur le serveur, ou placez une couche d’accès devant le tunnel : Cloudflare Access et les politiques de trafic de ngrok existent précisément pour cela. Liez votre serveur à 127.0.0.1, comme le fait l’exemple de code, afin que seul le client de tunnel sur votre propre machine puisse l’atteindre directement.
Limiter ce que les outils peuvent écrire
Un outil est une promesse sur ce que le modèle peut faire sur votre machine. Gardez-le restreint :
Commencez par des outils en lecture seule et ajoutez les outils d’écriture un par un.
N’exposez jamais une commande shell générique ni une suppression de fichiers sans restriction.
Limitez les outils de fichiers à un seul dossier de projet.
Journalisez chaque appel avec ses arguments, pour voir ce qui s’est passé ensuite.
Traitez la sortie d’un outil comme un texte non fiable. Une page web ou un document renvoyé par votre outil peut contenir des instructions destinées au modèle, un risque connu sous le nom d’injection de prompt.
Arrêtez le tunnel avec Ctrl+C quand vous avez terminé. Une adresse publique inactive ne présente que des inconvénients.
Quand un serveur hébergé l’emporte
Un tunnel est le bon outil pour construire et déboguer. Pour un usage quotidien, un serveur hébergé supprime toute une catégorie de problèmes, car il vit déjà à une adresse publique : plus d’ordinateur à garder éveillé, plus de nom d’hôte à recoller, plus de port à oublier.
PicassoIA fonctionne ainsi côté API. Son API pour développeurs est accessible à https://api.picassoia.com/v1 avec des endpoints de style Replicate : vous créez une prédiction, vous l’interrogez, puis vous récupérez le résultat. Les connexions MCP se gèrent depuis votre compte sur picassoia.com/en/mcp/accounts après connexion, et un compte peut exécuter jusqu’à 5 prédictions simultanément, partagées entre les tokens et les connexions MCP. Consultez la page de l’API PicassoIA pour les règles d’accès en vigueur avant de bâtir dessus.
Comment utiliser GPT 5.4 sur PicassoIA
Déboguer un serveur MCP implique beaucoup de rédaction : descriptions d’outils, schémas JSON, explications d’erreurs. GPT 5.4 est un bon partenaire de rédaction pour ce travail. Voici un flux de travail adapté à cet article :
Collez le nom d’un outil, son schéma d’entrée et un objectif en une ligne. Demandez trois variantes de description commençant par « Use this when ».
Demandez au modèle de lister deux situations où ChatGPT ne devrait pas appeler cet outil, puis ajoutez ces lignes à la description.
Collez l’erreur exacte de votre terminal ou de l’inspecteur ngrok et demandez les trois causes les plus probables, classées.
Recopiez la meilleure description dans votre serveur, redémarrez-le, puis actualisez le connecteur dans ChatGPT.
Conseils sur les paramètres : collez de vrais schémas plutôt que de les décrire, changez une seule chose par prompt, et limitez chaque requête à un seul outil. Pour un second avis sur un code délicat, passez le même prompt par Claude Sonnet 5 ou GPT 5.6 Sol et comparez les réponses.
💡 Astuce : lorsque deux modèles ne s’accordent pas sur la raison de l’échec d’une requête, faites confiance à celui qui désigne une ligne que vous pouvez vérifier dans l’inspecteur ngrok.
Créez vos propres images ensuite
Une fois votre serveur opérationnel, vous voudrez le documenter, le présenter en démo ou l’inclure dans un README, et un article a besoin de visuels. Chaque photographie de cet article a été générée, non prise : chaque prompt nomme un sujet, un décor, la direction de la lumière, un objectif et un type de pellicule. Cette recette fonctionne pour n’importe quel sujet.
Nommez la lumière : « lumière dorée basse venant de la gauche » vaut mieux que « bel éclairage ».
Choisissez un objectif : « 85 mm à f/1.8 » donne un rendu de portrait, « 24 mm à f/8 » donne une scène large et nette.
Décrivez les textures : la laine, l’aluminium brossé et la brique mouillée rendent une image plus vraie.
Ouvrez PicassoIA, choisissez un modèle d’image et testez un prompt pour votre propre projet. Si une image fixe ne suffit pas, un modèle de texte vers vidéo peut transformer la même idée en mouvement. Commencez par une scène de votre propre univers et voyez à quel point le premier résultat s’en approche.