- Дата публикации
MCP‑приложения с интерактивным UI на Azure App Service: как собрать и развернуть за 10 минут
Что нового
Microsoft предлагает хостить MCP Apps — веб‑приложения с интерактивным интерфейсом для ИИ‑чатов — на Azure App Service.
Ключевые новшества:
- MCP Apps как расширение Model Context Protocol:
- Инструменты (tools) теперь могут возвращать не только JSON, но и богатый UI, который рендерится прямо в чате.
- Поддерживаются клиенты: Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman и другие MCP‑совместимые клиенты.
- Единый UI для разных клиентов:
- Один и тот же HTML/JS/CSS‑интерфейс работает во всех поддерживаемых клиентах.
- MCP Apps — это обычные веб‑приложения, которые отдаются через MCP.
- Готовый пример:
- Полноценный образец MCP‑приложения «виджет погоды».
- ASP.NET Core — сервер MCP.
- Vite + TypeScript — фронтенд, собираемый в один
index.html. - Весь стек разворачивается на Azure App Service за один запуск
azd up.
- Интеграция с Azure App Service:
- Always On — без cold start, UI отдается сразу.
- Easy Auth с Entra ID — защита MCP‑эндпойнта без дополнительного кода.
- Пользовательские домены и TLS — MCP‑сервер с вашим доменом и управляемыми сертификатами.
- Deployment slots — поэтапные выкаты без простоя.
- Sidecar‑контейнеры — Redis, очереди, мониторинг рядом с MCP‑сервером.
- Application Insights — телеметрия по вызовам инструментов и UI.
- Два варианта хостинга MCP Apps:
- Azure Functions — serverless‑режим с масштабированием до нуля.
- Azure App Service — постоянный хостинг без cold start и с «тяжелыми» продакшн‑фичами.
Цифр по производительности и цене в материале нет, но есть четкая связка: serverless‑экономика у Functions, всегда включенный продакшн‑хостинг у App Service.
Как это работает
MCP Apps: что это технически
MCP Apps расширяют Model Context Protocol так:
- Tool объявляет UI‑ресурс:
- В метаданных инструмента появляется поле
_meta.ui.resourceUri. - Пример:
"ui://weather/index.html".
- В метаданных инструмента появляется поле
- Хост MCP запрашивает UI:
- Когда клиент (например, VS Code Copilot) вызывает инструмент, хост MCP:
- выполняет этот инструмент;
- по
resourceUriзапрашивает UI‑ресурс у MCP‑сервера.
- Когда клиент (например, VS Code Copilot) вызывает инструмент, хост MCP:
- Клиент рендерит UI в iframe:
- UI загружается в изолированный iframe внутри чата.
- Внутри iframe TypeScript‑приложение общается с хостом через
postMessageчерез SDK@modelcontextprotocol/ext-apps.
По факту MCP App — это обычный веб‑фронтенд, упакованный в один HTML‑файл и выдаваемый как MCP‑ресурс с особым MIME‑типом.
Архитектура примера «виджет погоды»
Структура репозитория:
app-service-mcp-app-sample/
├── src/
│ ├── Program.cs # Настройка MCP-сервера на ASP.NET Core
│ ├── WeatherTool.cs # MCP-инструмент с описанием UI
│ ├── WeatherUIResource.cs # MCP-ресурс, который отдает HTML
│ ├── WeatherService.cs # Работа с Open-Meteo API
│ └── app/ # Фронтенд на Vite (виджет погоды)
│ └── src/
│ └── weather-app.ts # Интеграция с MCP Apps SDK
├── .vscode/
│ └── mcp.json # Конфиг MCP-сервера для VS Code
├── azure.yaml # Конфиг Azure Developer CLI
└── infra/ # Bicep-инфраструктура
``
#### MCP‑сервер: Program.cs
ASP.NET Core‑приложение поднимает MCP‑сервер и регистрирует инструменты и ресурсы:
```csharp
using ModelContextProtocol;
var builder = WebApplication.CreateBuilder(args);
// Register WeatherService
builder.Services.AddSingleton<WeatherService>(sp =>
new WeatherService(WeatherService.CreateDefaultClient()));
// Add MCP Server with HTTP transport, tools, and resources
builder.Services.AddMcpServer()
.WithHttpTransport(t => t.Stateless = true)
.WithTools<WeatherTool>()
.WithResources<WeatherUIResource>();
var app = builder.Build();
// Map MCP endpoints (no auth required for this sample)
app.MapMcp("/mcp").AllowAnonymous();
app.Run();
Что важно под капотом:
AddMcpServer()— регистрирует обработчик MCP‑протокола.WithHttpTransport(t => t.Stateless = true)— включает HTTP‑транспорт в статeless‑режиме, без хранения сессий.WithTools<WeatherTool>()— регистрирует MCP‑инструмент.WithResources<WeatherUIResource>()— регистрирует UI‑ресурс.MapMcp("/mcp")— MCP‑эндпойнт по пути/mcp.
Инструмент с UI‑метаданными: WeatherTool.cs
Инструмент объявляет resourceUri в метаданных через атрибут McpMeta:
using System.ComponentModel;
using ModelContextProtocol.Server;
[McpServerToolType]
public class WeatherTool
{
private readonly WeatherService _weatherService;
public WeatherTool(WeatherService weatherService)
{
_weatherService = weatherService;
}
[McpServerTool]
[Description("Get current weather for a location via Open-Meteo. Returns weather data that displays in an interactive widget.")]
[McpMeta("ui", JsonValue = """{"resourceUri": "ui://weather/index.html"}""")]
public async Task<object> GetWeather(
[Description("City name to check weather for (e.g., Seattle, New York, Miami)")]
string location)
{
var result = await _weatherService.GetCurrentWeatherAsync(location);
return result;
}
}
Ключевая строка:
[McpMeta("ui", JsonValue = """{"resourceUri": "ui://weather/index.html"}""")]
Она добавляет в описание инструмента блок _meta.ui.resourceUri, на который ориентируется MCP‑хост. Когда ИИ‑клиент вызывает GetWeather, хост берет ui://weather/index.html и запрашивает соответствующий ресурс.
UI‑ресурс: WeatherUIResource.cs
Этот класс отдает собранный index.html как MCP‑ресурс с нужным MIME‑типом:
using ModelContextProtocol.Protocol;
using ModelContextProtocol.Server;
[McpServerResourceType]
public class WeatherUIResource
{
[McpServerResource(
UriTemplate = "ui://weather/index.html",
Name = "weather_ui",
MimeType = "text/html;profile=mcp-app")]
public static ResourceContents GetWeatherUI()
{
var filePath = Path.Combine(
AppContext.BaseDirectory, "app", "dist", "index.html");
var html = File.ReadAllText(filePath);
return new TextResourceContents
{
Uri = "ui://weather/index.html",
MimeType = "text/html;profile=mcp-app",
Text = html
};
}
}
Важно:
- URI‑схема
ui://— для UI‑ресурсов MCP Apps. - MIME‑тип
text/html;profile=mcp-app— сигнал клиенту MCP, что это MCP App. - Файл берется из
app/dist/index.html— это результат сборки Vite.
Логика погоды: WeatherService.cs
WeatherService использует Open‑Meteo API:
- геокодирует название города;
- запрашивает текущие погодные данные;
- возвращает результат в виде объекта, который потом получает UI.
Это обычный HTTP‑клиент на .NET, без специфики MCP.
Фронтенд MCP App: Vite + SDK
Фронтенд живет в src/app и собирается Vite в один HTML‑файл. Взаимодействие с MCP‑хостом — через SDK @modelcontextprotocol/ext-apps:
import { App } from "@modelcontextprotocol/ext-apps";
const app = new App({ name: "Weather Widget", version: "1.0.0" });
// Handle tool results from the server
app.ontoolresult = (params) => {
const data = parseToolResultContent(params.content);
if (data) render(data);
};
// Adapt to host theme (light/dark)
app.onhostcontextchanged = (ctx) => {
if (ctx.theme) applyTheme(ctx.theme);
};
await app.connect();
Что делает SDK:
- устанавливает соединение с хостом MCP через
postMessage; - получает результаты вызова инструмента (
ontoolresult); - реагирует на изменения контекста хоста (
onhostcontextchanged) — например, смену темы.
Сборка Vite с vite-plugin-singlefile складывает HTML, JS и CSS в один index.html. Это удобно для MCP: UI отдается как один ресурс.
Почему Azure App Service подходит для MCP Apps
Технически App Service делает то, что MCP Apps требуют по максимуму:
- Постоянный хостинг: .NET‑приложение с MCP‑сервером работает без остановки, UI‑ресурсы отдаются без задержек.
- HTTP‑эндпойнт
/mcp: MCP‑клиенты подключаются по HTTP, как к обычному веб‑сервису. - Интеграция с инфраструктурой Azure:
- Entra ID для аутентификации;
- слоты развертывания для безопасных обновлений;
- sidecar‑контейнеры для Redis, очередей, агентов мониторинга;
- Application Insights для логов и метрик вызовов MCP‑инструментов и UI.
Что это значит для вас
Когда использовать MCP Apps на Azure App Service
Этот стек полезен, если вы:
- Строите сложные инструменты для ИИ‑клиентов:
- дашборды аналитики;
- визуализацию карт;
- просмотрщики PDF и документов;
- интерфейсы для управления системами.
- Хотите, чтобы эти интерфейсы работали одинаково в Claude Desktop, ChatGPT, VS Code Copilot и других MCP‑клиентах.
- Уже используете Azure и хотите развернуть MCP‑сервер рядом с другими сервисами.
- Нуждаетесь в:
- отсутствии cold start;
- защищенных эндпойнтах с Entra ID;
- продакшн‑процессах деплоя (слоты, мониторинг, домены).
Когда лучше Azure Functions, а не App Service
Microsoft предлагает простой ориентир:
Azure Functions — если вы:
- пишете новое MCP‑приложение с нуля;
- хотите serverless‑модель: масштабирование до нуля и оплата по вызовам;
- можете терпеть возможный cold start (или готовы платить за Premium‑план для его снижения);
- делаете event‑driven‑сценарии, где MCP — один из триггеров.
Azure App Service — если вы:
- добавляете MCP‑функциональность к существующему веб‑приложению;
- хотите всегда включенный сервер без cold start;
- вам нужны постоянное состояние или интеграция с другими сервисами в рамках одного App Service;
- планируете использовать Easy Auth, custom domains, deployment slots, sidecar‑контейнеры.
Таблично это выглядит так:
- Масштабирование:
- Functions: масштаб до нуля, оплата по запросам.
- App Service: выделенный план, приложение всегда работает.
- Cold start:
- Functions: возможен (снижается Premium‑планом).
- App Service: нет, при включенном Always On.
- Деплой:
- Functions:
azd upс шаблоном Functions. - App Service:
azd upс шаблоном App Service.
- Functions:
- Специализация:
- Functions: триггеры событий, durable‑функции.
- App Service: Easy Auth, домены, слоты, sidecar‑сервисы.
Где это реально помогает
Конкретные сценарии:
- Командные инструменты внутри компании:
- Внутренний дашборд, который открывается прямо в ChatGPT или Copilot.
- Безопасный доступ через Entra ID, без раздачи ключей и VPN‑доступа к базе.
- Продукты для разработчиков:
- Расширения для VS Code Copilot, которые показывают UI внутри чата.
- Отладка и мониторинг сервисов через MCP‑инструменты.
- Клиентские сервисы:
- Виджеты погоды, курсов валют, аналитики, которые живут в чат‑клиентах.
- Один код UI — сразу в нескольких ИИ‑клиентах.
Когда это не ваш вариант
- Вам нужен простой текстовый инструмент без UI. В этом случае MCP Apps — лишний слой, достаточно обычного MCP‑инструмента.
- Вы не хотите связываться с Azure, предпочитаете другой облачный провайдер или on‑prem.
- У вас нет задач, где UI внутри ИИ‑чата дает выигрыш по UX.
Доступность из России
Azure и связанные сервисы, включая Azure App Service, официально ограничены для пользователей и компаний из России. Для работы может потребоваться зарубежный аккаунт, зарубежный способ оплаты и, в ряде случаев, VPN для доступа к порталу и API.
Если вы работаете из российской юрлицы, такой стек чаще всего подходит только для проектов, ориентированных на зарубежные рынки и инфраструктуру за пределами России.
Место на рынке
MCP Apps — это не модель и не облачный API, а способ встроить богатый UI в ИИ‑клиенты. Конкуренция здесь не между GPT‑5 и Claude 4, а между подходами к интеграции интерфейсов.
По сути, MCP Apps на Azure App Service конкурируют с:
- собственными плагин‑системами отдельных ИИ‑клиентов;
- кастомными веб‑панелями, которые пользователь открывает отдельно от чата;
- serverless‑подходом на Azure Functions.
Что дает связка MCP Apps + Azure App Service:
- Кросс‑клиентный UI: один интерфейс работает в Claude Desktop, ChatGPT, VS Code Copilot и других MCP‑клиентах.
- Интеграция с Azure‑инфраструктурой: Entra ID, App Insights, deployment slots, sidecar‑сервисы.
- Отсутствие cold start по сравнению с Functions в базовой конфигурации.
Чего нет:
- Нет конкретных сравнений по скорости отклика или стоимости с другими облаками.
- Нет прямых бенчмарков против альтернативных протоколов расширения.
Если вы уже глубоко сидите в Azure и строите инструменты вокруг Copilot, MCP Apps на App Service выглядят логичным продолжением этой экосистемы.
Установка
Для локального запуска понадобится:
- .NET 9 SDK;
- Node.js 18+;
- Git и Azure Developer CLI (
azd) для деплоя.
Клонирование и локальный запуск
# Clone the repo
git clone https://github.com/seligj95/app-service-mcp-app-sample.git
cd app-service-mcp-app-sample
# Build the frontend
cd src/app
npm install
npm run build
# Run the MCP server
cd ..
dotnet run
Сервер поднимется на http://localhost:5000.
Подключение к VS Code Copilot
В репозитории уже есть конфиг MCP‑сервера для VS Code:
{
"servers": {
"local-mcp-appservice": {
"type": "http",
"url": "http://localhost:5000/mcp"
}
}
}
Шаги:
- Откройте репозиторий в VS Code.
- Убедитесь, что файл
.vscode/mcp.jsonна месте. - Откройте панель GitHub Copilot Chat.
- Спросите:
"What's the weather in Seattle?".
Copilot вызовет инструмент GetWeather, а виджет погоды отрендерится прямо в чате в виде интерактивного UI.
Как запустить на Azure App Service
Деплой через Azure Developer CLI
В корне репозитория уже лежат azure.yaml и Bicep‑шаблоны. Деплой сводится к одной команде:
cd app-service-mcp-app-sample
azd auth login
azd up
azd up сделает следующее:
- создаст App Service Plan и Web App в вашей подписке Azure;
- соберет .NET‑приложение и фронтенд на Vite;
- задеплоит приложение на Azure App Service;
- выведет публичный URL MCP‑эндпойнта.
После деплоя вы увидите адрес вида:
https://app-abc123.azurewebsites.net
Подключение удаленного MCP‑сервера
Обновите .vscode/mcp.json, чтобы подключаться к удаленному серверу:
{
"servers": {
"remote-weather-app": {
"type": "http",
"url": "https://app-abc123.azurewebsites.net/mcp"
}
}
}
Теперь ваш MCP App живет в облаке. Любой клиент, который поддерживает MCP Apps, может вызывать инструмент погоды и рендерить интерактивный виджет, не полагаясь на локальный сервер разработчика.
Что попробовать дальше
Если вы уже собрали пример с погодой, логичный следующий шаг — адаптировать его под свои задачи:
- Прочитать спецификацию MCP Apps и добавить:
- формы ввода;
- сохранение состояния;
- многошаговые сценарии.
- Посмотреть примеры
ext-appsна GitHub:- просмотр карт;
- рендеринг PDF;
- системные мониторы и другие UI.
- Попробовать quickstart для MCP Apps на Azure Functions, если хотите serverless‑подход.
- Изучить паттерны хостинга удаленных MCP‑серверов на App Service и добавить:
- Easy Auth с Entra ID;
- App Insights для телеметрии;
- домены и TLS;
- deployment slots для blue/green‑релизов.
Если вы делаете сложные инструменты вокруг ИИ‑чатов и уже используете Azure, MCP Apps на App Service дают понятный путь от прототипа до продакшна с минимальным количеством обвязки вокруг UI и инфраструктуры.