Aller au contenu

Deployer les proxies MCP

Les serveurs MCP communiquent par stdio (stdin/stdout), mais les navigateurs ont besoin d’endpoints HTTP. Ce tutoriel vous montre comment deployer les proxies qui font le pont, en local avec Docker ou en production avec systemd et nginx.

Deployer les proxies MCP pour rendre accessibles depuis le navigateur les serveurs MCP publics (NASA, HackerNews, Wikipedia, etc.).

  • Docker et Docker Compose installes (pour la methode rapide)
  • Ou : une VM Ubuntu/Debian avec python3, node, npm, nginx (pour la production)
  • Comprendre ce qu’est un serveur MCP (voir Connecter un serveur MCP)

Des serveurs MCP accessibles par HTTP, avec CORS configure, recettes injectees, et monitoring systemd.

graph LR
Browser[Navigateur] -->|HTTPS| Nginx[nginx reverse proxy]
Nginx -->|HTTP localhost:900x| Bridge["mcp-stdio-bridge.py"]
Bridge -->|stdin/stdout| MCP["Serveur MCP (npx/python3)"]

Chaque bridge est un processus Python qui :

  • Spawn le serveur MCP comme processus enfant communicant via stdio
  • Accepte POST /mcp avec un body JSON-RPC 2.0
  • Transmet au subprocess via stdin, lit la reponse sur stdout
  • Gere le cycle de vie du subprocess (demarrage paresseux, redemarrage sur crash)
  • Injecte optionnellement des outils “recettes” depuis un fichier JSON
graph TB
subgraph "Par serveur MCP"
HTTP["POST /mcp (JSON-RPC 2.0)"] --> Bridge["mcp-stdio-bridge.py"]
Bridge --> Stdin["stdin"]
Stdin --> Process["MCP server subprocess"]
Process --> Stdout["stdout"]
Stdout --> Bridge
Bridge --> Response["Reponse HTTP"]
end
subgraph nginx
CORS["Headers CORS"] --> Proxy["proxy_pass localhost:900x"]
end
Client[McpClient] --> nginx
nginx --> HTTP

Pour le developpement local, Docker Compose demarre tous les serveurs en une commande :

Fenêtre de terminal
cd mcp-proxies
docker compose up -d

Tous les serveurs sont alors accessibles sur localhost:9001 a localhost:9008.

Pour demarrer un seul serveur :

Fenêtre de terminal
docker compose up -d hackernews

Verification : testez avec curl :

Fenêtre de terminal
curl -s -X POST http://localhost:9006/mcp \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "test", "version": "1.0" }
}
}'

Une reponse valide contient "result" avec les capabilities du serveur.


Pour un deploiement en production sur une VM Ubuntu/Debian :

Fenêtre de terminal
cd mcp-proxies
sudo ./setup.sh

Le script est idempotent (il peut etre relance sans risque). Il effectue :

  1. Verification des prerequis (python3, node, npm, nginx)
  2. Creation d’un utilisateur systeme dedie mcpbridge
  3. Copie des scripts bridge dans /opt/mcp-bridge/
  4. Generation des fichiers unit systemd pour chaque serveur
  5. Generation du bloc de locations nginx
  6. Demarrage ou redemarrage de tous les services
  7. Test de chaque endpoint avec curl
sequenceDiagram
participant Admin
participant Setup as setup.sh
participant System as systemd
participant Nginx as nginx
Admin->>Setup: sudo ./setup.sh
Setup->>Setup: Verifie prerequis
Setup->>Setup: Cree user mcpbridge
Setup->>Setup: Copie scripts vers /opt/mcp-bridge/
Setup->>System: Genere + active units systemd
Setup->>Nginx: Genere locations + reload
Setup->>Setup: curl test chaque endpoint
Setup-->>Admin: Rapport de demarrage

Le proxy NASA necessite une variable d’environnement NASA_API_KEY. Definissez-la avant de lancer le setup :

Fenêtre de terminal
export NASA_API_KEY="votre-cle-ici"
sudo -E ./setup.sh

Pour ajouter un serveur MCP au systeme de proxies :

Fenêtre de terminal
mkdir mcp-proxies/servers/mon-serveur
mcp-proxies/servers/mon-serveur/
recipes.json # Outils "recettes" injectes (optionnel)
service.conf # Configuration systemd (commande, port, env)
README.md # Documentation du serveur
examples.md # Exemples de prompts

Le fichier service.conf definit comment demarrer le serveur :

[Service]
ExecStart=npx -y @modelcontextprotocol/server-mon-serveur
Environment=PORT=9009

Le fichier recipes.json injecte des outils de decouverte dans le serveur :

[
{
"name": "guide-recherche",
"description": "Comment chercher dans mon-serveur",
"content": "## Recherche\\n\\nUtiliser search({query: 'mot-cle'})..."
}
]
Fenêtre de terminal
sudo ./setup.sh

Verification : le nouveau service apparait dans systemctl status mcp-bridge-mon-serveur.


Envoyez une requete initialize pour verifier qu’un serveur repond :

Fenêtre de terminal
curl -s -X POST http://localhost:9001/mcp \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "test", "version": "1.0" }
}
}'

Puis listez les outils :

Fenêtre de terminal
curl -s -X POST http://localhost:9001/mcp \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'

Une fois le proxy en marche, connectez-vous depuis votre app :

import { McpClient } from '@webmcp-auto-ui/core';
// En developpement local
const client = new McpClient('http://localhost:9001/mcp');
await client.initialize();
const tools = await client.listTools();
// En production
const client = new McpClient('https://demos.hyperskills.net/mcp-metmuseum/mcp');

Pour gerer plusieurs serveurs simultanement :

import { McpMultiClient } from '@webmcp-auto-ui/core';
const multi = new McpMultiClient();
await multi.addServer('https://demos.hyperskills.net/mcp-metmuseum/mcp');
await multi.addServer('https://demos.hyperskills.net/mcp-wikipedia/mcp');

Chaque serveur peut optionnellement inclure un fichier recipes.json qui injecte des outils de recettes (list_recipes, get_recipe, search_recipes) dans la liste d’outils du serveur MCP. Le bridge charge ces recettes au demarrage via le flag --recipes.

Les recettes permettent au LLM de decouvrir comment utiliser le serveur de maniere autonome, meme si le serveur MCP d’origine n’a pas de mecanisme de decouverte integre.


ServeurOutils principauxPortURL productionExemple de prompt
hackernewsget-front-page, search-posts9006/mcp-hackernews/mcp”Top 10 stories on HN today”
metmuseumsearch-museum-objects, get-museum-object9001/mcp-metmuseum/mcp”Show impressionist paintings”
openmeteoweather_forecast, geocoding9002/mcp-openmeteo/mcp”Weather in Paris this week”
wikipediasearch, readArticle9005/mcp-wikipedia/mcp”Article about quantum computing”
inaturalistsearch_observations9007/mcp-inaturalist/mcp”Birds spotted near Lyon”
nasanasa_apod, nasa_mars_rover, nasa_neo9008/mcp-nasa/mcp”Latest Mars rover photos”
datagouvproxy distant (pas de bridge)/mcp-datagouv/mcp”Transport datasets in France”

Les URLs de production sont prefixees par https://demos.hyperskills.net.


mcp-proxies/
bridge/
mcp-stdio-bridge.py # Le pont generique stdio-to-HTTP
inaturalist-mcp.py # Serveur MCP Python custom pour iNaturalist
nginx/
mcp-locations.conf # Blocs location nginx (CORS + proxy_pass)
servers/
hackernews/ # Config et recettes par serveur
metmuseum/
openmeteo/
wikipedia/
inaturalist/
nasa/
datagouv/
setup.sh # Script de provisioning VM
docker-compose.yml # Alternative Docker pour le dev local

ProblemeCause probableSolution
”Connection refused”Le bridge n’est pas demarresystemctl status mcp-bridge-<nom>
”CORS error”Headers CORS manquants dans nginxVerifiez mcp-locations.conf
Timeout au premier appelLe serveur MCP met du temps a demarrerLe bridge fait un demarrage paresseux, le premier appel est lent
”Invalid JSON-RPC”Format de requete incorrectVerifiez le body JSON-RPC 2.0
Serveur qui crash en boucleDependance npm manquantejournalctl -u mcp-bridge-<nom> pour voir les logs

  • Creer un serveur MCP custom : ecrivez votre propre serveur MCP en Node.js ou Python
  • Monitoring : ajoutez des healthchecks systemd et des alertes
  • Securite : ajoutez une authentification par token aux endpoints