Что такое MCP и зачем он нужен?
Без MCP модель остаётся советчиком. Она может написать инструкцию, предложить код или объяснить ошибку. Но сама по себе она не знает содержимое базы заметок и не умеет выполнить действие в ней.
MCP добавляет прослойку между моделью и внешней системой. Такой системой может быть локальный файл, база данных или отдельное приложение. Сервер описывает доступные инструменты. Модель получает эти описания и решает, какой инструмент нужен для текущего запроса.
Главная граница здесь простая: инструмент делает конкретное действие. Доступ ограничен отдельными операциями: «создай заметку», «добавь текст», «прочитай заметку». Такой набор возможностей проще проверять и контролировать, чем свободный shell-доступ и произвольные команды.
Например, пользователь пишет: «Создай заметку о встрече и добавь туда три пункта». Модель не открывает файл напрямую. Она выбирает инструмент создания заметки, получает идентификатор, затем вызывает инструмент добавления текста.
Для читателя это выглядит как один разговор. Внутри проходит несколько отдельных действий.
MCP даёт модели заранее определённые рычаги - и не более того. Чем точнее эти рычаги, тем проще понять, что именно произошло, когда результат оказался неправильным.
MCP - новый стандарт для подключения ИИ-ассистентов к системам, где живут данные: репозиториям контента, бизнес-инструментам и средам разработки.
Кто за что отвечает в связке MCP-клиент и MCP-сервер?
Разложу роли без документации:
- Модель читает сообщение пользователя и выбирает действие. Она видит описание доступных инструментов: название, назначение и аргументы.
- MCP-клиент связывает модель с сервером. Он получает решение модели, оформляет вызов инструмента и отправляет его дальше. Поэтому
mcp client- не само приложение с данными и не модель. - MCP-сервер принимает вызов. Он проверяет аргументы, выполняет конкретное действие и возвращает результат.
- Внешний источник хранит или отдаёт данные. В локальном примере это SQLite или JSON-файл.
Путь запроса выглядит так:
- Ты пишешь: «Добавь текст в заметку».
- Модель выбирает
append_to_note. - MCP-клиент передаёт серверу имя инструмента и аргументы.
- MCP-сервер добавляет текст в хранилище.
- Сервер возвращает результат клиенту.
- Модель показывает итог в чате.
Модель не обязана знать файл и способ записи: это зона ответственности сервера. Клиент не лезет в содержимое базы, его задача - передать вызов.
Такое разделение полезно именно в вайб-кодинге. Когда агент переписал часть приложения, проще искать поломку по границе: модель выбрала не тот инструмент, клиент передал неверные данные или сервер неправильно обработал аргументы.
Почему модель не вызывает инструмент напрямую?
Представь три слоя:
Модель отвечает на вопрос: «Что надо сделать?» Она выбирает инструмент и заполняет его аргументы. Например, передаёт note_id и текст, который нужно добавить.
Клиент отвечает на вопрос: «Куда и в каком формате отправить вызов?» Он знает, к какому MCP-серверу подключаться, и передаёт вызов дальше.
Сервер отвечает на вопрос: «Как выполнить действие?» Он открывает SQLite или JSON-файл, меняет данные и отдаёт результат.
Если убрать клиент и сервер, модели пришлось бы дать свободный доступ к окружению. Тогда она сама решала бы, какой файл открыть, какую команду запустить и куда отправить данные. Такой доступ сложнее ограничить и проверить.
MCP оставляет модели выбор инструмента, но не отдаёт ей весь набор системных возможностей. Для каждой функции есть отдельная граница и понятные аргументы. Правильный выбор инструмента ещё не гарантирует правильный результат, зато область возможной ошибки становится меньше.
Модель может правильно выбрать действие, а сервер всё равно может вернуть ошибку. Проверяй не только ответ в чате, но и результат операции в хранилище.
Практикум «Старт»
Три дня живой практики: от идеи до работающего проекта по ссылке
2 000 ₽старт 5 августа, 18:00 МСК
Что изменилось при переходе от сессии к stateless?

В старой схеме клиент проходил обязательное начало соединения:
- Отправлял
initialize. - Получал
Mcp-Session-Id. - Передавал этот идентификатор в следующем запросе.
- Вызывал инструмент внутри созданной сессии.
У нового варианта другая логика. Один вызов инструмента укладывается в один HTTP-запрос. В нём передаётся версия протокола MCP-Protocol-Version, а имя метода и инструмента дублируется в заголовках Mcp-Method и Mcp-Name.
Серверу больше не требуется хранить ID сессии и направлять запросы на тот же backend через sticky routing. Любой запрос должен быть понятен сам по себе.
| Характеристика | Stateful (старая схема) | Stateless (новая схема) |
|---|---|---|
| Начало соединения | Обязательный initialize | Не требуется |
| Идентификатор сессии | Mcp-Session-Id | Отсутствует |
| Вызов инструмента | Внутри созданной сессии | Самостоятельный HTTP-запрос |
| Заголовки | Зависит от реализации | MCP-Protocol-Version, Mcp-Method, Mcp-Name |
| Sticky routing | Требуется | Не требуется |
| Состояние приложения | Часто путали с сессией | Явный note_id или другой ID |
На этом месте я останавливаюсь на важной границе. Stateless относится к протокольному уровню MCP. Он не означает, что приложение обязано забывать все данные после каждого запроса.
Практический пример у Simon Willison показывает масштаб работы модели: один вопрос к Datasette привёл к 7 отдельным SQL-запросам. В другом примере MCP-инструмент вернул число заметок 151. За разговором пользователя стояла цепочка вызовов, несколько последовательных операций.
Новая спецификация MCP 2026-07-28 убрала обязательные initialize, initialized, Mcp-Session-Id и зависимость от sticky routing. Состояние приложения при этом остаётся задачей самого приложения.
MCP преобразуется из двустороннего протокола с состоянием в протокол запросов и ответов без состояния.
Переход к stateless нужен не ради нового названия. Он убирает лишнюю транспортную сессию. Состояние заметки, корзины или задачи переносится в явный идентификатор.
Как сделать локальный MCP-вызов stateless по шагам?

Определи минимальный endpoint.
Сделай один локальный HTTP endpoint
/mcp. Не добавляй сразу авторизацию, десятки инструментов и сложную бизнес-логику: фактура не содержит готовой настройки конкретного клиента или команды запуска.Важно разделить две вещи. Endpoint принимает MCP-запрос. Хранилище держит заметки. Сам endpoint не должен связывать вызовы через скрытый
Mcp-Session-Id.Минимальная схема выглядит так:
/mcp ├── create_note() -> note_id ├── append_to_note(note_id, text) └── get_note(note_id)Создай заметку с идентификатором.
Инструмент
create_noteсоздаёт запись и возвращаетnote_id. Этот ID становится явной связью между будущими вызовами.Сервер может хранить запись в SQLite или JSON-файле. Точная схема хранения, конкурентный доступ и обработка ошибок в фактуре не описаны, поэтому я не буду выдавать выдуманный код за готовую реализацию.
Правило для инструмента простое: связь должна быть видна снаружи. Верни идентификатор наружу.
json{ "tool": "create_note", "result": { "note_id": "созданный сервером идентификатор" } }Добавь текст по `note_id`.
Инструмент
append_to_noteполучаетnote_idиtext. Сервер находит запись по этому ID и добавляет текст в SQLite или JSON-файл.Следующий вызов не должен рассчитывать на память предыдущего HTTP-запроса. Клиент передаёт
note_idявно.json{ "tool": "append_to_note", "arguments": { "note_id": "идентификатор из предыдущего результата", "text": "Первый пункт заметки" } }Прочитай заметку отдельным вызовом.
Инструмент
get_noteполучает тот жеnote_idи возвращает сохранённый текст. Так проверяется состояние приложения поверх stateless-протокола.json{ "tool": "get_note", "arguments": { "note_id": "тот же идентификатор" } }Проверь два независимых HTTP-запроса.
Сначала отправь вызов создания заметки. Получи
note_id. Затем отдельным запросом вызови добавление текста или чтение заметки.В обоих запросах используй endpoint
/mcp. Не передавайMcp-Session-Id. Для нового stateless-вызова фактура фиксирует заголовкиMCP-Protocol-Version,Mcp-MethodиMcp-Name.httpPOST /mcp MCP-Protocol-Version: 2026-07-28 Mcp-Method: tools/call Mcp-Name: create_notehttpPOST /mcp MCP-Protocol-Version: 2026-07-28 Mcp-Method: tools/call Mcp-Name: get_noteЭто схема проверки, а не законченный JSON-RPC payload: фактура не содержит полного формата тела и всех обязательных заголовков. Я не подставляю недостающие поля из головы.
Проверь промптом границы инструмента.
Передай ИИ-агенту короткое требование. Оно помогает не смешать транспортную сессию и состояние заметки.
Проверка stateless-схемы заметокСобери минимальный локальный MCP-артефакт с endpoint /mcp и тремя инструментами: create_note, append_to_note и get_note. Состояние заметок храни в SQLite или JSON-файле. create_note должен возвращать явный note_id. append_to_note и get_note должны принимать note_id в аргументах. Не используй Mcp-Session-Id для связи вызовов. Покажи отдельно, какие данные передаются в первом HTTP-запросе и какие во втором. Не добавляй другие инструменты, авторизацию и сложную бизнес-логику. Если точного JSON-RPC payload или команды запуска не хватает в исходных данных, укажи это явно и не выдумывай.
Проверь результат в хранилище.
После вызова
append_to_noteвызовиget_noteс тем жеnote_id. Текст должен прийти из SQLite или JSON-файла, а не из памяти протокольной сессии.Если сервер перезапустился, память одного процесса не должна считаться надёжным хранилищем. Для локального примера фактура разрешает SQLite или JSON-файл, но не задаёт точную реализацию восстановления и конкурентной записи. Это место надо проверять отдельно.
Практикум «Старт»
Три дня живой практики: от идеи до работающего проекта по ссылке
2 000 ₽старт 5 августа, 18:00 МСК
Что делать, если приложению всё ещё нужно состояние?
Старая сессия смешивала несколько смыслов. Она могла означать соединение, пользователя, чат или последовательность вызовов. Из-за этого один и тот же ID не всегда совпадал с тем, что человек считал одной рабочей сессией.
В stateless-схеме смысл задаёт приложение:
note_idуказывает на заметку;basket_idуказывает на корзину;job_idуказывает на длительную задачу.
Сервер сам создаёт такой идентификатор и возвращает его в результате. Клиент сохраняет значение и передаёт его дальше. Инструменты получают состояние явно и не достают его из памяти MCP-соединения.
Например, create_note возвращает note_id. Затем append_to_note(note_id, text) меняет конкретную заметку. get_note(note_id) читает её. Протокол при этом остаётся stateless, а поведение приложения остаётся stateful.
Такой подход требует аккуратнее проектировать аргументы инструментов. Зато из вызова видно, с какой сущностью идёт работа. Это проще проверять в логах и при повторном запросе.
Что ломается после перехода на stateless?

Крайние случаи начинаются с совместимости. Клиент или middleware может по-прежнему отправлять initialize и ожидать Mcp-Session-Id. Новый сервер такой сценарий не обязан поддерживать.
Дальше идут функции, которым нужно обратиться к клиенту после вызова. В stateless-режиме отключается часть сценариев, связанных с unsolicited notifications и server-to-client requests. Client sampling, elicitation и roots тоже могут быть недоступны в legacy stateless-режиме.
Ломается и внутренняя диагностика. Раньше счётчик можно было привязать к sessionId. После удаления ID несколько клиентов с одинаковой ошибкой могут выглядеть как один поток событий. Для корреляции нужен другой ключ: явный идентификатор операции, failure fingerprint или внешняя телеметрия.
Авторизация тоже не исчезает вместе с сессией. Каждый запрос должен сам нести или получать из middleware credential, identity, права доступа и контекст аудита. Использовать старый ID как доказательство личности больше нельзя.
Есть и инфраструктурная ловушка. Любой запрос может попасть на другой экземпляр сервера. Поэтому память одного процесса не подходит для надёжного хранения счётчиков, задач и состояния. Данные надо вынести в SQLite, JSON-файл или другое внешнее хранилище с учётом ограничений конкретной реализации.
Поддержка новой схемы пока неоднородна: правильная по новой спецификации схема может не заработать в старой обвязке.
Вопросы и ответы
Вопросы и ответы
Что такое MCP-сервер?
MCP-сервер предоставляет модели конкретные инструменты и выполняет их вызовы. Я вижу его как связку между действием и внешним источником данных: локальным файлом, SQLite или другой системой.
Как устроены MCP-подключения?
В старой схеме клиент сначала отправлял initialize, получал Mcp-Session-Id, а затем вызывал инструменты. В новом stateless-варианте вызов оформляется самостоятельным HTTP-запросом.
Какой MCP protocol используется?
Финальная спецификация перехода называется MCP 2026-07-28. Она переводит базовый протокольный слой к stateless-взаимодействию.
Зачем MCP использует JSON?
JSON передаёт имя инструмента, аргументы и результат в структурированном виде. Так клиент и сервер обмениваются данными без привязки к человеческому тексту.
Можно ли работать с MCP через CLI?
Фактура не содержит отдельной инструкции по MCP CLI. Из неё можно утверждать только схему HTTP-вызова к endpoint /mcp, но не конкретную команду запуска через терминал.
Чем MCP-клиент отличается от сервера?
Клиент получает вызов от модели и передаёт его серверу. Сервер предоставляет инструменты, выполняет действие и возвращает результат.
Как модель участвует в MCP?
Модель получает описание доступных инструментов, выбирает нужный инструмент и формирует его вызов. Само действие выполняет MCP-сервер.
Как работает MCP?
Пользователь отправляет сообщение, модель выбирает инструмент, клиент передаёт вызов серверу, сервер работает с данными и возвращает результат модели. Я проверял эту цепочку на локальном примере с заметками.
Какие бывают MCP-примеры?
Я показываю минимальный пример с заметками: create_note возвращает note_id, append_to_note добавляет текст, а get_note читает запись.
Как работает MCP в stateless-схеме?
Каждый HTTP-запрос сам содержит данные, необходимые для обработки. Скрытая транспортная сессия не связывает вызовы, а состояние приложения передаётся явным идентификатором.
Как использовать MCP локально?
Собери endpoint /mcp, добавь инструменты заметок, выбери SQLite или JSON-файл для хранения и передавай note_id в каждом последующем вызове.
Как выглядит минимальный MCP-пример?
Минимальная схема состоит из одного endpoint и трёх инструментов: create_note, append_to_note и get_note. Первый инструмент создаёт ID, два других используют его явно.
Что такое MCP-серверы и чем они отличаются от клиентов?
MCP-серверы реализуют конкретные действия и доступ к данным. Со стороны клиента модель соединяется с этими серверами, а клиент передаёт выбранные моделью вызовы.
Источники
Практикум «Старт»
Три дня живой практики: от идеи до работающего проекта по ссылке
2 000 ₽старт 5 августа, 18:00 МСК

