Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In deze zelfstudie bouwt u een MCP-server (Model Context Protocol) die hulpprogramma's voor taakbeheer beschikbaar maakt met behulp van FastAPI en de MCP Python SDK. U implementeert de server in Azure Container Apps en maakt er verbinding mee vanuit GitHub Copilot Chat in VS Code.
In deze handleiding leert u:
- Een FastAPI-app maken die MCP-hulpprogramma's beschikbaar maakt
- De MCP-server lokaal testen met GitHub Copilot
- De app containeriseren en implementeren in Azure Container Apps
- GitHub Copilot verbinden met de geïmplementeerde MCP-server
Vereiste voorwaarden
- Een Azure-account met een actief abonnement. Maak gratis een account.
- Azure CLI versie 2.62.0 of hoger.
- Python 3.10 of hoger.
- Visual Studio Code met de GitHub Copilot-extensie .
- Docker Desktop (optioneel: alleen nodig om de container lokaal te testen).
De scaffold van de app maken
In deze sectie maakt u een nieuw Python-project met FastAPI en de MCP Python SDK.
Maak de projectmap en stel een virtuele omgeving in:
mkdir tasks-mcp-server && cd tasks-mcp-server python -m venv .venv source .venv/bin/activateMaken
requirements.txt:fastapi>=0.115.0 uvicorn>=0.30.0 mcp[cli]>=1.2.0Afhankelijkheden installeren:
pip install -r requirements.txtMaak
task_store.pyvoor de gegevensopslag in het geheugen aan.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()De
TaskItemdataclass definieert het gegevensmodel met eento_dict()methode voor serialisatie. DeTaskStoreklasse beheert een in-memory lijst die vooraf is ingevuld met voorbeeldgegevens en biedt CRUD-methoden. De singleton op moduleniveaustorewordt voor het gemak gedeeld in de toepassing.
Definieer de MCP-hulpprogramma's
In deze sectie definieert u de MCP-hulpprogramma's die het AI-model kan aanroepen en koppelen aan de MCP-server in uw FastAPI-toepassing.
Maken
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."Belangrijke punten:
-
FastMCP("TasksMCP", stateless_http=True)maakt een MCP-server met behulp van het stateless HTTP-patroon in de Python SDK. Het streambare HTTP-eindpunt wordt standaard ingesteld op het/mcpsubpad. - Elke
@mcp.tool()functie wordt een aanroepbaar hulpmiddel. De functie-documentatie en parameteraantekeningen helpen het AI-model te begrijpen hoe elk hulpprogramma moet worden gebruikt.
-
Maken
app.py. Dit bestand definieert de FastAPI-toepassing die de MCP-server koppelt: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"})De MCP-server-app wordt gemount op de hoofdmap (
/). Het streambare HTTP-eindpunt van de SDK is standaard ingesteld op/mcp, dus het volledige eindpuntpad is/mcp.Er wordt een afzonderlijk
/healtheindpunt gebruikt voor gezondheidscontroles van Container Apps. MCP-eindpunten verwachten JSON-RPC POST-aanvragen en zijn niet geschikt als statuscontroles.
De MCP-server lokaal testen
Voordat u implementeert in Azure, controleert u of de MCP-server werkt door deze lokaal uit te voeren en verbinding te maken vanuit GitHub Copilot.
Start de toepassing:
uvicorn app:app --reload --port 8080Open VS Code en open Copilot Chat en selecteer Agentmodus.
Selecteer de knop Extra en selecteer vervolgens Meer hulpprogramma's toevoegen...>MCP-server toevoegen.
Selecteer HTTP (HTTP of Server-Sent-gebeurtenissen).
Voer de server-URL in:
http://localhost:8080/mcpVoer een server-id in:
tasks-mcpSelecteer Werkruimte-instellingen.
Typ in een nieuwe Copilot-chatprompt: 'Toon mij alle taken'
Selecteer Doorgaan wanneer Copilot vraagt om bevestiging van het MCP-hulpprogramma.
U zou de takenlijst moeten zien die wordt geretourneerd uit uw in-memory opslag.
Aanbeveling
Probeer andere prompts zoals 'Creëer een taak om de PR te controleren', 'Taak 1 markeren als voltooid' of 'Taak 2 verwijderen'.
De toepassing in een container plaatsen
Verpak de toepassing als een Docker-container, zodat u deze lokaal kunt testen voordat u implementeert in Azure.
Maak een
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 maakt gebruik van een slanke basisimage van Python 3.12, installeert afhankelijkheden van
requirements.txt, en kopieert vervolgens de toepassingscode. Uvicorn dient de FastAPI applicatie op poort 8080.Controleer of de container lokaal wordt gebouwd en draait.
docker build -t tasks-mcp-server . docker run -p 8080:8080 tasks-mcp-serverControleer of het gezondheidseindpunt reageert:
curl http://localhost:8080/health
Implementeren in Azure Container Apps
Nadat u de toepassing in een container hebt geplaatst, implementeert u deze in Azure Container Apps met behulp van de Azure CLI. De opdracht az containerapp up bouwt de containerafbeelding in de cloud, zodat u Docker niet nodig hebt op uw machine voor deze stap.
Omgevingsvariabelen instellen:
RESOURCE_GROUP="mcp-tutorial-rg" LOCATION="eastus" ENVIRONMENT_NAME="mcp-env" APP_NAME="tasks-mcp-server-py"Maak een resourcegroep en een Container Apps-omgeving:
az group create --name $RESOURCE_GROUP --location $LOCATION az containerapp env create \ --name $ENVIRONMENT_NAME \ --resource-group $RESOURCE_GROUP \ --location $LOCATIONDe container-app implementeren:
az containerapp up \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --environment $ENVIRONMENT_NAME \ --source . \ --ingress external \ --target-port 8080CORS configureren:
az containerapp ingress cors enable \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --allowed-origins "*" \ --allowed-methods "GET,POST,DELETE,OPTIONS" \ --allowed-headers "*"Opmerking
Vervang wildcards voor productie door specifieke vertrouwde origins. Zie Beveiligde MCP-servers in Container Apps.
Controleer de implementatie:
APP_URL=$(az containerapp show \ --name $APP_NAME \ --resource-group $RESOURCE_GROUP \ --query "properties.configuration.ingress.fqdn" -o tsv) curl https://$APP_URL/health
GitHub Copilot verbinden met de geïmplementeerde server
Nu de MCP-server wordt uitgevoerd in Azure, configureert u VS Code om GitHub Copilot te verbinden met het geïmplementeerde eindpunt.
Maken of bijwerken
.vscode/mcp.json:{ "servers": { "tasks-mcp-server": { "type": "http", "url": "https://<your-app-fqdn>/mcp" } } }Vervang
<your-app-fqdn>door de FQDN uit de implementatie-uitvoer.Open Copilot Chat in Agent modus in VS Code.
Controleer of
tasks-mcp-serverwordt weergegeven in de Hulpmiddelenlijst. Selecteer indien nodig Start.Test met een prompt zoals 'Een taak maken om de faseringsomgeving te implementeren'.
Configureer schaling voor interactief gebruik
Azure Container Apps kan standaard worden geschaald naar nul replica's. Voor MCP-servers die interactieve clients zoals Copilot bedienen, leidt koud starten tot merkbare vertragingen. Stel een minimumaantal replica's in om ten minste één exemplaar actief te houden:
az containerapp update \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--min-replicas 1
Beveiligingsoverwegingen
In deze zelfstudie wordt gebruikgemaakt van een niet-geverifieerde MCP-server voor het gemak. Voordat u een MCP-server in productie draait, bekijk de volgende aanbevelingen. Wanneer een agent aangedreven door grote taalmodellen (LLM's) uw MCP-server aanroept, houd rekening met promptinjectie-aanvallen.
- Verificatie en autorisatie: beveilig uw MCP-server met Microsoft Entra-id. Zie Beveiligde MCP-servers in Container Apps.
- Invoervalidatie: Altijd hulpprogrammaparameters valideren. Gebruik Pydantic om gegevensvalidatie af te dwingen bij invoer van hulpprogramma's.
- HTTPS: Azure Container Apps dwingt HTTPS standaard af met automatische TLS-certificaten.
- Minimale bevoegdheid: alleen de hulpprogramma's beschikbaar maken die uw use-case vereist. Vermijd hulpprogramma's die destructieve bewerkingen uitvoeren zonder bevestiging.
- CORS: Toegestane oorsprongen beperken tot vertrouwde domeinen in productie.
- Logboekregistratie en bewaking: MCP-hulpprogramma-aanroepen loggen voor auditing. Gebruik Azure Monitor en Log Analytics.
De hulpbronnen opschonen
Als u niet van plan bent om deze toepassing te blijven gebruiken, verwijdert u de resourcegroep om alle resources te verwijderen die u in deze zelfstudie hebt gemaakt:
az group delete --resource-group $RESOURCE_GROUP --yes --no-wait