MCP

MCP (Model Context Protocol) — открытый протокол от Anthropic (ноя 2024), де-факто стандарт 2025–2026: единый интерфейс между LLM и внешним миром (tools + resources + prompts). «USB-C для AI-агентов».

Суть

Вместо того чтобы писать интеграцию под каждую пару (модель × сервис), пишешь MCP-сервер один раз — и его подключает любая LLM-среда (Claude, Cursor, VS Code, ChatGPT).

Зачем это нужно

Снимает комбинаторный взрыв интеграций. Объединяет «руки» (Tool Calling) и базу знаний (RAG) агента под одним интерфейсом — то есть закрывает сразу tools + resources в Agent Anatomy.

Как работает

  • Сервер выставляет три вида возможностей: tools (действия), resources (данные), prompts (шаблоны).
  • Готовые серверы: Gmail, Google Drive, Slack, Linear, Notion, GitHub, Calendar, n8n — десятки.
  • Принцип: «написал сервер один раз — работает со всеми моделями».
  • MCP — это «транспорт» / способ реализации, а не «магия памяти»: через него агенты общаются между собой и с инструментами (например, ходят в долгосрочную память или делают RAG по кодовой базе). Как именно реализовать хождение в память — через MCP, свою прослойку или API — вопрос проектирования. В одной из разобранных реализаций на MCP строят коммуникацию компонентов мультиагентной системы.
  • MCP как узел графа vs как tool: обычно MCP-инструмент вызывает сама LLM (Tool Calling). Но в LangGraph MCP-сервер можно подключить и как отдельный узел графа, в который ведёт условное ребро — вызов решает код, а не модель (детерминизм, экономия токенов, видимость на диаграмме). Типично для fallback-цепочки RAG→MCP (см. LangGraph MCP as Node).

Пример

Реестр инструментов: каждый инструмент — единая обёртка (имя, описание, JSON-схема, handler), to_openai_spec() отдаёт его в формате, понятном любой LLM. Реестр собирается в один список tools — это и есть «написал один раз → работает со всеми моделями».

class MCPTool:                       # единая обёртка инструмента (совместима с OpenAI/MCP)
    def __init__(self, name, description, schema, handler):
        self.name, self.description = name, description
        self.schema, self.handler = schema, handler      # JSON-схема аргументов + Python-функция

    def to_openai_spec(self):        # один формат -> понимает любая LLM (GPT/Claude/Ollama)
        return {"type": "function", "function": {
            "name": self.name, "description": self.description, "parameters": self.schema}}

registry = {                         # реестр доступных инструментов
    "read_file": MCPTool("read_file", "Читает файл с диска.",
                         {"type": "object", "properties": {"filepath": {"type": "string"}}},
                         handler=lambda filepath: open(filepath).read()),
}
tools_for_llm = [t.to_openai_spec() for t in registry.values()]   # единым списком в параметр tools

Важная оговорка к этому примеру: MCP в нём нет. Несмотря на имя класса, здесь показан реестр функций для tool calling — своя обёртка, отдающая спецификацию в формате tools у API модели. Ни одного элемента протокола тут не задействовано: нет JSON-RPC, нет разделения на хост, клиент и сервер, нет транспорта (stdio или HTTP), нет двух примитивов из трёх — resources и prompts.

Пример иллюстрирует верную мысль — «описал инструмент один раз, отдал любой модели», — но эта мысль про единый формат описания функций, а не про MCP. Настоящий MCP-сервер отличается тем, что живёт отдельным процессом, разговаривает по протоколу и обнаруживается клиентом, а не собирается в словарь внутри вашего кода. Путать эти два уровня опасно на проектировании: из «у меня уже есть реестр инструментов» не следует «у меня уже есть MCP», и ни одно из пяти условий окупаемости ниже такой реестр не закрывает.

Когда MCP, а когда проще без него

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

Способ Когда уместен
Функция или SDK внутри процесса инструмент ваш, живёт в том же коде, переиспользовать некому
Прямой вызов API (REST/OpenAPI) сервис внешний, но нужен одному агенту и меняется вместе с ним
CLI функциональность уже есть в терминале, оборачивать её в сервис избыточно
MCP см. критерии ниже

MCP окупается, когда выполняется хотя бы одно:

  • переиспользование — инструментами пользуются несколько агентов или команд;
  • удалённость — агент работает в песочнице или вебе и не может дотянуться до внутренностей напрямую;
  • безопасность — авторизацию нужно держать вне промпта;
  • независимый цикл обновления — сервер обновляется отдельно от агентов;
  • динамическое обнаружение — набор инструментов меняется и агент должен узнавать о новых сам.

Если ни одно не выполняется, MCP добавляет слой, за который придётся платить отладкой: ошибка может жить в модели, хосте, клиенте или сервере, и локализовать её сложнее, чем в прямом вызове.

Чего протокол не приносит. Права, политика подтверждений и журнал действий остаются на вашей стороне — MCP отвечает за подключение, а не за управление. Отдельная работа — валидация прикладного результата: ответ 200 от сервера не означает, что бизнес-действие выполнено правильно. И к чужому MCP-серверу стоит относиться как к любой внешней зависимости: лимиты, четыре уровня ошибок, тестирование перед тем, как пускать в прод.

Три примитива: инструменты — только треть стандарта

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

Примитив Кто решает, что он сработает Зачем нужен
tools модель действия и способности агента
resources приложение данные в контекст без хода модели
prompts пользователь готовые проверенные команды

Формулировка, которая помогает не путать: tools служат модели, resources — приложению, prompts — пользователю.

Практический критерий выбора: нужны агенту руки — это tool; нужно положить данные в контекст или показать их в интерфейсе — resource; нужен готовый сценарий, запускаемый человеком по клику, — prompt.

Узнаваемые примеры со стороны интерфейса: упоминания через «собаку» и подключение файлов из хранилища — это resources, слэш-команды и кнопки-воркфлоу — prompts.

Учебный каталог отстаёт от спецификации

Программа Anthropic Academy всё ещё перечисляет sampling, roots, logging notifications, stateful/stateless sessions и SSE как advanced topics. Это полезная карта старых ревизий, но не описание текущего протокола. В версии MCP 2026-07-28:

  • roots, sampling и protocol logging помечены deprecated; новые реализации не должны на них строиться;
  • roots всегда были информационной подсказкой, а не access-control boundary — сервер протоколом не удерживается внутри объявленных путей;
  • вместо sampling рекомендуется прямое подключение сервера к API провайдера модели;
  • для logging рекомендуются stderr при stdio и OpenTelemetry для структурированной наблюдаемости;
  • progress notifications остались request-scoped механизмом текущей ревизии.

Такой разрыв — самостоятельный урок для работы с учебными материалами: curriculum показывает, чему курс обещает научить, но версия протокола проверяется по спецификации в момент реализации.

Транспорт без протокольной сессии

Текущая ревизия оставляет два стандартных транспорта: локальный stdio и Streamable HTTP. В HTTP каждое JSON-RPC сообщение идёт отдельным POST; ответ — один JSON-объект либо привязанный к этому запросу SSE stream с progress/logging notifications и финальным результатом.

Версия 2026-07-28 убрала GET stream и protocol-level sessions. Долгие server-to-client взаимодействия теперь выражаются иначе:

  • MRTR возвращает InputRequiredResult, после чего клиент повторяет исходный запрос с ответами и непрозрачным requestState;
  • subscriptions/listen открывает отдельный долгоживущий поток для явно выбранных change notifications.

MRTR позволяет обработать повтор на другом экземпляре без shared session storage, но requestState приходит обратно как недоверенный ввод. Если он влияет на полномочия или бизнес-логику, сервер защищает целостность, principal, срок жизни и связь с исходным запросом. Долговечные approvals, idempotency и бизнес-состояние всё равно живут вне transport stream.

Место MCP в стеке интеграции

Экономическая формулировка того, зачем стандарт вообще появился: он превращает задачу N×M интеграций (N моделей × M источников данных) в 1×N — источник оборачивается один раз, а не под каждую модель. Именно это, а не удобство API, сделало его отраслевым стандартом подключения инструментов.

MCP занимает средний уровень в четырёхслойном стеке и не подменяет соседние (AI Integration Patterns):

Уровень Стандарт Что решает
Транспорт JSON-RPC 2.0 Независимые запросы поверх stdio или Streamable HTTP; request-scoped SSE
Семантика MCP Единый интерфейс к БД, файловой системе, корпоративному сервису
Поведение A2A Делегирование цели между агентами (Agent2Agent Protocol)
Переносимость ONNX Запуск модели вне тяжёлого Python-окружения

Практическое следствие для регулируемого контура: внешний MCP-сервер — это внешний API, и проходит он тот же контур проверки информационной безопасности. Публичные каталоги MCP-серверов зарубежных провайдеров не подходят для обработки чувствительных данных без отдельного контура изоляции, потому что подключение через стандартный протокол не меняет юрисдикцию хостинга (RU AI Regulatory).

Соседние протоколы: четыре вопроса, а не один стек

Таблица выше про слои интеграции. Рядом сложился другой разрез — открытые протоколы вокруг агента, и они не конкурируют, потому что отвечают на разные вопросы:

Протокол Вопрос Кто на другом конце
MCP что агент умеет серверы инструментов и данных, к которым агент подключается сам
Agent2Agent Protocol как агенты разговаривают друг с другом другой агент
Agent Client Protocol кто пускает агента в среду и опосредует его действия поверхность, владеющая файлами, терминалом и правами
AG UI Protocol как происходящее попадает к человеку в интерфейс пользовательское приложение

Роль слова «клиент» в первом и третьем — противоположная, и это главная ловушка разреза. В MCP клиентом является сам агент: он тянется наружу за возможностями. В ACP клиент — редактор или другая поверхность, а агент запускается ею как подпроцесс и просит разрешения. Одно слово, два конца.

Стыкуются они без конфликта: агент, подключённый к редактору по ACP, остаётся MCP-клиентом для своих инструментов.

MCP как контрактный слой, а не просто транспорт

Взгляд, дополняющий «N×M → 1×N»: ценность стандарта не в том, что он избавляет от адаптеров, а в том, что он выносит адаптеры из ядра рантайма. Ядро работает с возможностями, описанными контрактом, и не знает, чем они реализованы; интеграционная сложность остаётся снаружи и меняется, не трогая оркестрацию.

Практическое следствие для проектирования: внешнюю интеграцию нельзя считать «просто функцией». У неё есть свой профиль изоляции (Agent Sandboxing), свой класс риска и своя операционная семантика (Tool Catalog) — и всё это описывается в контракте возможности, а не выводится из имени инструмента.

Отсюда же требование к результату вызова: песочница должна возвращать не только вывод, но и факты исполнения — что было разрешено, сколько потрачено, какой профиль применялся. Без них расследование упирается в «инструмент вернул строку».

Связано с

  • Supply Chain AI — чужой MCP-сервер как зависимость, а не как настройка

  • Open Knowledge Format — соседний открытый стандарт: MCP даёт доступ к действиям во время выполнения, OKF описывает знание файлами

  • Tool Catalog — что должно лежать в контракте возможности

  • Tool Calling — MCP стандартизирует подключение инструментов

  • Agent Anatomy — MCP = tools + knowledge base под одним интерфейсом

  • RAG — ресурсы/данные тоже отдаются через MCP

  • LangGraph MCP as Node — MCP как узел графа (альтернатива «MCP как tool»)