Comment Construire Votre Premier Serveur MCP : Tutoriel Pas à Pas

Prérequis
Avant de commencer, assurez-vous d'avoir les éléments suivants :
: - Python 3.10 ou une version supérieure installé.
- Une connaissance de base des fonctions Python et du code asynchrone.
- uv (gestionnaire de paquets Python rapide) – installez-le avec
curl -LsSf https://astral.sh/uv/install.sh | sh. - Un client MCP tel que Claude Desktop (téléchargez-le sur claude.ai/download et maintenez-le à jour).
- Un éditeur de texte ou un IDE.
Aucune expérience préalable avec MCP n'est nécessaire. Nous allons créer un serveur MCP météo pratique qui permet à l'IA d'interroger en temps réel les alertes météorologiques et les prévisions aux États-Unis via l'API du National Weather Service.
Étape 1 : Configurer l'environnement
Créez un répertoire de projet propre et initialisez-le avec uv :
mkdir weather-mcp-server
cd weather-mcp-server
uv init
uv venv
source .venv/bin/activate # Sur Windows : .venv\Scripts\activate
uv add "mcp[cli]" httpx
Cela installe le SDK Python officiel MCP (FastMCP) et httpx pour les appels API. Votre projet possède maintenant un pyproject.toml et un environnement virtuel.
Sortie attendue : Un nouveau dossier .venv et les dépendances listées dans uv.lock.
Étape 2 : Créer le code du serveur MCP
Créez le fichier principal :
touch weather.py
Collez ce code complet, prêt à l'exécution, dans weather.py :
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# Initialiser le serveur MCP
mcp = FastMCP("weather")
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
# Fonction utilitaire pour appeler l'API NWS de manière sécurisée
async def make_nws_request(url: str) -> dict[str, Any] | None:
headers = {"User-Agent": USER_AGENT, "Accept": "application/geo+json"}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
# Formater les alertes météorologiques de manière lisible pour l'IA
def format_alert(feature: dict) -> str:
props = feature["properties"]
return f"""
Event: {props.get("event", "Unknown")}
Area: {props.get("areaDesc", "Unknown")}
Severity: {props.get("severity", "Unknown")}
Description: {props.get("description", "No description available")}
Instructions: {props.get("instruction", "No specific instructions provided")}
"""
# Outil 1 : Obtenir les alertes météorologiques actives pour un état américain
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get current weather alerts for a U.S. state (e.g., "CA" or "TX")."""
url = f"{NWS_API_BASE}/alerts/active/area/{state.upper()}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return f"No active alerts for {state.upper()}."
alerts = [format_alert(f) for f in data["features"]]
return "\n---\n".join(alerts)
Outil 2 : Obtenir les prévisions sur 5 jours pour n’importe quelle latitude/longitude
@mcp.tool() async def get_forecast(latitude: float, longitude: float) -> str: """Obtenir les prévisions météo pour une latitude et une longitude spécifiques.""" points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}" points_data = await make_nws_request(points_url) if not points_data: return "Impossible de récupérer les données de prévision pour cet emplacement." forecast_url = points_data["properties"]["forecast"] forecast_data = await make_nws_request(forecast_url) if not forecast_data: return "Impossible de récupérer les prévisions détaillées." periods = forecast_data["properties"]["periods"][:5] forecasts = [] for period in periods: forecast = f""" {period["name"]} : Température : {period["temperature"]}°{period["temperatureUnit"]} Vent : {period["windSpeed"]} {period["windDirection"]} Prévisions : {period["detailedForecast"]} """ forecasts.append(forecast) return "\n---\n".join(forecasts)
def main(): mcp.run(transport="stdio")
if name == "main": main()
**Concepts clés expliqués :**
- Les décorateurs `@mcp.tool()` transforment des fonctions asynchrones normales en outils MCP que l'IA peut découvrir et appeler.
- Le serveur s'exécute via **stdio** (entrée/sortie standard) – la configuration par défaut pour les serveurs MCP locaux.
- Toute journalisation doit être envoyée vers stderr (FastMCP gère cela automatiquement).
## Étape 3 : Tester le serveur localement
Exécutez le serveur :
```bash
uv run weather.py
Sortie attendue : Le terminal reste ouvert et silencieux (c’est normal pour les serveurs stdio). Vous ne verrez les messages JSON-RPC que lorsqu'un client MCP se connectera.
Laissez ce terminal ouvert pour l'étape suivante.
Étape 4 : Connecter le serveur MCP à Claude Desktop
- Ouvrez Claude Desktop.
- Créez ou modifiez le fichier de configuration à l'emplacement :
- macOS :
~/Library/Application Support/Claude/claude_desktop_config.json - Windows :
%APPDATA%\Claude\claude_desktop_config.json
- macOS :
Ajoutez cette entrée exacte (remplacez /ABSOLUTE/PATH/TO/weather-mcp-server par le chemin réel de votre dossier) :
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/TO/weather-mcp-server",
"run",
"weather.py"
]
}
}
}
- Quittez complètement Claude Desktop (Cmd+Q sur macOS ou fermez depuis la barre système sur Windows) et redémarrez-le.
- Dans Claude, cliquez sur « Ajouter des fichiers, connecteurs et plus » → survolez Connecteurs → vous devriez voir « weather » dans la liste.
Étape 5 : Utiliser votre serveur MCP avec l'IA
Essayez ces requêtes dans Claude Desktop :
- « Quelles sont les alertes météo actives au Texas ? »
- « Donnez-moi les prévisions pour San Francisco (utilisez lat 37.77, long -122.41). »
- « Vérifiez les alertes en Californie et dites-moi si je dois me préparer à quelque chose. »
Claude découvrira automatiquement les outils, demandera votre approbation la première fois et renverra les résultats formatés.
Comportement attendu : L'IA appellera vos outils en arrière-plan et affichera des réponses en langage naturel.
Problèmes courants et dépannage
-
Le serveur n’apparaît pas dans Claude :
- Vérifiez que le JSON est valide (pas de virgules traînantes).
- Utilisez un chemin absolu dans la configuration.
- Redémarrez Claude complètement.
- Consultez les logs :
~/Library/Logs/Claude/mcp*.log(macOS) ou équivalent sur Windows.
-
Erreurs d’API ou absence de données :
- L’API NWS fonctionne uniquement pour les localisations aux États-Unis.
- Utilisez des codes d’état à deux lettres (CA, TX, etc.).
- Les coordonnées doivent être des latitudes/longitudes valides.
-
« Commande non trouvée » :
- Assurez-vous que uv est dans votre PATH et que l’environnement virtuel est activé.
- Exécutez
uv --versionpour vérifier l’installation.
-
Délai d’expiration ou réponse lente :
- Augmentez le délai d’expiration dans
make_nws_requestsi nécessaire. - NWS impose des limites de débit – évitez les requêtes abusives en production.
- Augmentez le délai d’expiration dans
-
Problèmes de permissions :
- Sur macOS, accordez à Claude Desktop un accès complet au disque dans Paramètres Système → Confidentialité et Sécurité.
Étapes suivantes
- Ajoutez plus d’outils : Créez des outils pour des bases de données, GitHub, Slack ou vos propres API en utilisant le même modèle
@mcp.tool(). - Ajoutez des ressources et des invites : Utilisez
mcp.resource()etmcp.prompt()pour des données de type fichier et des instructions réutilisables. - Déployez à distance : Passez au transport HTTP/SSE et hébergez sur AWS Lambda, Vercel ou tout serveur (FastMCP prend en charge
stateless_http=True). - Prenez en charge plusieurs langages : Essayez les SDK officiels TypeScript, Go ou Rust pour les mêmes fonctionnalités.
- Partagez votre serveur : Publiez le dépôt pour que d’autres puissent l’ajouter via
npxou Docker.
Vous avez maintenant un serveur MCP entièrement fonctionnel que tout client AI compatible peut utiliser. Expérimentez, étendez les outils et commencez dès aujourd’hui à créer des intégrations AI puissantes !