В MCP я полез довольно практично: мне надоело вручную переносить заметки из Obsidian в LLM, и я решил написать между ними небольшой сервер. Уже во время разработки стало понятно, почему вокруг Model Context Protocol столько разговоров. Сам по себе MCP не делает модели умнее и не добавляет им каких-то принципиально новых способностей. Его задача гораздо скучнее: привести в порядок то, как AI-приложения подключаются к файлам, базам данных, API и другим внешним системам.
До появления MCP проблема решалась вполне привычно. Нужно дать LLM доступ к GitHub — пишем интеграцию с GitHub. Нужно подключить PostgreSQL — добавляем ещё одну. Потом появляется другой AI-клиент, третий источник данных, внутренний API компании, CRM, документация, и постепенно вокруг моделей вырастает тот же интеграционный зоопарк, который разработчики строили последние двадцать лет.
MCP пытается поставить между этими системами общий интерфейс. Если совсем коротко, Model Context Protocol — это открытый протокол, через который AI-приложения могут подключаться к внешним данным и инструментам стандартным способом.
Звучит пока довольно абстрактно, поэтому попробуем разобраться, что именно он стандартизирует, как проходит обычный вызов инструмента и зачем вообще добавлять новый протокол, если REST API и function calling уже давно существуют.
Зачем вообще понадобился MCP
Представим, что у нас есть Cursor и мы хотим дать ему доступ к GitHub, PostgreSQL и Obsidian. Без общего протокола каждая связь становится отдельной интеграцией:
Cursor → GitHub
Cursor → PostgreSQL
Cursor → Obsidian
Потом в компании появляется ещё один AI-клиент. Допустим, Claude. Для него нужно решить примерно те же задачи:
Claude → GitHub
Claude → PostgreSQL
Claude → Obsidian
Само по себе это не выглядит катастрофой. Разработчики постоянно интегрируют одни системы с другими. Проблема начинается, когда количество клиентов и источников данных растёт одновременно: интеграций становится всё больше, у каждой свой способ настройки, авторизации, описания доступных операций и передачи результата обратно модели.
MCP предлагает договориться о границе между этими двумя мирами:
Cursor ─┐
Claude ─┼── MCP ── GitHub
ChatGPT ─┘ ├─ PostgreSQL
└─ Obsidian
Каждый AI-клиент поддерживает один протокол, а каждая внешняя система может предоставить MCP-сервер. В идеальном мире после этого серверу уже не особенно важно, подключается к нему Cursor, Claude или приложение, которое появится через год.
Именно поэтому MCP часто сравнивают с USB-C. Аналогия уже успела надоесть, но смысл передаёт неплохо: USB-C не изобрёл монитор, ноутбук или внешний диск, он стандартизировал способ их соединения. MCP примерно так же не изобретает API, базы данных или tools для LLM. Он пытается стандартизировать способ, которым AI-приложение получает к ним доступ.
На практике всё, конечно, сложнее. Авторизация никуда не исчезает, плохой API не становится хорошим, а бизнес-логику по-прежнему кто-то должен написать. Но общий контракт между AI-приложением и внешней системой уже сам по себе снимает приличный кусок интеграционной работы.
Как устроен MCP
В базовой архитектуре есть три основных участника: Host, Client и Server. Названия не самые очевидные, особенно когда впервые пытаешься понять, где заканчивается LLM и начинается сам протокол.
Host — это приложение, в котором работает пользователь. Например Cursor, Claude Code, VS Code или собственное приложение с подключённой LLM. Важно, что сама модель не является MCP Host: приложение может сегодня использовать Claude, завтра GPT, но Host при этом останется тем же.
Внутри Host находятся MCP Clients. Каждый Client отвечает за связь с конкретным MCP Server, поэтому схема обычно выглядит примерно так:
┌→ MCP Client → GitHub MCP
AI-приложение ──────┼→ MCP Client → PostgreSQL MCP
└→ MCP Client → Obsidian MCP
Server находится с другой стороны и предоставляет определённый набор возможностей. Это может быть небольшой локальный процесс, умеющий читать файлы с диска, или полноценный удалённый сервис внутри корпоративной инфраструктуры. Оба варианта для MCP нормальны.
Например, мой сервер для Obsidian работает непосредственно с Markdown-файлами vault и предоставляет несколько операций: поиск, чтение, просмотр структуры и запись. Другой MCP Server может ходить в GitHub API, третий — выполнять SQL-запросы, четвёртый — работать с CRM. Для Host все они выглядят через один протокольный интерфейс.
У Host при этом остаётся довольно важная роль. Именно приложение решает, к каким серверам подключаться, какие данные передавать модели и какие операции разрешать. Сервер не получает автоматически весь разговор пользователя и доступ ко всему, что знает приложение. Это одна из границ, на которых потом строится безопасность MCP.
Tools, Resources и Prompts
Когда MCP Server подключён, он может предоставить клиенту несколько типов возможностей. Чаще всего говорят о трёх: Tools, Resources и Prompts. На словах они похожи, но назначение у них разное.
Tools — это действия, которые можно выполнить. Например сервер для GitHub может предоставить create_issue, сервер для базы данных — run_query, а мой сервер для Obsidian — vault_search и vault_read. Модель получает название инструмента, описание и схему аргументов, после чего может решить использовать его для выполнения пользовательского запроса.
Условно tool может выглядеть так:
search_notes(query: string)
Пользователь пишет:
Найди всё, что я писал про MCP.
Модель видит доступный search_notes и понимает, что этот инструмент подходит для задачи. Дальше приложение вызывает его через MCP, сервер выполняет реальный поиск и возвращает результат.
Resources устроены немного иначе. Это не действие, а данные, которые сервер может предоставить клиенту: содержимое файла, документ, описание схемы базы данных, внутреннюю документацию или любой другой контекст, которому сервер назначил URI. Если грубо упростить разницу, tool отвечает на вопрос «что можно сделать», resource — «что можно прочитать».
Prompts — ещё один тип возможности. Сервер может предоставить заранее подготовленные сценарии взаимодействия с моделью: например шаблон code review, анализ инцидента или подготовку отчёта. В отличие от tools, которые модель часто выбирает сама, prompts обычно ближе к явному пользовательскому действию — человек выбирает готовый сценарий и запускает его.
Если свести всё к одной таблице:
| Возможность | Для чего нужна | Пример |
|---|---|---|
| Tool | выполнить действие | создать issue |
| Resource | получить данные | прочитать документ |
| Prompt | запустить готовый сценарий | провести code review |
На практике я пока чаще всего работаю именно с tools. Как только хочется, чтобы LLM не просто получила заранее подготовленный контекст, а сама могла найти нужный файл, выполнить поиск или сделать следующее действие, всё довольно быстро сводится к инструментам.
Что происходит после запроса пользователя
Теория Host, Client и Server становится гораздо понятнее, если пройти один запрос целиком. Возьмём тот же Obsidian. Допустим, пользователь пишет в LLM-клиенте:
Найди мои заметки про MCP и собери краткое резюме.
Внутри контекста модели этих заметок нет, зато подключён MCP Server, который предоставляет vault_search и vault_read. Модель видит описания доступных инструментов и понимает, что сначала имеет смысл выполнить поиск:
vault_search("MCP")
Host передаёт этот вызов соответствующему MCP Client, Client отправляет запрос Server, а тот уже выполняет совершенно обычный код: проходит по Markdown-файлам и ищет совпадения. В ответ, например, возвращается список:
Projects/mcp.md
Ideas/ai-tools.md
Daily/2026-08-15.md
Самое интересное начинается дальше. Модель может посмотреть на результат и решить, что одного списка файлов недостаточно. Тогда она вызывает vault_read для одного или нескольких документов, получает содержимое и только после этого отвечает пользователю.
Получается примерно такая цепочка:
Пользователь
↓
AI-приложение
↓
LLM
↓
выбирает tool
↓
MCP Client
↓
MCP Server
↓
внешняя система
↓
результат
↓
LLM
↓
Пользователь
То есть модель не получает какой-то специальный «доступ к Obsidian». Она получает ограниченный набор операций, которые кто-то заранее спроектировал и разрешил. В этом месте хорошо видно, почему дизайн tools оказывается важнее, чем кажется сначала. Если дать модели десять понятных операций, она может довольно предсказуемо из них собирать последовательность действий. Если дать сорок почти одинаковых методов с неясными описаниями, ей каждый раз придётся угадывать, какой из них имел в виду разработчик.
Когда я делал свой MCP Server, это стало одним из самых полезных наблюдений. Хочется сразу добавить отдельный инструмент под каждый сценарий, но в итоге небольшой набор хороших примитивов часто работает лучше. Это вполне знакомая проблема API design, просто потребителем API теперь становится не другой разработчик, а LLM.
Как клиент узнаёт, что умеет сервер
Разумеется, Cursor или другой Host не знает заранее, что конкретный сервер умеет vault_search. MCP нужен в том числе для того, чтобы возможности сервера можно было обнаружить стандартным способом.
Для tools клиент может запросить список доступных инструментов. Сервер в ответ передаёт название каждого tool, описание и JSON Schema его параметров. Условно это выглядит примерно так:
{
"name": "search_notes",
"description": "Search notes by text",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string"
}
},
"required": ["query"]
}
}
Дальше этот каталог инструментов может быть предоставлен модели. Именно поэтому хорошее описание tool — не декоративная документация. Если написать do_stuff с описанием Does some stuff, модель получит примерно столько же информации, сколько получил бы разработчик от такого API. Название search_notes и нормальное описание назначения инструмента уже дают ей гораздо больше шансов выбрать его в правильный момент.
Под капотом MCP использует JSON-RPC 2.0, поэтому никакого особого «AI-протокола общения с функциями» там нет. Вызов инструмента — обычное структурированное сообщение. Например концептуально он может выглядеть так:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_notes",
"arguments": {
"query": "MCP"
}
}
}
Сервер выполняет операцию и возвращает структурированный результат. SDK обычно скрывает большую часть этой рутины, поэтому при написании простого сервера разработчик может вообще почти не соприкасаться с JSON-RPC напрямую.
Здесь стоит сделать небольшое отступление про версии. MCP пока развивается достаточно быстро, и архитектура протокольного взаимодействия уже заметно менялась. В спецификации 2026-07-28 убрали обязательный initialize/initialized handshake и protocol-level sessions: запросы стали самодостаточными, а для предварительного получения версий и capabilities сервера появился необязательный server/discover. Поэтому старые статьи, где подключение начинается с обязательной инициализации и Mcp-Session-Id, описывают предыдущую версию протокола, а не обязательно ошибаются.
Локальные и удалённые MCP-серверы
До сих пор мы говорили о MCP как о логическом протоколе, но сообщения ещё нужно как-то передать между Client и Server. Для этого существуют transports.
Самый простой вариант — stdio. Host запускает MCP Server как локальный процесс и общается с ним через стандартный ввод и вывод. Для разработки это почти идеальная схема: не нужны порты, домены, HTTPS и отдельная сетевая авторизация. Например локальный сервер для Obsidian можно запустить в Docker, смонтировать внутрь нужную директорию и соединить с Cursor через stdio.
Cursor
↓
stdio
↓
MCP Server
↓
Obsidian Vault
Для удалённых серверов используется HTTP. Здесь уже появляются привычные инфраструктурные задачи: HTTPS, authentication, authorization, rate limiting, observability и всё остальное, что обычно появляется у публичного или корпоративного API. Зато такой сервер может обслуживать много клиентов и работать с общей инфраструктурой компании: CRM, документацией, аналитикой или внутренними сервисами.
В актуальной спецификации MCP протокольное ядро стало stateless, поэтому удалённые серверы проще масштабировать обычными средствами web-инфраструктуры. Запрос больше не обязан попадать на тот же экземпляр, который когда-то создавал сессию; его можно отправить на любой подходящий instance за load balancer. Старый HTTP+SSE transport при этом официально переведён в deprecated, хотя старые реализации ещё какое-то время будут встречаться.
В грубом приближении разница между двумя сценариями выглядит так:
| Local MCP | Remote MCP | |
|---|---|---|
| Где работает | на машине пользователя | на сервере |
| Типичный transport | stdio | HTTP |
| Авторизация | часто не нужна | обычно нужна |
| Типичные данные | файлы, IDE, локальные инструменты | CRM, API, корпоративные системы |
Мне локальный MCP интересен как способ дать AI доступ к моему рабочему окружению. Но с точки зрения компаний гораздо интереснее remote-вариант: можно построить единый слой, через который разные AI-инструменты получают контролируемый доступ к внутренним системам. На этом уровне MCP уже начинает выглядеть не как удобная функция IDE, а как часть AI-инфраструктуры.
MCP, Function Calling, API и RAG — это разные вещи
Когда начинаешь разбираться с MCP, первый нормальный вопрос — зачем вообще нужен ещё один протокол, если function calling существует уже давно. Модель и без MCP умеет получить описание функции, выбрать её, передать аргументы и дождаться результата. Разница оказалась не в самом вызове функции, а уровнем выше: откуда приложение получает список доступных инструментов, как обнаруживает их и как подключает новые внешние системы.
Function Calling находится ближе к взаимодействию приложения с моделью. Мы говорим LLM: вот несколько функций, которые ты можешь использовать, вот их параметры. MCP находится ближе к интеграционной части и стандартизирует способ подключения источника этих возможностей.
Function Calling:
LLM
↓
functions приложения
MCP:
AI-приложение
↓
MCP
↓
внешние системы
На практике эти механизмы отлично уживаются вместе. MCP Client получает tools от сервера, а Host затем может представить их модели через механизм tool/function calling конкретного LLM-провайдера. Поэтому рассматривать MCP как замену function calling не особенно полезно.
С API история похожая. MCP не заменяет REST, GraphQL или любой внутренний RPC компании. Очень часто MCP Server внутри сам является адаптером поверх существующего API. Например CRM продолжает предоставлять обычный REST API, а MCP Server превращает его в несколько понятных для AI-инструментов операций вроде find_customer, create_lead или get_deals.
LLM
↓
MCP
↓
MCP Server
↓
REST API
↓
CRM
Сам сервис ничего не знает про LLM и не обязан знать. MCP просто создаёт ещё один интерфейс с другой стороны.
RAG тоже решает другую задачу. В классической схеме retrieval-система получает запрос, находит релевантные документы и добавляет их в контекст до генерации ответа:
запрос → retrieval → документы → context → LLM
С MCP модель может сама решить вызвать поиск, посмотреть результат, прочитать конкретный документ и при необходимости выполнить следующий tool. При этом MCP Server вполне может внутри использовать embeddings, vector database и обычный RAG. Например tool semantic_search может обращаться в Qdrant и возвращать найденные фрагменты.
Поэтому вопрос «MCP или RAG?» мне кажется немного искусственным. Иногда нужен только retrieval, иногда модели нужен набор действий, а иногда удобно завернуть retrieval в один из MCP tools и использовать оба подхода одновременно.
MCP и AI-агенты
Ещё одно понятие, которое постоянно встречается рядом с MCP, — AI agents. Настолько постоянно, что можно решить, будто MCP сам является каким-то агентным фреймворком. Это не так.
Агенту нужно решить, что делать дальше, выбрать последовательность действий, посмотреть на результат, возможно изменить план и определить момент, когда задача закончена. MCP эту логику не задаёт. Он может предоставить агенту GitHub, базу данных, filesystem или CRM, но не говорит, когда именно ими пользоваться и как строить reasoning loop.
Если упрощать до одной фразы, агент решает что делать, а MCP стандартизирует через какой интерфейс получить внешние возможности для этого действия.
Именно с агентами MCP становится особенно интересным. В обычном чат-боте модель может один раз вызвать погоду или поиск. Агент работает дольше и способен последовательно использовать несколько систем: прочитать issue, найти код, посмотреть документацию, проверить CI и подготовить изменение. Если под каждую из этих систем существует стандартный MCP-интерфейс, собрать такую среду заметно проще.
Где MCP действительно имеет смысл
Наиболее очевидный сценарий сегодня — разработка. Coding agent может получить через MCP доступ к репозиторию, документации, issue tracker, CI, логам или внутренним инструментам. В результате задача уровня «посмотри issue, найди связанный код и предложи исправление» перестаёт требовать, чтобы человек вручную собирал весь контекст.
Второй сценарий — базы знаний. Собственно, поэтому я и начал писать свой сервер для Obsidian. Если накоплено несколько лет заметок, гораздо интереснее не копировать конкретный документ в LLM, а дать модели ограниченный поиск и чтение, чтобы она сама находила нужный контекст.
Для компаний к этому добавляются аналитика и внутренние системы. PostgreSQL, BigQuery, CRM, ERP, документация, таск-трекеры, внутренние API — всё это потенциальные источники MCP capabilities. Если AI-инструмент внутри организации один, можно спокойно написать прямую интеграцию. Если их становится пять, а внутренних систем двадцать, общий контракт начинает выглядеть гораздо привлекательнее.
При этом я бы не пытался добавлять MCP в каждый проект, где встретилась LLM. Если backend всегда вызывает одну конкретную функцию generate_description(product) и никакого выбора внешнего инструмента модель не делает, отдельный MCP Server почти наверняка будет лишним слоем. То же касается детерминированных workflow, где последовательность операций заранее известна приложению.
Для меня хороший критерий примерно такой: MCP становится интересен там, где появляется отдельная граница между AI-приложением и набором внешних возможностей, причём эти возможности потенциально нужны разным клиентам.
Безопасность никуда не делась
У MCP есть одна особенность, которая одновременно делает его полезным и немного страшным: tools могут менять реальный мир. search_docs просто возвращает данные, а delete_customer, transfer_money или даже обычный vault_write уже создают последствия.
Протокол не решает за разработчика, какие операции безопасно отдавать модели. По-прежнему нужно думать о least privilege, authentication, authorization, audit log и пользовательском подтверждении опасных действий. Если модели нужен только поиск по документации, нет никакого смысла заодно выдавать ей write и delete «на будущее».
Когда я добавлял запись в свой MCP Server для Obsidian, именно это стало самым неприятным вопросом. Читать заметки относительно безопасно, а разрешить модели полностью перезаписать Markdown-файл — уже другое дело. В итоге довольно быстро приходишь к знакомым инженерным идеям: ограниченным директориям, read-only режиму, git, diff и подтверждению изменений перед применением.
В спецификации MCP этому тоже уделяется внимание: tool calls должны быть понятны пользователю, а потенциально опасные действия желательно оставлять под человеческим контролем. Для remote MCP отдельно развивается authorization-модель; в версии 2026-07-28 её дополнительно усилили, а Dynamic Client Registration формально начали выводить из использования в пользу Client ID Metadata Documents.
Важно и другое: MCP Server становится новой trust boundary. Если мы подключили неизвестный сервер, мы доверяем не только его коду, но и описаниям tools, данным, которые он возвращает, и тому, как всё это может повлиять на дальнейшие действия модели. Красивый стандартный интерфейс не делает интеграцию автоматически безопасной.
MCP не решает архитектуру за нас
Мне вообще нравится смотреть на MCP как на довольно скучный инфраструктурный протокол, потому что это немного охлаждает ожидания. Он не исправляет плохие API, не проектирует tools, не определяет бизнес-логику, не решает проблему hallucinations и не гарантирует, что агент выберет правильное действие.
Если сервер предоставляет тридцать плохо названных tools, модель по-прежнему будет путаться. Если внутренний API компании требует семи вызовов для простейшей операции, MCP не сделает его хорошим. Если конкретные данные нельзя показывать внешней LLM, сам факт подключения через MCP не меняет правила доступа.
Он стандартизирует границу. Всё интересное по обе стороны этой границы остаётся обычной инженерной работой.
И, пожалуй, именно поэтому MCP мне интересен. Не как очередная технология, которая «полностью меняет разработку», а как достаточно понятный строительный блок. У нас уже есть модели, API, базы данных, файловые системы и корпоративные сервисы. Теперь появился общий контракт, через который AI-приложения могут с ними работать.
Ценность здесь не в том, что LLM внезапно научилась читать GitHub или PostgreSQL. При желании мы могли подключить их и раньше. Разница в том, что теперь для этого постепенно появляется стандартный интерфейс, который можно переиспользовать между разными клиентами.
А дальше начинается уже более интересная часть: какие возможности вообще стоит отдавать модели, насколько крупными должны быть tools, как контролировать изменения и где провести границу между автоматизацией и ответственностью инженера.
И вот это, кажется, тема гораздо больше самого MCP.
Частые вопросы
Что такое MCP простыми словами?
MCP, или Model Context Protocol, — открытый протокол, который стандартизирует подключение AI-приложений к внешним данным и инструментам. Через него модель может, например, искать документы, читать файлы, обращаться к API или выполнять разрешённые действия.
Что такое MCP Server?
MCP Server — программа или сервис, который предоставляет через MCP набор возможностей. Это могут быть tools для выполнения действий, resources с данными или готовые prompts.
Чем MCP отличается от API?
API описывает интерфейс конкретной системы. MCP стандартизирует интерфейс между AI-приложением и внешними возможностями. При этом MCP Server часто сам использует обычный REST или другой API.
Чем MCP отличается от Function Calling?
Function Calling относится к тому, как приложение предоставляет функции самой LLM. MCP отвечает за стандартное подключение внешних источников этих функций и данных к AI-приложению. На практике они часто используются вместе.
Чем MCP отличается от RAG?
RAG в первую очередь решает задачу поиска и доставки релевантного контекста. MCP позволяет AI-приложению работать с внешней системой через стандартный протокол. Retrieval при этом вполне может быть реализован внутри MCP tool.
MCP — это AI-агент?
Нет. MCP не занимается планированием и reasoning loop агента. Он предоставляет агенту стандартизированный доступ к внешним возможностям.
MCP работает только локально?
Нет. Локальные MCP-серверы часто работают через stdio, а удалённые можно подключать по HTTP.
Всегда ли нужен MCP для интеграции LLM?
Нет. Если интеграция простая, фиксированная и используется только одним приложением, обычный API или function calling часто будут проще. MCP становится особенно полезен, когда внешних систем и AI-клиентов становится много.