Глава 2 — Знакомство с Model Context Protocol (MCP)
Второй пост поглавного разбора LLM Primer IV: Designing AI Cognition with MCP. В котором мы строим ментальную модель — три роли, проводной формат JSON-RPC, динамическая поверхность обнаружения и жизненный цикл сессии — аккуратно настолько, чтобы остаток книги мог на ней стоять.
Почему существует эта глава
Глава 1 назвала проблему. Эта глава строит ментальную модель ответа. MCP можно резюмировать одной фразой и неправильно понять в одном абзаце, поэтому глава не торопится: что такое протокол на проводном уровне, что означают три роли и кому что принадлежит, чем он отличается от REST API в случаях, реально значимых в продакшене, и что происходит во время сессии от подключения до завершения. Цель в том, чтобы к концу вы могли — ещё до следующей главы — предсказать, чем должен быть серверный примитив, чем должен быть клиентский примитив и почему MCP заслуживает ту структуру, которую имеет.
2.1 Что такое MCP и что на самом деле означает «USB-C для ИИ»
Model Context Protocol — открытая спецификация того, как LLM-приложения обнаруживают, описывают и вызывают внешние возможности. На проводе это JSON-RPC 2.0 поверх одного из небольшого числа транспортов. На архитектурном уровне это контракт, позволяющий хосту работать с любым соответствующим сервером без штучного интеграционного кода. Инструмент, построенный один раз под протокол, работает с каждым хостом, который на нём говорит. Хост, построенный один раз под протокол, может пользоваться каждым инструментом, который на нём говорит.
Прижившееся сокращение — «USB-C для ИИ». Структурная форма действительно зеркалит USB-C — единый стандарт соединения, опосредующий между открытой популяцией устройств и открытой популяцией хостов. Пределы метафоры стоит назвать: USB-C стандартизирует разъём плюс стек над ним; MCP стандартизирует только протокол. USB-C работает в электрических временных масштабах с аппаратно закреплённой кадрировкой; MCP — в сетевых временных масштабах с программно определяемой кадрировкой, что делает MCP более гибким и одновременно вынуждает его обрабатывать обрывы соединения и медленных партнёров, которых USB-C не знает.
Более близкое для инженеров сравнение — LSP. Language Server Protocol определил протокол, на котором могут говорить любой редактор и любой языковой сервер; MCP определяет протокол, на котором могут говорить любой LLM-хост и любой провайдер возможностей. Форма выигрыша идентична — связь многие-ко-многим сворачивается общим протоколом в нечто, масштабирующееся аддитивно. Выбор положить в основу MCP JSON-RPC 2.0, а не изобретать свежий проводной формат, был осознанным: JSON-RPC мал, зрел, агностичен к языку и негламурен. Интересные архитектурные выборы — не на проводном уровне. Они в том, как Host, Client и Server делят ответственность.
2.2 Host, Client и Server — кому что принадлежит
MCP определяет три роли, и первое, что нужно понять, — это что «Client» и «Server» не означают того, что они часто означают в других местах. Server экспонирует возможности — инструменты, ресурсы, промпты. Client — это одно протокол-говорящее соединение к одному Server, управляемое внутри большего приложения. Большее приложение — это Host. Host владеет моделью, сессией пользователя и политикой того, что модели разрешено делать. Server-ы владеют своими поверхностями возможностей. Client-ы — это провода между ними, по одному на каждый Server.
Разделение важно, потому что у каждой роли разная ответственность и разная позиция доверия. Host — это граница доверия, важная с точки зрения пользователя; всё остальное — это то, что Host решил впустить. Host, общающийся с пятью Server-ами, имеет пять Client-ов внутри, у каждого свой состояние сессии, свои подписки, свой взгляд на то, какие возможности были согласованы. Если Server падает, падает соответствующий Client; остальные Client-ы продолжают работать; Host остаётся живым. Client-ы — это поодиночке изолированные на соединение прослойки, не дающие одному плохому Server-у отравить всю сессию.
Есть и аргумент безопасности в пользу разделения. Каждый Server — как минимум код, написанный кем-то другим. Client опосредует всё, что Server может сделать с Host — уведомления, запросы пользовательского ввода, запросы sampling, опубликованные ресурсы, — и именно ему принадлежит политика на уровне сервера. Host, Client и Server — это логические роли, а не строго физические: в локальной установке Server часто подпроцесс через stdio; в удалённом развёртывании — сервис над HTTP-транспортом. Протоколу это безразлично; границам ролей — нет.
2.3 MCP против REST — что покупают динамическое обнаружение и семантические описания
Резонный вопрос: «разве это не просто REST?» Различия не косметические. Самые серьёзные — динамическое обнаружение, семантические описания, написанные для LLM, и двунаправленная модель сообщений.
REST API публикует конечные точки в документации, написанной для людей-разработчиков. Набор конечных точек, которым пользуется клиент, фиксируется во время сборки; новые требуют переразвёртывания. MCP это инвертирует. В начале сессии Client спрашивает: «что вы предлагаете?» — а Server отвечает типизированным каталогом — схемы, описания, метаданные, — которым хост пользуется программно. Если Server позже добавляет инструмент, уведомление listChanged обновляет Client посреди сессии без перезапуска. Server — авторитетный источник истины о собственных возможностях; описание не может разойтись с реализацией, потому что отдельной клиентской копии, от которой можно было бы отойти, нет.
Семантические описания — второе различие. Документация конечной точки REST написана для разработчика, который прочтёт и решит. Описание MCP-инструмента написано для LLM, которая прочтёт его как часть своего промпта и решит автономно. Описание вида «POST в /users/:id/orders» бесполезно для LLM, которой нужно знать, какую концептуальную операцию выполняет инструмент, когда его предпочесть, какие у него побочные эффекты и что значат его входы в доменных терминах. Работа по переводу API в термины, читаемые LLM, выполнена один раз — в Server-е, там, где её могут поддерживать ближайшие к возможности люди.
Третье различие — двунаправленность. REST — запрос-ответ; соединение закрывается. MCP двунаправлен по проекту. Server может посылать уведомления в любой момент, может инициировать запросы sampling обратно к Client-у, может вытягивать ответы от пользователя посреди потока. Ничто из этого технически невозможно над REST. Всё это там неуклюже. В MCP это часть стандарта.
2.4 Согласование возможностей и жизненный цикл сессии
Сессия начинается, когда Client открывает транспорт и посылает запрос initialize, несущий версию протокола и возможности. Server отвечает своими возможностями — экспонирует ли он инструменты, экспонирует ли ресурсы, предлагает ли подписки, поддерживает ли продвинутые функции. Client подтверждает уведомлением initialized. Сессия в операционном состоянии, и доступные типы сообщений — ровно то подмножество, на которое согласились обе стороны.
Это согласование и есть то, что позволяет Client и Server с разными наборами функций сосуществовать продуктивно. Здесь же обрабатывается версионирование: Server выбирает наибольшую версию, которую поддерживают обе стороны. Операционно у жизненного цикла есть последствия. Инициализация не бесплатна — есть стоимость round-trip и, для удалённых серверов, поверх этого стоимость установки соединения. Долгоживущие сессии — предпочтительный паттерн; изменения возможностей идут как уведомления, а не как переподключение. Хосты, уважающие это — держащие сессии тёплыми, переподключающиеся в фоне после сетевых сбоев, — получают материально лучшую латентность. Хосты, рвущие и переинициализирующие соединение на каждый запрос, работают правильно, но неэффективно.
Стоит зафиксировать асимметрию: у запросов есть ответы, у уведомлений их нет. События list-changed — уведомления, поэтому Client, пропустивший одно, должен быть готов обновить свой взгляд, заново вызвав list_tools. Уведомление — оптимизация, а не гарантия. Надёжный MCP-код относится к нему как к подсказке, а не к записи.
Что подготавливает глава 2
Теперь у вас есть ментальная модель. MCP — это JSON-RPC-протокол с тремя ролями, динамическим обнаружением, делающим Server авторитетом по своим возможностям, описаниями, написанными для аудитории-LLM, двунаправленной моделью сообщений с уведомлениями и серверно-инициированными запросами, и жизненным циклом, открывающимся явным согласованием возможностей и работающим внутри того подмножества, на которое согласились обе стороны. Этого хватает, чтобы конкретно говорить о том, что именно экспонируют Server и Client, — чем и занимаются следующие две главы.
Дальше — Глава 3: Серверные примитивы — Resources, Prompts, Tools. Три существительных, которые может предложить сервер, почему каждое имеет значение и дисциплина выбора правильного примитива вместо перегрузки одного на территорию другого.