Розгортання MCP-серверів в Azure Container Apps

💡 Усі статті, обговорення, новини про DevOps — в одному місці. Приєднуйтесь до DevOps спільноти!

Незалежно від того, чи створюєте ви AI-агентів, чи використовуєте інструменти на базі LLM, такі як GitHub Copilot у Visual Studio Code, ви, ймовірно, останнім часом багато чуєте про MCP (Model Context Protocol); можливо, ви вже ним користуєтеся. Він швидко стає стандартним рівнем сумісності між різними компонентами AI-стеку.

У цій статті ми розглянемо, як запустити віддалені MCP-сервери як безсерверні контейнери в Azure Container Apps і використовувати їх у GitHub Copilot у Visual Studio Code.

MCP-сервери сьогодні

MCP використовує клієнт-серверну архітектуру. Все починається з клієнта, такого як GitHub Copilot у VS Code або Claude Desktop. Клієнт підключається до одного або кількох MCP-серверів.

Сервери є основними точками розширення в MCP. Кожен сервер надає клієнту нові інструменти, навички та можливості. Наприклад, сервер може надавати пошукову систему, яка дозволяє агенту, що працює в клієнті, здійснювати пошук в Інтернеті. Або агент може використовувати MCP-сервер GitHub для роботи з репозиторіями GitHub. Можливості безмежні.

Більшість MCP-серверів за замовчуванням запускаються локально. Хост, на якому запущено клієнт, запускає кожен сервер як підпроцес, і клієнт взаємодіє з ним, використовуючи стандартний ввід і вивід. Це добре працює для багатьох сценаріїв. З точки зору безпеки це також безпечніше, оскільки сервер не відкритий на порті, і будь-які секрети, необхідні серверу, залишаються локальними для хоста.

Віддалені MCP-сервери

З розвитком MCP спільнота починає досліджувати ідею віддалених MCP-серверів. Це природна еволюція протоколу. Замість запуску локального MCP-сервера, який викликає пошукову систему, уявіть собі підключення до великомасштабного, багатокористувацького, віддаленого MCP-сервера в хмарі, який розміщується та керується постачальником пошукової системи.

MCP все ще перебуває на відносно ранній стадії розвитку, і спільнота все ще розробляє специфікацію для підтримки віддалених серверів.

По-перше, MCP мав підтримувати транспортний рівень, який дозволяє хосту підключатися до віддаленого сервера. Спочатку було додано транспортний рівень HTTP з SSE (Server-Sent Events), але остання специфікація вже відмовляється від нього на користь потокового HTTP-транспорту.

По-друге, тепер, коли існують транспорти, які підтримують віддалені сервери, потрібні способи аутентифікації клієнтів на віддалених серверах. Специфікація в цій області також все ще розвивається.

Створення віддаленого MCP-сервера

На момент написання цієї статті клієнти все ще наздоганяють специфікацію, що розвивається. Такий клієнт, як VS Code, вже підтримує віддалені сервери, але поточна версія підтримує лише SSE-транспорт, і єдиним методом аутентифікації, з яким вона добре працює, є заголовки API-ключів.

Тепер ми розгорнемо віддалений MCP-сервер, використовуючи SSE-транспорт і аутентифікацію за допомогою API-ключа. Для цього, клонуйте репозиторій:

git clone 

github.com/...​ainer-apps-mcp-sample.git

Ми почнемо з метеорологічного MCP-сервера з офіційного швидкого старту (див. weather.py)

Він надає простий інструмент для отримання погоди в заданому місці в Сполучених Штатах. Він запускається локально і взаємодіє з хостом, використовуючи стандартний ввід/вивід.

Щоб додати SSE-транспорт, ми додаємо сервер FastAPI (main.py).

from fastapi import FastAPI, Request, Depends
from mcp.server.sse import SseServerTransport
from starlette.routing import Mount
from weather import mcp
app = FastAPI(docs_url=None, redoc_url=None)
sse = SseServerTransport("/messages/")
app.router.routes.append(Mount("/messages", app=sse.handle_post_message))
@app.get("/sse", tags=["MCP"])
async def handle_sse(request: Request):
async with sse.connect_sse(request.scope, request.receive, request._send) as (
read_stream,
write_stream,
):
init_options = mcp._mcp_server.create_initialization_options()
await mcp._mcp_server.run(
read_stream,
write_stream,
init_options,
)

MCP SDK вже має вбудовану реалізацію SSE-транспорту. Нам потрібно було лише додати сервер FastAPI, який надає кінцеву точку /sse і обробляє кінцеву точку /messages, використовуючи MCP SDK.

А щоб додати аутентифікацію за допомогою API-ключа, ми створюємо функцію, яка перевіряє заголовок x-api-key у запиті та порівнює його зі списком дійсних API-ключів. У складніших сценаріях ми могли б використовувати базу даних або службу керування секретами для зберігання API-ключів і їхнього зіставлення з окремими користувачами.

from fastapi import Security, HTTPException, status
from fastapi.security import APIKeyHeader
import os
api_key_header = APIKeyHeader(name="x-api-key")
def ensure_valid_api_key(api_key_header: str = Security(api_key_header)):
def check_api_key(key: str) -> bool:
valid_keys = os.environ.get("API_KEYS«, «„).split(“,»)
return key in valid_keys and key != ""
if not check_api_key(api_key_header):
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail="Invalid API key«,
)

Потім ми можемо додати функцію ensure_valid_api_key як залежність, щоб її виклик був обов’язковим для будь-якого маршруту на сервері.

app = FastAPI(docs_url=None, redoc_url=None, dependencies=[Depends(ensure_valid_api_key)])

Розгортання сервера в Azure Container Apps

Тепер давайте розгорнемо сервер в Azure Container Apps.

Переконавшись, що ми знаходимося в кореневому каталозі репозиторію, ми можемо виконати наступну команду для розгортання програми разом з усіма необхідними ресурсами:

az containerapp up \
-g <RESOURCE_GROUP> -n weather-mcp —environment mcp \
-l westus —env-vars API_KEYS=<AN_API_KEY> \
—source .

Вона використовує Dockerfile у репозиторії для створення образу контейнера та його розгортання в Azure Container Apps. Прапор —env-vars встановлює змінну середовища API_KEYS у контейнері. Ми повинні надати безпечне значення, і ми можемо додати кілька API-ключів, розділяючи їх комами.

Після завершення розгортання Azure CLI поверне URL-адресу програми.

Підключення до сервера з Visual Studio Code

У VS Code виконайте команду MCP: Add server. Виберіть «HTTP (Server-sent events)» як транспорт і введіть URL-адресу кінцевої точки /sse на сервері (наприклад, weather-mcp.sleepypanda.westus.azurecontainerapps.io/sse).

Відкриється файл конфігурації mcp.json VS Code. Оскільки сервер вимагає API-ключ, внесіть кілька змін:

  • Додайте нове поле вводу promptString для API-ключа. Це запитуватиме у нас API-ключ під час запуску сервера.
  • Додайте заголовок x-api-key до конфігурації сервера. Це надсилатиме API-ключ на сервер під час підключення.
{
«inputs»: [
{
«type»: «promptString»,
«id»: «weather-api-key»,
«description»: «Weather API Key»,
«password»: true
}
],
«servers»: {
«weather-sse»: {
«type»: «sse»,
«url»: «weather-mcp.sleepypanda.westus.azurecontainerapps.io/sse»,
«headers»: {
«x-api-key»: «${input:weather-api-key}»
}
}
}
}

Поруч із сервером у JSON-файлі натисніть кнопку «Start». Це ініціює підключення VS Code до сервера. Вам буде запропоновано ввести API-ключ. Введіть API-ключ, який ми встановили у змінній середовища API_KEYS під час розгортання програми.

Відкрийте інтерфейс чату Copilot, натиснувши Ctrl+Shift+I (Cmd+Shift+I на macOS). Змініть режим на «Agent». Введіть «What’s the weather in San Francisco?» і натисніть Enter. Агент повинен використовувати MCP-сервер і відповісти поточною погодою в Сан-Франциско.

Для отримання додаткової інформації про використання MCP-серверів у VS Code зверніться до документації VS Code.

Висновок

У цій статті ми розглянули, як запустити віддалені MCP-сервери в Azure Container Apps. Ми почали з простого метеорологічного MCP-сервера і додали SSE-транспорт та аутентифікацію за допомогою API-ключа. Потім ми розгорнули сервер в Azure Container Apps і використали його в GitHub Copilot у Visual Studio Code.

👍ПодобаєтьсяСподобалось4
До обраногоВ обраному3
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Підписатись на коментарі