Поделиться через


Руководство. Развертывание сервера .NET MCP в приложениях контейнеров Azure

В этом руководстве вы создадите сервер протокола MCP, предоставляющий средства управления задачами с помощью ASP.NET Core и пакета NuGet ModelContextProtocol.AspNetCore . Вы развертываете сервер в приложениях контейнеров Azure и подключаетесь к нему из чата GitHub Copilot в VS Code.

Изучив это руководство, вы:

  • Создание приложения ASP.NET Core, предоставляющего средства MCP
  • Тестирование сервера MCP локально с помощью GitHub Copilot
  • Контейнеризация и развертывание приложения в приложениях контейнеров Azure
  • Подключите GitHub Copilot к развернутому серверу MCP

Предпосылки

Создайте каркас приложения

В этом разделе описано, как создать проект ASP.NET Core и настроить его в качестве сервера MCP.

  1. Создайте проект веб-API ASP.NET Core:

    dotnet new web -n TasksMcpServer
    cd TasksMcpServer
    
  2. Добавьте пакет NuGet сервера MCP:

    dotnet add package ModelContextProtocol.AspNetCore --prerelease
    
  3. Замените все содержимое Program.cs следующим кодом:

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

    Основные моменты:

    • AddMcpServer().WithHttpTransport().WithToolsFromAssembly() регистрирует сервер MCP и обнаруживает все классы, помеченные как [McpServerToolType].
    • MapMcp("/mcp") создает потоковый HTTP-эндпоинт на /mcp.
    • AddSingleton<TaskStore>() регистрирует хранилище данных в памяти, создаваемое в следующем разделе.
    • Вы добавляете конечную точку /health отдельно для проб работоспособности приложений контейнеров Azure. Конечные точки MCP возвращают ответы JSON-RPC, которые не подходят для мониторинга состояния системы.
    • Вы включаете CORS, потому что GitHub Copilot в VS Code выполняет кросс-доменные запросы к серверам MCP.

Определение средств MCP

Затем определите хранилище данных управления задачами и средства MCP, которые предоставляют его клиентам ИИ.

  1. Создайте файл с именем TaskStore.cs для хранилища данных в памяти.

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

    Запись TaskItem определяет модель данных с пятью свойствами. Класс TaskStore управляет списком в памяти, предварительно заполненным примерами данных и предоставляет методы для перечисления, поиска, создания, переключения и удаления задач.

  2. Создайте файл с именем TasksMcpTools.cs, содержащий определения инструментов 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.";
        }
    }
    

    Атрибут [McpServerToolType] помечает класс как поставщик инструментов MCP. Каждый [McpServerTool] метод становится вызываемым инструментом. Используйте [Description] атрибуты, чтобы помочь модели ИИ понять назначение и параметры каждого средства.

Тестирование сервера MCP локально

Перед развертыванием в Azure убедитесь, что сервер MCP работает, запустив его локально и подключившись к нему с помощью GitHub Copilot.

  1. Запустите приложение:

    dotnet run
    

    Сервер запускается на http://localhost:5000 или на порту, показанном в выходных данных консоли. Конечная точка MCP находится в http://localhost:5000/mcp.

  2. Откройте VS Code, а затем откройте чат Copilot и выберите режим агента .

  3. Нажмите кнопку "Сервис" , а затем нажмите кнопку "Добавить дополнительные инструменты" ...>Добавьте СЕРВЕР MCP.

  4. Выберите HTTP (HTTP или Server-Sent события).

  5. Введите URL-адрес сервера: http://localhost:5000/mcp

  6. Введите идентификатор сервера: tasks-mcp

  7. Выберите параметры рабочей области.

  8. В новом запросе чата Copilot введите "Показать мне все задачи"

  9. GitHub Copilot показывает подтверждение перед вызовом средства MCP. Нажмите Продолжить.

Вы увидите, что Copilot возвращает список задач из хранилища в памяти.

Подсказка

Попробуйте использовать другие запросы, такие как "Создать задачу для проверки pr", "Пометить задачу 1 как завершенную" или "Удалить задачу 2".

Помещение приложения в контейнер

Упаковайте приложение как контейнер Docker, чтобы протестировать его локально перед развертыванием в Azure.

  1. Создайте Dockerfile в корневом каталоге проекта.

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

    Многоэтапная сборка использует образ пакета SDK для восстановления, сборки и публикации приложения, а затем копирует только опубликованные выходные данные в меньший образ среды выполнения ASP.NET. Переменная ASPNETCORE_URLS среды настраивает приложение для прослушивания порта 8080.

  2. Проверьте сборку контейнера и выполняется локально:

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

    Убедитесь, что точка проверки работоспособности отвечает: curl http://localhost:8080/health

Развертывание в приложениях контейнеров Azure

После контейнеризации приложения разверните его в azure Container Apps с помощью Azure CLI. Команда az containerapp up создает образ контейнера в облаке, поэтому для этого шага не требуется Docker.

  1. Задайте переменные среды:

    RESOURCE_GROUP="mcp-tutorial-rg"
    LOCATION="eastus"
    ENVIRONMENT_NAME="mcp-env"
    APP_NAME="tasks-mcp-server"
    
  2. Создайте группу ресурсов:

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  3. Создайте среду приложений контейнеров:

    az containerapp env create \
        --name $ENVIRONMENT_NAME \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION
    
  4. Разверните приложение контейнера:

    az containerapp up \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --environment $ENVIRONMENT_NAME \
        --source . \
        --ingress external \
        --target-port 8080
    
  5. Настройте CORS, чтобы разрешить запросы GitHub Copilot.

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

    Замечание

    Для производственной среды замените подстановочные знаки * определенными доверенными источниками. См. руководство по серверам Secure MCP в контейнерных приложениях.

  6. Проверьте развертывание:

    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 к развернутому серверу

Теперь, когда сервер MCP запущен в Azure, настройте VS Code для подключения GitHub Copilot к развернутой конечной точке.

  1. В проекте создайте или обновите .vscode/mcp.json:

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

    Замените <your-app-fqdn> полным доменным именем из выходных данных развертывания.

  2. В VS Code откройте чат Copilot в режиме агента.

  3. Если сервер не появляется автоматически, выберите кнопку «Сервис» и проверьте, отображается ли tasks-mcp-server. При необходимости нажмите кнопку "Пуск ".

  4. Проверьте, как сервер MCP отвечает на запрос "Перечислить все мои задачи", чтобы убедиться в его правильной работе после развертывания.

Настройка масштабирования для интерактивного использования

По умолчанию приложения контейнеров Azure могут масштабироваться до нуля реплик. Для серверов MCP, которые обслуживают интерактивных клиентов, таких как Copilot, холодные запуски вызывают заметные задержки. Задайте минимальное число реплик для поддержания по крайней мере одного экземпляра:

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

Вопросы безопасности

В этом руководстве для простоты используется неавтоентизованный сервер MCP. Перед запуском сервера MCP в рабочей среде ознакомьтесь со следующими рекомендациями. Когда агент, работающий на больших языковых моделях (LLM), вызывает сервер MCP, учитывайте атаки инъекции команд.

  • Проверка подлинности и авторизация. Защита сервера MCP с помощью идентификатора Microsoft Entra. См. раздел "Безопасные серверы MCP" в приложениях контейнеров.
  • Проверка входных данных: всегда проверяйте параметры средства. Используйте заметки данных или FluentValidation в ASP.NET Core. См. проверку модели в ASP.NET Core.
  • HTTPS: приложения контейнеров Azure по умолчанию применяют ПРОТОКОЛ HTTPS с автоматическими сертификатами TLS.
  • Минимальные привилегии: предоставляйте только те инструменты, которые требуются для вашего случая. Избегайте средств, выполняющих разрушительные операции без подтверждения.
  • CORS: ограничение разрешенных источников доверенным доменам в рабочей среде.
  • Ведение журнала и мониторинг: Запись вызовов инструментов MCP для аудита. Используйте Azure Monitor и Log Analytics.

Очистите ресурсы

Если вы не планируете продолжать использовать это приложение, удалите группу ресурсов, чтобы удалить все ресурсы, созданные в этом руководстве:

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

Следующий шаг