Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans ce tutoriel, vous créez un serveur MCP (Model Context Protocol) qui expose des outils de gestion des tâches à l’aide de FastAPI et du SDK Python MCP. Vous déployez le serveur sur Azure Container Apps et vous y connectez à partir de GitHub Copilot Chat dans VS Code.
Dans ce tutoriel, vous allez :
- Créer une application FastAPI qui expose les outils MCP
- Tester le serveur MCP localement avec GitHub Copilot
- Conteneuriser et déployer l’application sur Azure Container Apps
- Connecter GitHub Copilot au serveur MCP déployé
Prerequisites
- Un compte Azure avec un abonnement actif. Créez-en un gratuitement.
- Azure CLI version 2.62.0 ou ultérieure.
- Python 3.10 ou version ultérieure.
- Visual Studio Code avec l’extension GitHub Copilot .
- Docker Desktop (facultatif , nécessaire uniquement pour tester le conteneur localement).
Créer la structure de l’application
Dans cette section, vous allez créer un projet Python avec FastAPI et le Kit de développement logiciel (SDK) Python MCP.
Créez le répertoire du projet et configurez un environnement virtuel :
mkdir tasks-mcp-server && cd tasks-mcp-server python -m venv .venv source .venv/bin/activateCréer
requirements.txt:fastapi>=0.115.0 uvicorn>=0.30.0 mcp[cli]>=1.2.0Installez des dépendances :
pip install -r requirements.txtCréez
task_store.pypour le magasin de données en mémoire :from dataclasses import dataclass, field from datetime import datetime, timezone @dataclass class TaskItem: id: int title: str description: str is_complete: bool = False created_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc)) def to_dict(self) -> dict: return { "id": self.id, "title": self.title, "description": self.description, "is_complete": self.is_complete, "created_at": self.created_at.isoformat(), } class TaskStore: def __init__(self): self._tasks: list[TaskItem] = [ TaskItem(1, "Buy groceries", "Milk, eggs, bread"), TaskItem(2, "Write docs", "Draft the MCP tutorial", True), ] self._next_id = 3 def get_all(self) -> list[dict]: return [t.to_dict() for t in self._tasks] def get_by_id(self, task_id: int) -> dict | None: task = next((t for t in self._tasks if t.id == task_id), None) return task.to_dict() if task else None def create(self, title: str, description: str) -> dict: task = TaskItem(self._next_id, title, description) self._next_id += 1 self._tasks.append(task) return task.to_dict() def toggle_complete(self, task_id: int) -> dict | None: task = next((t for t in self._tasks if t.id == task_id), None) if task is None: return None task.is_complete = not task.is_complete return task.to_dict() def delete(self, task_id: int) -> bool: task = next((t for t in self._tasks if t.id == task_id), None) if task is None: return False self._tasks.remove(task) return True # For demonstration only — not thread-safe. store = TaskStore()La
TaskItemclasse de données définit le modèle de données avec uneto_dict()méthode de sérialisation. La classeTaskStoregère une liste en mémoire préremplie avec des données d'exemple et fournit des méthodes CRUD. Le singleton au niveaustoredu module est partagé avec l'application entière pour simplifier.
Définir les outils MCP
Dans cette section, vous définissez les outils MCP que le modèle IA peut appeler et monter le serveur MCP dans votre application FastAPI.
Créer
mcp_server.py:from mcp.server.fastmcp import FastMCP from task_store import store mcp = FastMCP("TasksMCP", stateless_http=True) @mcp.tool() async def list_tasks() -> list[dict]: """List all tasks with their ID, title, description, and completion status.""" return store.get_all() @mcp.tool() async def get_task(task_id: int) -> dict | None: """Get a single task by its numeric ID. Args: task_id: The numeric ID of the task to retrieve. """ return store.get_by_id(task_id) @mcp.tool() async def create_task(title: str, description: str) -> dict: """Create a new task with the given title and description. Returns the created task. Args: title: A short title for the task. description: A detailed description of what the task involves. """ return store.create(title, description) @mcp.tool() async def toggle_task_complete(task_id: int) -> str: """Toggle a task's completion status between complete and incomplete. Args: task_id: The numeric ID of the task to toggle. """ task = store.toggle_complete(task_id) if task: status = "complete" if task["is_complete"] else "incomplete" return f"Task {task['id']} is now {status}." return f"Task with ID {task_id} not found." @mcp.tool() async def delete_task(task_id: int) -> str: """Delete a task by its numeric ID. Args: task_id: The numeric ID of the task to delete. """ if store.delete(task_id): return f"Task {task_id} deleted." return f"Task with ID {task_id} not found."Points clés :
-
FastMCP("TasksMCP", stateless_http=True)crée un serveur MCP à l’aide du modèle HTTP sans état dans le Kit de développement logiciel (SDK) Python. Le point de terminaison HTTP streamable est défini par défaut sur le/mcpsous-chemin. - Chaque
@mcp.tool()fonction devient un outil invocable. Les annotations function docstring et de paramètres aident le modèle d'IA à comprendre comment utiliser chaque outil.
-
Créer
app.py. Ce fichier définit l’application FastAPI qui monte le serveur MCP :from contextlib import AsyncExitStack, asynccontextmanager from fastapi import FastAPI from fastapi.responses import JSONResponse from mcp_server import mcp @asynccontextmanager async def lifespan(app: FastAPI): async with AsyncExitStack() as stack: await stack.enter_async_context(mcp.session_manager.run()) yield app = FastAPI(lifespan=lifespan) app.mount("/", mcp.streamable_http_app()) @app.get("/health") async def health(): return JSONResponse({"status": "healthy"})L’application serveur MCP monte à la racine (
/). Le point de terminaison HTTP streamable du Kit de développement logiciel (SDK) a la valeur par défaut/mcp: le chemin d’accès complet du point de terminaison est/mcpdonc .Un point de terminaison distinct
/healthest utilisé pour les sondes de santé des Container Apps. Les points de terminaison MCP attendent les demandes POST JSON-RPC et ne conviennent pas comme contrôles d'intégrité.
Tester le serveur MCP localement
Avant de déployer sur Azure, vérifiez que le serveur MCP fonctionne en l’exécutant localement et en vous connectant à partir de GitHub Copilot.
Démarrez l’application :
uvicorn app:app --reload --port 8080Ouvrez VS Code, puis ouvrez Copilot Chat et sélectionnez le mode Agent .
Sélectionnez le bouton Outils , puis sélectionnez Ajouter d’autres outils...>Ajoutez le serveur MCP.
Sélectionnez HTTP (HTTP ou événements envoyés par le serveur).
Entrez l’URL du serveur :
http://localhost:8080/mcpEntrez un ID de serveur :
tasks-mcpSélectionnez Paramètres de l’espace de travail.
Dans une nouvelle invite de conversation Copilot, tapez : « Afficher toutes les tâches »
Sélectionnez Continuer lorsque Copilot demande la confirmation de l’outil MCP.
Vous devez voir la liste des tâches retournée par votre mémoire vive.
Conseil / Astuce
Essayez d'autres invites comme « Créer une tâche pour examiner la demande de tirage », « Marquer la tâche 1 comme terminée » ou « Supprimer la tâche 2 ».
Conteneuriser l’application
Empaqueter l’application en tant que conteneur Docker afin de pouvoir la tester localement avant de le déployer sur Azure.
Créez un
Dockerfile:FROM python:3.12-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . EXPOSE 8080 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]Dockerfile utilise une image de base Python 3.12 slim, installe les dépendances à partir de
requirements.txt, puis copie le code de l’application. Uvicorn sert l’application FastAPI sur le port 8080.Vérifiez que les constructions et les exécutions du conteneur se font localement.
docker build -t tasks-mcp-server . docker run -p 8080:8080 tasks-mcp-serverConfirmez que le point de terminaison d'intégrité répond :
curl http://localhost:8080/health
Déployer sur Azure Container Apps
Après avoir conteneurisé l’application, déployez-la sur Azure Container Apps à l’aide d’Azure CLI. La az containerapp up commande génère l’image conteneur dans le cloud. Vous n’avez donc pas besoin de Docker sur votre machine pour cette étape.
Définissez des variables d’environnement :
RESOURCE_GROUP="mcp-tutorial-rg" LOCATION="eastus" ENVIRONMENT_NAME="mcp-env" APP_NAME="tasks-mcp-server-py"Créez un groupe de ressources et un environnement Container Apps :
az group create --name $RESOURCE_GROUP --location $LOCATION az containerapp env create \ --name $ENVIRONMENT_NAME \ --resource-group $RESOURCE_GROUP \ --location $LOCATIONDéployez l’application conteneur :
az containerapp up \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --environment $ENVIRONMENT_NAME \ --source . \ --ingress external \ --target-port 8080Configurer CORS :
az containerapp ingress cors enable \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --allowed-origins "*" \ --allowed-methods "GET,POST,DELETE,OPTIONS" \ --allowed-headers "*"Note
Pour la production, remplacez les origines génériques par des origines approuvées spécifiques. Consultez les serveurs MCP sécurisés sur Container Apps.
Vérifiez le déploiement :
APP_URL=$(az containerapp show \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --query "properties.configuration.ingress.fqdn" -o tsv) curl https://$APP_URL/health
Connecter GitHub Copilot au serveur déployé
Maintenant que le serveur MCP s’exécute dans Azure, configurez VS Code pour connecter GitHub Copilot au point de terminaison déployé.
Créer ou mettre à jour
.vscode/mcp.json:{ "servers": { "tasks-mcp-server": { "type": "http", "url": "https://<your-app-fqdn>/mcp" } } }Remplacez
<your-app-fqdn>par le FQDN de la sortie du déploiement.Dans VS Code, ouvrez Copilot Chat en mode Agent.
Vérifiez que
tasks-mcp-serverapparaît dans la liste des outils. Sélectionnez Démarrer si nécessaire.Testez avec une invite comme « Créer une tâche pour déployer l’environnement intermédiaire ».
Configurer la mise à l’échelle pour une utilisation interactive
Par défaut, Azure Container Apps peut effectuer une mise à l’échelle vers zéro réplica. Pour les serveurs MCP qui servent des clients interactifs comme Copilot, les démarrages à froid provoquent des retards notables. Définissez un nombre minimal de réplicas pour conserver au moins une instance en cours d’exécution :
az containerapp update \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--min-replicas 1
Considérations relatives à la sécurité
Ce tutoriel utilise un serveur MCP non authentifié pour plus de simplicité. Avant d’exécuter un serveur MCP en production, passez en revue les recommandations suivantes. Lorsqu’un agent alimenté par de grands modèles de langage (LLMs) appelle votre serveur MCP, tenez compte des attaques d’injection de commande.
- Authentification et autorisation : Sécurisez votre serveur MCP avec l’ID Microsoft Entra. Consultez les serveurs MCP sécurisés sur Container Apps.
- Validation d’entrée : validez toujours les paramètres de l’outil. Utilisez Pydantic pour appliquer la validation des données sur les entrées d’outil.
- HTTPS : Azure Container Apps applique HTTPS par défaut avec des certificats TLS automatiques.
- Privilège minimum : exposez uniquement les outils dont votre cas d’usage a besoin. Évitez les outils qui effectuent des opérations destructrices sans confirmation.
- CORS : Restreindre les origines autorisées aux domaines de confiance en production.
- Journalisation et surveillance : journaliser les appels de l'outil MCP pour l'audit. Utilisez Azure Monitor et Log Analytics.
Nettoyer les ressources
Si vous ne prévoyez pas de continuer à utiliser cette application, supprimez le groupe de ressources pour supprimer toutes les ressources que vous avez créées dans ce tutoriel :
az group delete --resource-group $RESOURCE_GROUP --yes --no-wait
Étape suivante
Contenu connexe
- Vue d’ensemble des serveurs MCP sur Azure Container Apps
- Déployer un serveur MCP sur Container Apps (.NET)
- Déployer un serveur MCP sur Container Apps (Node.js)
- Déployer un serveur MCP sur Container Apps (Java)
- Résoudre les problèmes de serveurs MCP sur Container Apps
- Kit de développement Python pour MCP