Tutorial: Implantar um servidor MCP do .NET nos Aplicativos de Contêiner do Azure

Neste tutorial, você criará um servidor MCP (Model Context Protocol) que expõe as ferramentas de gerenciamento de tarefas usando ASP.NET Core e o pacote NuGet ModelContextProtocol.AspNetCore . Implante o servidor no Aplicativos de Contêiner do Azure e conecte-o ao GitHub Copilot Chat no VS Code.

Neste tutorial, você:

  • Criar um aplicativo ASP.NET Core que expõe ferramentas MCP
  • Testar o servidor MCP localmente com o GitHub Copilot
  • Conteinerizar e implantar o aplicativo nos Aplicativos de Contêiner do Azure
  • Conectar o GitHub Copilot ao servidor MCP implantado

Pré-requisitos

Criar a estrutura do aplicativo

Nesta seção, você criará um novo projeto ASP.NET Core e o configurará como um servidor MCP.

  1. Crie um novo projeto de API Web do ASP.NET Core:

    dotnet new web -n TasksMcpServer
    cd TasksMcpServer
    
  2. Adicione o pacote NuGet do servidor MCP:

    dotnet add package ModelContextProtocol.AspNetCore --prerelease
    
  3. Substitua o conteúdo de Program.cs pelo seguinte código:

    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();
    

    Pontos principais:

    • AddMcpServer().WithHttpTransport().WithToolsFromAssembly() registra o servidor MCP e descobre todas as classes marcadas com [McpServerToolType].
    • MapMcp("/mcp") monta o ponto de extremidade HTTP transmissível no /mcp.
    • AddSingleton<TaskStore>() registra o armazenamento de dados na memória que você cria na próxima seção.
    • Você adiciona um ponto de extremidade /health separadamente para investigações de integridade de Aplicativos de Contêiner do Azure. Os pontos de extremidade MCP retornam respostas JSON-RPC que não são adequadas como investigações de integridade.
    • Você ativa o CORS porque o GitHub Copilot no VS Code faz solicitações de origem cruzada para servidores MCP.

Definir as ferramentas do MCP

Em seguida, defina o armazenamento de dados de gerenciamento de tarefas e as ferramentas MCP que os expõem aos clientes de IA.

  1. Crie um arquivo nomeado TaskStore.cs para o armazenamento de dados na memória:

    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;
        }
    }
    

    O TaskItem registro define o modelo de dados com cinco propriedades. A TaskStore classe gerencia uma lista na memória pré-preenchida com dados de exemplo e fornece métodos para listar, localizar, criar, alternar e excluir tarefas.

  2. Crie um arquivo nomeado TasksMcpTools.cs com as definições da ferramenta MCP:

    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.";
        }
    }
    

    O [McpServerToolType] atributo marca a classe como um provedor de ferramentas MCP. Cada [McpServerTool] método se torna uma ferramenta invocada. Use [Description] atributos para ajudar o modelo de IA a entender a finalidade e os parâmetros de cada ferramenta.

Testar o servidor MCP localmente

Antes de implantar no Azure, verifique se o servidor MCP funciona executando-o localmente e conectando-se do GitHub Copilot.

  1. Execute o aplicativo:

    dotnet run
    

    O servidor começa a funcionar na porta http://localhost:5000 (ou na porta exibida na saída do console). O ponto de extremidade do MCP está em http://localhost:5000/mcp.

  2. Abra o VS Code e, em seguida, abra o Chat do Copilot e selecione o modo Agente .

  3. Selecione o botão Ferramentas e, em seguida, selecione Adicionar Mais Ferramentas...>Adicionar servidor MCP.

  4. Selecione HTTP (HTTP ou Eventos Server-Sent).

  5. Insira a URL do servidor: http://localhost:5000/mcp

  6. Insira uma ID do servidor: tasks-mcp

  7. Selecione Configurações do Workspace.

  8. Em um novo prompt de Chat do Copilot, digite: "Mostrar-me todas as tarefas"

  9. O GitHub Copilot mostra uma confirmação antes de invocar a ferramenta MCP. Selecione Continuar.

Você deverá ver o Copilot retornar a lista de tarefas do repositório na memória.

Tip

Tente outros prompts como "Criar uma tarefa para examinar a PR", "Marcar tarefa 1 como concluída" ou "Excluir tarefa 2".

Colocar o aplicativo em um contêiner

Empacote o aplicativo como um contêiner do Docker para que você possa testá-lo localmente antes de implantar no Azure.

  1. Crie um Dockerfile na raiz do projeto:

    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"]
    

    A compilação de múltiplas etapas usa a imagem do SDK para restaurar, compilar e publicar o aplicativo e, em seguida, copia apenas a saída publicada para uma imagem menor da runtime do ASP.NET. A ASPNETCORE_URLS variável de ambiente configura o aplicativo para escutar na porta 8080.

  2. Verifique se o contêiner compila e é executado localmente:

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

    Confirme se o endpoint de saúde responde: curl http://localhost:8080/health

Implantar nos Aplicativos de Contêiner do Azure

Depois de colocar o aplicativo em contêiner, implante-o nos Aplicativos de Contêiner do Azure usando a CLI do Azure. O az containerapp up comando cria a imagem de contêiner na nuvem, portanto, você não precisa do Docker em seu computador para esta etapa.

  1. Definir variáveis de ambiente:

    RESOURCE_GROUP="mcp-tutorial-rg"
    LOCATION="eastus"
    ENVIRONMENT_NAME="mcp-env"
    APP_NAME="tasks-mcp-server"
    
  2. Crie um grupo de recursos:

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. Criar um ambiente de Aplicativos de Contêiner:

    az containerapp env create \
        --name $ENVIRONMENT_NAME \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION
    
  4. Implante o aplicativo de contêiner:

    az containerapp up \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --environment $ENVIRONMENT_NAME \
        --source . \
        --ingress external \
        --target-port 8080
    
  5. Configure o CORS para permitir solicitações do GitHub Copilot:

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

    Observação

    Para produção, substitua as origens * curinga por origens confiáveis específicas. Consulte servidores MCP seguros em Aplicativos de Contêiner para obter orientações.

  6. Verifique a implantação:

    APP_URL=$(az containerapp show \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --query "properties.configuration.ingress.fqdn" -o tsv)
    
    curl https://$APP_URL/health
    

Conectar o GitHub Copilot ao servidor implantado

Agora que o servidor MCP está em execução no Azure, configure o VS Code para conectar o GitHub Copilot ao ponto de extremidade implantado.

  1. Em seu projeto, crie ou atualize .vscode/mcp.json:

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

    Substitua <your-app-fqdn> pelo FQDN da saída de implantação.

  2. Abra o Copilot Chat no modo Agente dentro do VS Code.

  3. Se o servidor não aparecer automaticamente, selecione o botão Ferramentas e verifique tasks-mcp-server se está listado. Selecione Iniciar , se necessário.

  4. Teste com um prompt como "Listar todas as minhas tarefas" para confirmar se o servidor MCP implantado responde.

Configurar o dimensionamento para uso interativo

Por padrão, os Aplicativos de Contêiner do Azure podem ser dimensionados para zero réplicas. Para servidores MCP que atendem clientes interativos como o Copilot, inicializações a frio causam atrasos perceptíveis. Defina uma contagem mínima de réplicas para manter pelo menos uma instância em execução:

az containerapp update \
    --name $APP_NAME \
    --resource-group $RESOURCE_GROUP \
    --min-replicas 1

Considerações de segurança

Este tutorial usa um servidor MCP não autenticado para simplificar. Antes de executar um servidor MCP em produção, examine as recomendações a seguir. Quando um agente alimentado por grandes modelos de linguagem (LLMs) chamar seu servidor MCP, fique atento aos ataques de injeção de prompt.

  • Autenticação e autorização: proteja o servidor MCP usando a ID do Microsoft Entra. Consulte servidores MCP seguros em Aplicativos de Contêiner.
  • Validação de entrada: sempre valide os parâmetros da ferramenta. Utilize anotações de dados ou FluentValidation no ASP.NET Core. Consulte a validação de modelo no ASP.NET Core.
  • HTTPS: Os Aplicativos de Contêiner do Azure impõem HTTPS por padrão com certificados TLS automáticos.
  • Privilégio mínimo: exponha apenas as ferramentas necessárias para seu caso de uso. Evite ferramentas que executam operações destrutivas sem confirmação.
  • CORS: restringir as origens permitidas a domínios confiáveis na produção.
  • Registro e monitoramento de logs: registre as invocações da ferramenta MCP para auditoria. Use o Azure Monitor e o Log Analytics.

Limpar os recursos

Se você não planeja continuar usando este aplicativo, exclua o grupo de recursos para remover todos os recursos que você criou neste tutorial:

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

Próxima etapa