Протоколы · LLM-агенты
MCP: runtime-слой между LLM-хостом и внешними инструментами
Model Context Protocol нужен не потому, что API-вызовы сложны. Он становится полезен, когда много LLM-хостов должны одинаково обнаруживать, вызывать, ограничивать и аудировать много внешних серверов-инструментов.
Ключевые выводы
- Для одного скрипта и одного сервиса прямой HTTP-вызов остаётся правильным ответом.
- OpenAPI описывает HTTP API; MCP задаёт runtime-контракт, по которому LLM-хост обнаруживает и вызывает возможности.
- MCP Client - адаптер внутри хоста. MCP Server - внешний исполнитель, который держит downstream credentials и бизнес-логику.
- Хороший MCP Server курирует инструменты. Он не должен зеркалить каждый endpoint исходного API.
- MCP стандартизирует контракт вызова, но не доверие. Security, filtering, audit, retries и rollback остаются архитектурной работой.
I Начнём с обычного requests-вызова
У вас есть языковая модель и сервис: погода, трекер задач, база данных. Вы хотите, чтобы модель этим сервисом пользовалась, а не просто рассуждала о нём. Первый честный ответ: часто достаточно прямого HTTP-запроса.
Если модель говорит «нужна погода в London», ваш код может вызвать API погоды через requests, вернуть результат модели и на этом остановиться. MCP Server здесь не нужен. Оборачивать один такой вызов в MCP - лишний слой без архитектурной причины.
Потребность появляется, когда вызывающая сторона - не ваш скрипт, хост - не под вашим контролем, а одну и ту же внешнюю возможность должны обнаруживать и вызывать разные независимые runtime.
II Протокол - это правила; сервер - исполнитель
Протокол - набор правил: имена методов вроде tools/list и tools/call, поля описания инструмента, форма ответа, форма ошибки, lifecycle. Правила сами ничего не выполняют.
MCP Server - конкретная программа. Она получает сообщение по протоколу, маппит его на downstream-работу, вызывает реальный API, обрабатывает credentials и ошибки, возвращает результат. Протокол один; серверов много.
Так снимается вопрос «если протокол один, почему серверов много?». HTTP тоже один протокол, но веб-серверов много. Протокол определяет, как говорить; сервер делает работу.
III Что MCP добавляет поверх OpenAPI
MCP не заменяет OpenAPI. Это разные слои. OpenAPI описывает endpoints, параметры, схемы и ответы. MCP задаёт runtime-контракт, по которому LLM Host обнаруживает доступные возможности и вызывает их в стандартной форме.
Статическое описание полезно, но кто-то всё равно должен выполнить вызов, обработать auth, нормализовать ошибки и не дать модели лишнюю поверхность API. MCP добавляет runtime discovery, исполнение, двунаправленные примитивы и одну форму вызова для разных серверов.
На практике слои стыкуются: MCP Server можно сгенерировать из OpenAPI-спеки, а затем сузить до меньшего и безопасного tool catalog.
IV Кто есть кто в одном вызове
Host - приложение, внутри которого живёт модель и оркестрация: desktop assistant, IDE, внутренняя agent platform. Модель находится внутри хоста.
MCP Client - не пользовательское приложение. Это адаптер внутри хоста. Обычно хост создаёт одно MCP Client-соединение на каждый сервер.
MCP Server - внешний исполнитель: граница обёрнутого сервиса. Модель не вызывает его напрямую и не получает service token. Хост спрашивает; сервер исполняет.
V Что реально летит по проводу
MCP использует JSON-RPC 2.0. Для базовой петли достаточно понимать три сообщения: initialize, tools/list и tools/call. Полная спецификация шире: lifecycle, capability negotiation, transports, resources, prompts, authorization, sessions и errors.
Tools - действия. Resources - данные только на чтение, доступные по URI. Prompts - переиспользуемые шаблоны. Разделение важно: прочитать документ у сервера и попросить сервер что-то изменить - разные границы ответственности.
Сравнение подходов к интеграции
За
Против
VI Сервер - куратор, а не зеркало
Слабый MCP Server выставляет исходный API endpoint за endpoint. Полезный сервер проектирует меньший tool catalog для модели: названия ориентированы на задачу, input schemas узкие, небезопасных действий нет, если они специально не разрешены.
Именно здесь интеграция становится архитектурой. Read-only сервер для аналитики, CI-сервер и write-capable сервер для автоматизации могут стоять над одним GitHub API, но иметь разные scopes и разные имена инструментов.
Namespacing - практическая гигиена. Если два сервера выставляют generic search, хост может спутать намерение. Имена вроде github_read_search и github_ci_rerun менее красивые, но безопаснее.
API сервиса
28 endpoints · показаны 14
VII Транспорт: локальный процесс или сетевой сервис
stdio - естественный транспорт для локальных серверов. Хост запускает сервер как дочерний процесс и общается через стандартный ввод-вывод. Это быстро, локально и удобно изолируется процессом, контейнером или sandbox.
Streamable HTTP - актуальный транспорт для удалённых серверов. Один HTTP endpoint принимает сообщения клиента; сервер может ответить JSON или text/event-stream, если нужен progress, несколько сообщений или server-to-client notifications.
У MCP нет глобального реестра серверов. Хост узнаёт, к каким серверам подключаться, out of band: mcp.json, environment variables, настройки IDE, desktop config или managed gateway.
VIII Когда сервер просит слова
Базовая форма проста: client спрашивает, server отвечает. Но в MCP есть и обратные примитивы, важные для agentic workflows.
sampling позволяет серверу попросить хост прогнать что-то через модель. Сервер всё равно не владеет ключом модели. Он просит хост, а хост решает, какую модель использовать, показывать ли prompt и разрешать ли запрос.
elicitation позволяет серверу запросить недостающие данные у пользователя. Так человек остаётся в контуре, а сервер не вынужден угадывать.
IX Минимальный FastMCP skeleton
Маленький сервер может быть тонким слоем вокруг обычного API client. Смысл не в том, что пятнадцать строк production-ready; смысл в том, что в центре остаётся нормальный API-вызов.
# pip install fastmcp
from fastmcp import FastMCP
mcp = FastMCP("github-reader") # read-only server
@mcp.tool()
def find_issues(repo: str, query: str) -> list:
"""Find issues in a repository by text query."""
try:
return github_api.search_issues(repo, query) # inside: ordinary requests
except github_api.RateLimitError as e:
raise RuntimeError(f"GitHub API rate limit exceeded: {e}") from e
@mcp.tool()
def read_pull_request(repo: str, number: int) -> dict:
"""Read pull request details by number."""
return github_api.get_pr(repo, number)
if __name__ == "__main__":
mcp.run() # stdio by default X Ошибки и состояние живут на разных уровнях
Ошибка протокола означает, что само сообщение некорректно: неизвестный метод, невалидная форма, несовместимая версия. Ошибка исполнения инструмента означает, что запрос валиден, но downstream-работа не удалась: rate limit, timeout, upstream 500, invalid repository.
В MCP protocol failures возвращаются как JSON-RPC error. Tool execution failures обычно возвращаются как результат tools/call с isError: true и actionable text, который модель может использовать.
Состояние нужно разделять так же. Protocol sessions могут иметь lifecycle и negotiation, а long-running workflow state должен жить в Host или Orchestrator: branch names, partial results, retry policy, compensation logic и user approvals.
XI MCP не делает систему безопасной за вас
MCP - не DLP, не IAM и не compliance. Если сервер может читать CRM, tickets, repositories или user data, стандарт сам по себе не мешает этим данным попасть в модель или утечь наружу.
Host контролирует, какой context отправляется модели: маскирует PII, применяет workspace policy, убирает лишний output. MCP Server контролирует, что возвращает из downstream systems: меньшие payloads, никаких secrets, никаких внутренних fields без необходимости.
Production safety рождается из allowlisted tools, least-privilege OAuth scopes, audit logs, confirmation prompts для destructive actions, output sanitization и rollback design.
XII Короткие ответы на частые недопонимания
Кто пишет сервер? Вендор сервиса, community maintainer или ваша команда для внутреннего сервиса. Для одного сервиса могут сосуществовать несколько серверов.
Почему сервер, а не библиотека? Библиотека привязана к языку и живёт в процессе хоста. Сервер общается сообщениями, держит credentials у себя, может жить локально или удалённо и обновляться независимо.
Это просто API-call? Механически да. Новая часть - стандартизированное самоописание и вызов: чужой host может спросить, что доступно, и вызвать это без custom-интеграции для каждой пары.
XIII Куда движется экосистема
Направление очевидно: больше remote servers, managed gateways, понятнее authorization patterns и лучшее session behavior за load balancers и proxies.
Интересная работа не в метафоре, а в operational details: horizontal scaling, stateless operation там, где это уместно, middleware patterns, auditability и безопасное курирование инструментов.
XIV Чего MCP не решает
MCP снижает integration complexity, но не отменяет system design. Он не решает, какие tools безопасно показывать, какие data можно отправлять модели, как работают retries, как возобновлять долгий workflow и как откатывать частично выполненную бизнес-операцию.
В одну строку: MCP стандартизирует контракт вызова, но не стандартизирует доверие.
FAQ
MCP заменяет OpenAPI?
Нет. OpenAPI описывает HTTP API. MCP задаёт runtime-контракт для LLM-хостов, чтобы обнаруживать и вызывать capabilities.
Когда MCP не нужен?
Когда один скрипт говорит с одним сервисом и вы контролируете обе стороны. Прямой HTTP-вызов проще.
Что такое MCP Client?
Адаптер внутри хоста. Это не пользовательское приложение.
Что такое MCP Server?
Внешний исполнитель, который выставляет curated tools и вызывает downstream systems.
MCP решает security?
Нет. Он стандартизирует calls; безопасность всё равно требует least privilege, audit, filtering и approval paths.