Привет, Хабр! На связи Дмитрий Бондарев, я backend-разработчик Авито — занимаюсь проектами на стыке разработки и машинного обучения. В первой части этого материала мы обратились к истокам API и существующим ограничениям интерфейса в работе с агентами.

В этой статье обратимся к архитектуре MCP и ключевым принципам протокола, рассмотрим, как он решает проблемы интеграции с агентами. Обсудим вызовы, которые ИИ бросает нашему мышлению и подходу к разработке и бизнесу. И, наконец, сделаем выводы — так ли нужны агенты в работе и повседневной жизни? 

Содержание:

Model Context Protocol: архитектура и решения

MCPModel Context Protocol, — еще называют USB-C для ИИ-приложений, так как с ним можно быстро соединить сервисы между собой и радоваться жизни. Это открытый стандарт для подключения ИИ-ассистентов к источникам данных и документам, в основе которого лежит протокол JSON-RPC 2.0.

Релиз MCP состоялся 25 ноября 2024 года, и спустя всего несколько месяцев после релиза протокола пользователи создали десятки тысяч MCP-серверов. Они есть буквально для всего: например, можно взять мессенджер, загрузить свой API-ключ, и LLM будет общаться через ваш профиль в Telegram. Можно доставать информацию из Slack и Confluence, делать саммари, даже создавать крутые 3D-модели. Например, на одной конференции ребята из Сбера рассказывали, как они строят CAD-модели, которые используют в инженерии.

Архитектура MCP

В основе MCP лежат три взаимосвязанных модуля, каждый из которых отвечает за отдельный аспект взаимодействия между языковой моделью и внешними системами. Архитектура протокола выстроена так, чтобы разделить ответственность между этими компонентами. Это обеспечивает независимость интеграций от конкретной модели и создать единый способ работы с инструментами, данным и пользовательским контекстом.

Источник: https://modelcontextprotocol.io/specification/2025-06-18/architecture 

Client — компонент на стороне хоста, который устанавливает соединение с MCP-сервером, согласует возможности и вызывает предоставленные сервером функции (tools, prompts и т.д.). Может предоставлять серверу сервисы клиента, например sampling. Знает, как работать с MCP-серверами и поддерживает динамические возможности.

Host — хост-приложение, внутри которого работают клиент и модель. Он оркестрирует сессии, маршрутизирует запросы между моделью и несколькими серверами, изолирует их, контролирует доступ и хранит историю диалога.

Server — это уже самостоятельный процесс, публикующий возможности через MCP и обрабатывающий запросы клиента (вызовы инструментов, доступ к ресурсам, предоставление промптов). Не видит полный контекст диалога — вся координация происходит через хост.

Ключевые принципы дизайна MCP

Серверы должны быть простыми в разработке

Хост-приложение берёт на себя сложную оркестрацию, что позволяет быстро разворачивать MCP-серверы, формировать их с чётко определенными возможностями и с минимальными расходами на организацию.

Композиционность архитектуры

Модульный дизайн позволяет изолировать каждую сервисную функциональность, легко комбинировать разные серверы, независимо развивать различные компоненты и создаёт пространство для масштабирования системы. 

Серверы не видят полный контекст диалога

Серверы получают только необходимую контекстную информацию, а полная история разговора остается у хоста. Каждое серверное соединение изолировано, а все взаимодействия между серверами контролирует хост.

Capability Negotiation — согласование возможностей

Это процесс обмена информацией о поддерживаемых функциях между клиентом и сервером при инициализации соединения. Механизм позволяет определить доступные возможности в рамках сессии и оптимизировать взаимодействие между компонентами системы.

При установке соединения клиент отправляет серверу запрос на обнаружение (discovery), а сервер предоставляет структурированное описание всех своих возможностей — какие ресурсы (resources) доступны и какие инструменты (tools) позволяют изменять внешнее состояние (например, отправлять письма или создавать задачи).

Клиенты MCP поддерживают:

  • sampling — механизм пробной проверки возможностей сервера перед их использование,

  • notifications — механизм подписки на обновления от сервера (вместо того, чтобы регулярно опрашивать сервер о его возможностях, клиент «запоминает» интерес к определенным типам событий и ждет уведомлений).

Resources

Приложение самостоятельно определяет моменты обращения к ресурсам и использует полученные результаты для своих задач.

Можно использовать:

  • для сбора данных, необходимых для работы приложения;

  • для обогащения сообщений дополнительным контекстом.

На скриншоте — пример интеграции Claude с Google Drive. Пользователь хочет добавить файлы в запрос. Приложение запрашивает список доступных файлов, а пользователь выбирает нужные для работы.

Использование resources в Claude
Использование resources в Claude

Tools

Это механизм вызова функций, который управляется LLM. Позволяет модели:

  • выполнять необходимые операции в реальном времени,

  • использовать внешние сервисы и функции,

  • обрабатывать запросы с помощью специализированных утилит.

Использование tools в Claude
Использование tools в Claude

Например, мы можем попросить Claude посчитать корень из трёх, используя JavaScript. У Claude есть tools интерпретации JavaScript, который использует этот инструмент для обработки запроса.

Prompts

Шаблоны запросов, которые полностью контролирует пользователь. Он самостоятельно определяет момент их использования в зависимости от своих задач. 

Контроль реализован через:

  • интерактивные команды (slash-команды);

  • кнопочные интерфейсы;

  • элементы меню и другие элементы UI.

Выбор готового промпта из списка
Выбор готового промпта из списка

Промпты применяются для запуска рабочих процессов, автоматизации типовых задач и быстрого выполнения повторяющихся операций.

Тут еще больше контента

Способы подключения MCP (Transport Agnostic)

MCP использует гибкие механизмы подключения, адаптированные под разные сценарии использования

Локальное выполнение (STDIO) обеспечивает:

  • Прямое взаимодействие через стандартные потоки ввода-вывода;

  • Высокую производительность без сетевых задержек;

  • Повышенный уровень безопасности благодаря выполнению операций в локальной изолированной среде;

  • Упрощенную отладку.

Особенности удаленного выполнения (HTTP + SSE):

  • Поддержка HTTP-запросов для вызова инструментов;

  • Поддержка корпоративных стандартов безопасности и авторизации;

  • Server-Sent Events (SSE) для двунаправленной связи;

  • Высокая масштабируемость;

  • Возможность построения распределённой архитектуры.

Как MCP решает проблемы интеграции с LLM-агентами?

Решение проблемы MxN: M+N

Архитектура MCP предлагает решение в формате M+N, в котором:

  • существует единая абстракция для всех инструментов;

  • есть стандартизированный интерфейс взаимодействия;

  • унифицирована схема интеграции.

Источник: https://huggingface.co/learn/mcp-course/unit1/key-concepts

На практике реализация всё же сталкивается с некоторыми ограничениями. Даже продвинутые модели демонстрируют недостаточную эффективность работы с MCP. На сложных задачах точность выполнения операций не превышает 50%, а вероятность ошибок возрастает при увеличении количества шагов.

Однако при всем этом обычный REST в тех же условиях, скорее всего, уже умер бы.

Решение проблемы self-discovery: динамическое обнаружение инструментов

Механизм обнаружения (он же runtime discovery) в MCP реализован через стандартизированные методы, которые позволяют автоматически находить доступные инструменты, получать метаданные о каждом инструменте и определять схемы входных и выходных данных.

// Запрос списка доступных инструментов
{ 
  “jsonrpc”: 2.0”,
  “method”: “tools/list”,
  “id”: 1
}

// Ответ с описанием инструментов
{ 
  “jsonrpc”: “2.0”,
  “result”: {
    “tools”: [
      {
        “name”: “create_report”,
        “description”: “Создает отчет по клиенту”,
        “inputSchema”: { … }
      }
    ]
  },
  “id”: 1
}

Работает runtime discovery следующим образом:

  1. Инициализируется запрос на обнаружение.

  2. Система возвращает список доступных инструментов.

  3. Для каждого инструмента предоставляется уникальное имя, описание функционала, схема вводных параметров и описание входных данных.

Решение проблемы контекста: от stateless к stateful-сессиям

Классические API построены на stateless-принципе, что создает дополнительную нагрузку на LLM-агента, увеличивает вероятность ошибок и время выполнения.

GET /api/tasks?user_id=123&status=active&filter=urgent
GET /api/tasks?user_id=123&status=active&filter=urgent&page=2
POST /api/tasks { “user_id”: 123, “title”: “New task”, … }

Stateful-подход в MCP предлагает решение через встроенные контекстные сессии:

  • Сохраняется контекст диалога;

  • Есть поддержка длительных взаимодействий;

  • Управление состояниями автоматизировано;

  • Оптимизирован обмен данными.

Пример MCP:

// Контекст сохраняется между вызовами
1. “Покажи мои срочные задачи”
2. “Отметь первую как выполненную” // знает о предыдущем списке

Решение проблемы гранулярности: one tool, one human task

Основная проблема классических API — избыточная гранулярность, множество мелких запросов и необходимость множественных вызовов.

Пример REST:

1. GET /user/123
2. GET /user/123/orders
3. GET/orders/456/items
4. POST /reports { user_data, order_data, items_data }
5. PUT /reports/789 { status: “completed” }

Подход MCP ориентирован на высокоуровневые операции, соответствующие человеческим. Характеризуется:

  • едиными инструментами для выполнения комплексных задач;

  • человекочитаемыми интерфейсами;

  • снижением когнитивной нагрузки.

Классический пример рефакторинга API — конвертация 90 отдельных вызовов в 20 высокоуровневых задач.

Пример MCP:

{
  “name”: “generate_customer_report”,
  “description: “Создает полный отчет по клиенту с историей заказов”,
  “parameters”: {
    “customer_id”: 123,
    “period”: “last_month”
  }
} 
Жми сюда!

Решение проблемы выбора инструментов: структурированная организация

Cognitive lead возникает при слишком большом количестве инструментов. Качество выбора падает с ростом числа опций, возникает информационная перегрузка — а это влияет на эффективность работы модели.

// Инструменты организованы по серверам
{
  “filesystem_server”: [“read_file”, “write_file”, “list_directory”],
  “database_server”: [“query_db”, “update_records”],
  “email_server”: [“send_email”, “create_draft”]
}

Структурированный подход MCP включает:

  • Иерархическую организацию — группировку инструментов по серверам;

  • Семантическое описание — понятные для LLM-моделей описания;

  • Контекстную группировку — объединение по сценариям использования.

Двунаправленная связь и server-initiated messages

Серверы могут инициировать сообщения и уведомления.

// Сервер может отправить progress notification
{
  “jsonrpc”: “2.0”,
  “method”: “notifications/progress”,
  “params: {
    “progressToken”: “report_generation_123”,
    “progress”: 75,
    “total”: 100
  }
}
// Сервер может запросить дополнительную информацию:
{
  “jsonrpc”: “2.0”,
  “method”: “sampling/createMessage”,
  “params”: {
    “messages”: [
      {
        “role”: “assistans”,
        “content”: “Для создания отчета нужна дополнительная информация. Какой период включить?”
      }
    ]
  }
}

Архитектурные сдвиги: от детерминизма к адаптивности

Раньше мы думали как архитекторы. Теперь же настало время мыслить как садовники. Потому что мы выращиваем систему, которая создает пространство политик, в которых может жить наш агент. Модель уже недетерминирована, она — почти как живое существо.

Классическая архитектура предполагает статические графы выполнения.

  • Предопределенные пути — последовательность вызовов известна при разработке.

  • Жёсткая логика — if/else-ветки в коде определяют поведение.

  • Ошибки = баги — неожиданный путь выполнения это ошибка разработчика.

MCP — это высокоуровневые инструменты, мимикрирующие человеческие задачи.

  • Адаптивные пути — модель выбирает стратегию выполнения в runtime.

  • Контекстные решения — выбор инструментов зависит от текущей ситуации.

  • Неопределённость как норма — система должна адаптироваться к новым сценариям.

Мы переходим от программирования алгоритмов к программированию возможностей, а от однонаправленной связи — к двунаправленной.

Классические API подразумевают только request-response, MCP же — встроенную двунаправленность, которая создает более богатое взаимодействие, приближенное к человеческому диалогу, где любая сторона может инициировать сообщение.

Архитектурная метафора: от заводского конвейера к живому организму

Раньше мы работали с «конвейером» — задача шла от этапу к этапу. Теперь же в наших руках что-то очень похожее на человеческий организм. Образно говоря, у модели есть мозг, и нужно, чтобы MCP-сервисы  — конечности, органы, — уживались между собой. Различные органы взаимодействуют через общую нервную систему, то есть хоста, а сама модель способна к обучению и эволюции. Мы становимся в какой-то степени творцами этой эволюции, а не проектировщиками заводов. Это требует сдвига мышления — и у архитектора, и у разработчиков.

Кликни здесь и узнаешь

Практика внедрения: паттерны, безопасность, примеры

Мы не ожидали, что код моделей может стать настолько вероятностным. Непредсказуемость поведения агентов потребовала разработки особых паттернов и создания новых механизмов контроля и защиты, таких как AI Gateway — промежуточного сервиса, служащего единой точкой входа и контроля графика между клиентом и агентом.

Архитектурные паттерны агентов строятся на следующих принципах:

  • MCP в роли защитного фасада для микросервисов.

  • REST-вызовы объединяются в высокоуровневые инструменты.

  • управление транзакционностью реализуется в новой архитектуре. 

Централизованный контроль через AI Gateway — важнейший компонент архитектуры. Он выполняет функции обработки MCP-трафика через специализированный слой (например, Azure API Managment), внедрения системы лимитов, валидации аргументов мониторинга и аудита. Кроме того, Gateway контролирует политики и защищает клиент от prompt injection.

Атака ShadowLeak

Эра ИИ привнесла новые, специфические риски. Нередки случаи prompt-injection атак — манипуляций через внедрение вредоносных промптов, и создания фальшивых инструментов-двойников, компрометирующих систему. 

Один из самых известных случаев утечки данных произошел в июне 2025 года. На Gmail пользователя пришло инициированное письмо. Пользователь запросил через ИИ-агент саммари всех новых писем, но из-за внедренного в письмо обращения злоумышленников данные пользователя были скомпрометированы.

Схема работает так: к системе, содержащей чувствительные данные (например, к электронной почте) подключен агент. При недостаточной защите агента злоумышленники могут пробраться через уязвимость в системе и, внедрив свой запрос, получить данные пользователя.

Источник: https://www.radware.com/blog/threat-intelligence/shadowleak/

Этот инцидент заставил пересмотреть подходы к безопасности. Теперь важно доверять не только разработчику — нужен комплексный контроль поведения агента. Система решений должна функционировать на уровне отдельных инструментов, а непредсказуемое поведение агента важно моделировать ещё на этапе разработки.

Классические bootstrap примеры

Код на GO: MCP server

type Input struct {
	Name string `json:"name" jsonschema:"the name of the person to greet"`
}

type Output struct {
	Greeting string `json:"greeting" jsonschema:"the greeting to tell to the user"`
}

func SayHi(ctx context.Context, req *mcp.CallToolRequest, input Input) (
	*mcp.CallToolResult,
	Output,
	error,
) {
	return nil, Output{Greeting: "Hi " + input.Name}, nil
}

func main() {
	// Create a server with a single tool.
	server := mcp.NewServer(&mcp.Implementation{Name: "greeter", Version: "v1.0.0"}, nil)
	mcp.AddTool(server, &mcp.Tool{Name: "greet", Description: "say hi"}, SayHi)
	// Run the server over stdin/stdout, until the client disconnects.
	if err := server.Run(context.Background(), &mcp.StdioTransport{}); err != nil {
		log.Fatal(err)
	}
}

Код на Python: MCP server

from mcp.server.fastmcp import FastMCP

mcp = FastMCP(name="Tool Example")

@mcp.tool()
def sum(a: int, b: int) -> int:
    """Add two numbers together."""
    return a + b

@mcp.tool()
def get_weather(city: str, unit: str = "celsius") -> str:
    """Get weather for a city."""
    # This would normally call a weather API
    return f"Weather in {city}: 22degrees{unit[0].upper()}"

Делаем выводы

Model Context Protocol, хоть и не целиком, решает главные проблемы интеграции с языковыми моделями и меняет саму парадигму работы с агентами. Это больше не жесткий алгоритм, а среда, в которой ИИ-агент может гибко адаптироваться и принимать решения.

С правильным подходом агент может стать не просто инструментом, а партнером в решении бизнес-задач. Однако реализация требует дополнительных расходов и рисков, при этом не всегда действительно повышает эффективность решения задач. И в большинстве случаев это заставляет задуматься о целесообразности применения агентов.

Когда имеет смысл применять агентов?

  • Вы не можете заранее определить последовательность шагов и выбираете их в процессе выполнения задачи;

  • Жёсткая автоматизация не окупится из-за редкости задачи или высокой вариативности сценариев;

  • Часто меняются данные, политики, приоритеты и стратегии.

В других случаях классического workflow должно быть достаточно.


Кстати, если вам интересна работа в бигтехе —  Хабр совместно с ЭКОПСИ проводит большое исследование IT-брендов работодателей. В прошлом году в нём поучаствовали 34 000 специалистов. Если у вас есть опыт — он точно будет учтён.