Zelfstudie: Een .NET MCP-server implementeren in Azure Container Apps

In deze zelfstudie bouwt u een MCP-server (Model Context Protocol) die hulpprogramma's voor taakbeheer beschikbaar maakt met behulp van ASP.NET Core en het NuGet-pakket ModelContextProtocol.AspNetCore . 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 ASP.NET Core-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

De scaffold van de app maken

In deze sectie maakt u een nieuw ASP.NET Core-project en configureert u het als een MCP-server.

  1. Maak een nieuw ASP.NET Core Web API-project:

    dotnet new web -n TasksMcpServer
    cd TasksMcpServer
    
  2. Voeg het NuGet-pakket van de MCP-server toe:

    dotnet add package ModelContextProtocol.AspNetCore --prerelease
    
  3. Vervang de inhoud van Program.cs met de volgende code:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddMcpServer()
        .WithHttpTransport()
        .WithToolsFromAssembly();
    
    builder.Services.AddCors(options =>
    {
        options.AddDefaultPolicy(policy =>
        {
            policy.AllowAnyOrigin()
                  .AllowAnyHeader()
                  .AllowAnyMethod();
        });
    });
    
    builder.Services.AddSingleton<TaskStore>();
    
    var app = builder.Build();
    
    app.UseCors();
    
    app.MapGet("/health", () => Results.Ok("healthy"));
    app.MapMcp("/mcp");
    
    app.Run();
    

    Belangrijke punten:

    • AddMcpServer().WithHttpTransport().WithToolsFromAssembly() registreert de MCP-server en detecteert alle klassen die zijn gemarkeerd met [McpServerToolType].
    • MapMcp("/mcp") monteert het streambare HTTP-eindpunt bij /mcp.
    • AddSingleton<TaskStore>() registreert het in-memory gegevensarchief dat u in de volgende sectie maakt.
    • U voegt een /health eindpunt afzonderlijk toe voor statustests van Azure Container Apps. MCP-eindpunten retourneren JSON-RPC antwoorden die niet geschikt zijn als statuscontroles.
    • U schakelt CORS in omdat GitHub Copilot in VS Code cross-origin-aanvragen doet voor MCP-servers.

Definieer de MCP-hulpprogramma's

Definieer vervolgens het gegevensarchief voor taakbeheer en de MCP-hulpprogramma's die deze beschikbaar maken voor AI-clients.

  1. Maak een bestand met de naam TaskStore.cs voor het in-memory gegevensarchief:

    namespace TasksMcpServer;
    
    public record TaskItem(int Id, string Title, string Description, bool IsComplete, DateTime CreatedAt);
    
    public class TaskStore
    {
        private readonly List<TaskItem> _tasks = new()
        {
            new(1, "Buy groceries", "Milk, eggs, bread", false, DateTime.UtcNow),
            new(2, "Write docs", "Draft the MCP tutorial", true, DateTime.UtcNow.AddDays(-1)),
        };
    
        private int _nextId = 3;
    
        public List<TaskItem> GetAll() => _tasks.ToList();
    
        public TaskItem? GetById(int id) => _tasks.FirstOrDefault(t => t.Id == id);
    
        public TaskItem Create(string title, string description)
        {
            var task = new TaskItem(_nextId++, title, description, false, DateTime.UtcNow);
            _tasks.Add(task);
            return task;
        }
    
        public TaskItem? ToggleComplete(int id)
        {
            var index = _tasks.FindIndex(t => t.Id == id);
            if (index < 0) return null;
            var old = _tasks[index];
            var updated = old with { IsComplete = !old.IsComplete };
            _tasks[index] = updated;
            return updated;
        }
    
        public bool Delete(int id)
        {
            var task = _tasks.FirstOrDefault(t => t.Id == id);
            if (task is null) return false;
            _tasks.Remove(task);
            return true;
        }
    }
    

    De TaskItem record definieert het gegevensmodel met vijf eigenschappen. De TaskStore klasse beheert een in-memory lijst die vooraf is ingevuld met voorbeeldgegevens en biedt methoden voor het weergeven, zoeken, maken, in- en uitschakelen van taken.

  2. Maak een bestand met de naam TasksMcpTools.cs MCP-hulpprogrammadefinities:

    using System.ComponentModel;
    using ModelContextProtocol.Server;
    
    namespace TasksMcpServer;
    
    [McpServerToolType]
    public class TasksMcpTools
    {
        private readonly TaskStore _store;
    
        public TasksMcpTools(TaskStore store)
        {
            _store = store;
        }
    
        [McpServerTool, Description("Lists all tasks with their ID, title, description, and completion status.")]
        public List<TaskItem> ListTasks()
        {
            return _store.GetAll();
        }
    
        [McpServerTool, Description("Gets a single task by its ID.")]
        public TaskItem? GetTask(
            [Description("The numeric ID of the task to retrieve")] int id)
        {
            return _store.GetById(id);
        }
    
        [McpServerTool, Description("Creates a new task with the given title and description. Returns the created task.")]
        public TaskItem CreateTask(
            [Description("A short title for the task")] string title,
            [Description("A detailed description of what the task involves")] string description)
        {
            return _store.Create(title, description);
        }
    
        [McpServerTool, Description("Toggles a task's completion status between complete and incomplete.")]
        public string ToggleTaskComplete(
            [Description("The numeric ID of the task to toggle")] int id)
        {
            var task = _store.ToggleComplete(id);
            return task is not null
                ? $"Task {task.Id} is now {(task.IsComplete ? "complete" : "incomplete")}."
                : $"Task with ID {id} not found.";
        }
    
        [McpServerTool, Description("Deletes a task by its ID.")]
        public string DeleteTask(
            [Description("The numeric ID of the task to delete")] int id)
        {
            return _store.Delete(id)
                ? $"Task {id} deleted."
                : $"Task with ID {id} not found.";
        }
    }
    

    Het [McpServerToolType] kenmerk markeert de klasse als een MCP-hulpprogrammaprovider. Elke [McpServerTool] methode wordt een aanroepbaar hulpmiddel. Gebruik [Description] kenmerken om het AI-model inzicht te geven in het doel en de parameters van elk hulpprogramma.

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.

  1. Voer de toepassing uit:

    dotnet run
    

    De server wordt gestart op http://localhost:5000 (of de poort die wordt weergegeven in de console-uitvoer). Het MCP-eindpunt bevindt zich op http://localhost:5000/mcp.

  2. Open VS Code en open Copilot Chat en selecteer Agentmodus.

  3. Selecteer de knop Extra en selecteer vervolgens Meer hulpprogramma's toevoegen...>MCP-server toevoegen.

  4. Selecteer HTTP (HTTP of Server-Sent-gebeurtenissen).

  5. Voer de server-URL in: http://localhost:5000/mcp

  6. Voer een server-id in: tasks-mcp

  7. Selecteer Werkruimte-instellingen.

  8. Typ in een nieuwe Copilot-chatprompt: 'Toon mij alle taken'

  9. GitHub Copilot toont een bevestiging voordat u het MCP-hulpprogramma aanroept. Klik op Doorgaan.

U zou moeten zien dat Copilot de lijst met taken uit uw in-memory opslag retourneert.

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.

  1. Maak een Dockerfile in de hoofdmap van het project:

    FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
    WORKDIR /src
    COPY *.csproj .
    RUN dotnet restore
    COPY . .
    RUN dotnet publish -c Release -o /app
    
    FROM mcr.microsoft.com/dotnet/aspnet:8.0
    WORKDIR /app
    COPY --from=build /app .
    ENV ASPNETCORE_URLS=http://+:8080
    EXPOSE 8080
    ENTRYPOINT ["dotnet", "TasksMcpServer.dll"]
    

    De build met meerdere fasen maakt gebruik van de SDK-installatiekopieën om de app te herstellen, te bouwen en te publiceren en kopieert vervolgens alleen de gepubliceerde uitvoer naar een kleinere ASP.NET runtime-installatiekopieën. De ASPNETCORE_URLS omgevingsvariabele configureert de app om te luisteren op poort 8080.

  2. Controleer of de container lokaal wordt gebouwd en draait.

    docker build -t tasks-mcp-server .
    docker run -p 8080:8080 tasks-mcp-server
    

    Controleer 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 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.

  1. Omgevingsvariabelen instellen:

    RESOURCE_GROUP="mcp-tutorial-rg"
    LOCATION="eastus"
    ENVIRONMENT_NAME="mcp-env"
    APP_NAME="tasks-mcp-server"
    
  2. Een resourcegroep maken:

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. Een Container Apps-omgeving maken:

    az containerapp env create \
        --name $ENVIRONMENT_NAME \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION
    
  4. De container-app implementeren:

    az containerapp up \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --environment $ENVIRONMENT_NAME \
        --source . \
        --ingress external \
        --target-port 8080
    
  5. CONFIGUREER CORS om GitHub Copilot-aanvragen toe te staan:

    az containerapp ingress cors enable \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --allowed-origins "*" \
        --allowed-methods "GET,POST,DELETE,OPTIONS" \
        --allowed-headers "*"
    

    Opmerking

    Vervang tijdens de productiefase de jokertekens * door specifieke vertrouwde bronnen. Zie Beveiligde MCP-servers in Container Apps voor hulp.

  6. 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.

  1. Maak of werk .vscode/mcp.jsonhet volgende bij in uw project:

    {
        "servers": {
            "tasks-mcp-server": {
                "type": "http",
                "url": "https://<your-app-fqdn>/mcp"
            }
        }
    }
    

    Vervang <your-app-fqdn> door de FQDN uit de implementatie-uitvoer.

  2. Open Copilot Chat in Agent modus in VS Code.

  3. Als de server niet automatisch wordt weergegeven, selecteert u de knop Extra en verifieert u of tasks-mcp-server wordt weergegeven. Selecteer indien nodig Start.

  4. Test met een prompt zoals 'Al mijn taken vermelden' om te bevestigen dat de geïmplementeerde MCP-server reageert.

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 behulp van Microsoft Entra-id. Zie Beveiligde MCP-servers in Container Apps.
  • Invoervalidatie: Altijd hulpprogrammaparameters valideren. Gebruik gegevensaantekeningen of FluentValidation in ASP.NET Core. Zie Modelvalidatie in ASP.NET Core.
  • 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, verwijder dan de resourcegroep om alle resources te verwijderen die u in deze tutorial hebt gemaakt.

az group delete --resource-group $RESOURCE_GROUP --yes --no-wait

Volgende stap