1. Зачем вообще нужен отдельный протокол
В этом модуле мы наконец разберёмся, что такое MCP (Model Context Protocol) и как он вписывается в стек ChatGPT App. Давайте начнем с того, что зафиксируем место MCP в архитектуре, сравним его с «типичным REST» и разберем основные сущности протокола: tools, resources и prompts.
Представьте, что вы пишете обычный веб‑сервис. По старой доброй традиции вы поднимаете REST API: у вас есть /api/gifts, /api/users, /api/orders, у каждого свой формат входа и выхода, свои коды ошибок и авторизация. Это привычно, но есть один нюанс: каждому клиенту вы вынуждены объяснять, что и как вы реализовали. Документация, OpenAPI, примеры, SDK — всё это нужно, потому что формат API вы придумали сами.
С ChatGPT App ситуация усложняется. Клиентом у вас является не только фронтенд, но и сама модель. Ей нужно:
- узнать, какие вообще операции доступны;
- понять, какие аргументы нужны каждой операции;
- вызывать эти операции по ходу диалога, иногда несколько раз, иногда с разными параметрами;
- интерпретировать структурированный ответ и решать, что показать пользователю, а что использовать только как контекст для следующей реплики.
Если каждый разработчик будет придумывать свой формат API, модель окажется в аду интеграции: под каждый App нужен будет кастомный клиент, куча «обвязки» и хрупкая логика. Проблему решает идея протокола.
MCP (Model Context Protocol) — это открытая спецификация стандартного способа, как LLM‑клиент (ChatGPT, IDE‑плагин, агент и т.п.) общается с вашим сервером инструментов и данных. Он задаёт общий язык, в котором сервер объявляет свои инструменты, ресурсы и промпты, а клиент — вызывает их и получает результаты.
Интуитивно MCP — это USB‑C порт для мира AI: если вы делаете «флешку» (сервис, базу данных, CRM, поисковый движок), вам нужно реализовать один стандартный разъём. Тогда любой «ноутбук» (ChatGPT, другой агент, IDE) может к вам подключиться без кастомного кабеля.
2. Взгляд с высоты: где MCP в архитектуре ChatGPT App
Чтобы зафиксировать картинку, вспомним уже знакомую архитектуру, но теперь с явным MCP‑слоем.
Текущий ментальный образ вы уже видели: пользователь общается с ChatGPT, внутри диалога рендерится виджет (Apps SDK), а где‑то снаружи живёт ваш бэкенд. Теперь добавим MCP и разложим всё по слоям.
Вот упрощённая схема:
Пользователь
↓ (натуральный язык)
ChatGPT (модель + UI)
↓ (tool calls по MCP)
MCP-клиент внутри ChatGPT
↓ (JSON-RPC, MCP)
Ваш MCP-сервер (backend)
↓
Ваша БД / внешние API / очереди
Под «MCP‑клиентом внутри ChatGPT» здесь понимается внутренняя часть платформы, которая говорит с вашим MCP‑сервером по протоколу: делает discovery, вызывает инструменты и читает ресурсы.
С точки зрения Apps SDK минимальный ChatGPT App состоит из трёх компонентов. Первый — MCP‑сервер, который объявляет инструменты и отдаёт структурированные данные. Второй — UI‑бандл (виджет), который рендерится внутри ChatGPT и читает эти данные через window.openai. Третий — сама модель, которая решает, когда вызывать какой инструмент и как отвечать пользователю.
Важно увидеть здесь следующее. Во всех предыдущих модулях вы много работали на уровне Apps SDK и виджета, то есть в верхней части схемы. Сейчас мы спускаемся на уровень MCP‑сервера — это ваш официальный «язык общения» с ChatGPT и любыми другими клиентами, которые решат использовать ваш App.
3. MCP против «типичного REST»: в чём разница
На схеме выше мы зафиксировали, где MCP находится в архитектуре ChatGPT App. Теперь пора аккуратно сравнить подходы «свой REST» и MCP, чтобы было понятно, почему в контексте ChatGPT Apps второй вариант выигрывает почти всегда.
В REST‑подходе вы проектируете эндпоинты, форматы запросов и ответов так, как вам удобно. Клиенту, чтобы с вами работать, нужно знать URL‑ы, методы, схемы и коды ошибок. Иногда помогает OpenAPI, иногда вы просто кидаете пример запроса в README. Модель сама по себе ничего из этого не понимает: ей нужен слой кода, который превратит «подбери подарок маме на 50 лет» в конкретный HTTP‑запрос, а потом обратно — JSON‑ответ в данные, пригодные для диалога.
В MCP всё иначе. Протокол сам по себе задаёт:
- как клиент может узнать список ваших инструментов;
- как описать аргументы и результаты через JSON Schema;
- как описать ресурсы и промпты;
- как выглядит вызов инструмента и ответ на него.
За счёт этого ChatGPT и другие MCP‑клиенты могут автоматически:
- выполнить discovery — узнать, какие у вас есть tools/resources/prompts;
- построить внутреннюю схему параметров для каждого инструмента;
- вызывать их без кастомной хардкод‑логики клиента;
- кэшировать метаданные и использовать их в поиске и ранжировании приложений.
Можно свести отличие в небольшую таблицу.
| Вопрос | Свой REST / gRPC | MCP |
|---|---|---|
| Как клиент узнаёт, что вы умеете? | Из документации, README, OpenAPI | Через стандартные методы discovery (список tools/resources) |
| Кто описывает параметры? | Вы, произвольно (JSON, FormData, что угодно) | JSON Schema в полях инструмента |
| Как модель вызывает функции? | Через ваш кастомный клиентский код | Непосредственно через MCP‑примитивы |
| Сколько обвязки у клиента? | Много и на каждый сервис своя | Один общий протокол для всех MCP‑серверов |
| Поддержка несколькими клиентами | Нужно писать SDK для каждого клиента | MCP‑сервер самодокументируемый, клиент может переиспользовать логику |
Если сформулировать эмоционально: REST — это «каждый сам за себя», MCP — это «договор между всеми участниками экосистемы, как общаться с моделью и данными».
4. Основные сущности MCP: tools, resources, prompts
Теперь давайте по именам назовём трёх главных героев MCP: инструменты, ресурсы и промпты.
Tools: действия, к которым вы уже привыкли
С tools вы уже сталкивались в Модуле 4: там мы описывали инструмент, давали ему имя, описание и JSON Schema аргументов, а потом модель вызывала его через callTool. На уровне MCP инструмент — это серверная операция с чётким контрактом:
- имя и описание (для модели и для UX/дискавери);
- JSON Schema для аргументов;
- JSON Schema или описание структуры результата;
- дополнительная мета‑информация (например, привязка к конкретному UI‑компоненту в Apps SDK).
Сервер MCP обязан уметь, по крайней мере, отвечать на «запрос списка инструментов» и обрабатывать «вызов инструмента», возвращая структурированный результат.
В нашем учебном приложении Gift‑помощника уже есть, допустим, инструмент suggest_gifts, который принимает возраст, пол, бюджет и пару предпочтений, а возвращает список рекомендованных подарков.
Условный TypeScript‑скетч такого инструмента в коде MCP‑сервера может выглядеть, например, так (псевдокод/заглушка):
// Псевдо-код, не финальный API SDK
const suggestGiftsTool = defineTool({
name: "suggest_gifts",
description: "Подбирает идеи подарков по параметрам получателя",
inputSchema: z.object({
age: z.number(),
relation: z.enum(["friend", "partner", "parent"]),
budgetUsd: z.number(),
}),
handler: async (input) => {
// TODO: ваша бизнес-логика
return { items: [] };
},
});
Реальные сигнатуры мы будем разбирать в следующих лекциях, здесь важна идея: инструмент — это не просто REST‑эндпоинт, это элемент протокола с объявленной схемой.
Ресурсы (resources): данные, к которым можно обратиться по ID/URI
Ресурсы (resources) в MCP — это способ описать доступные данные: файлы, каталоги, записи БД, вики‑страницы, даже результаты поисковых индексов. Клиент может:
- получить список ресурсов;
- прочитать конкретный ресурс по ID/URI;
- иногда — выполнить поиск по ним.
В отличие от tools, которые «что‑то делают», resources обычно «что‑то хранят». Например, в Gift‑App вы можете представить каталог товаров как ресурс gift_catalog, к которому модель обращается, чтобы узнать доступные категории, фильтры, диапазоны цен и так далее.
В коде это может выглядеть концептуально так:
const giftCatalogResource = defineResource({
uri: "catalog://gifts",
description: "Каталог подарков, доступных для рекомендации",
read: async () => {
// Возвращаем структуру каталога
return { categories: [], priceRanges: [] };
},
});
Мы пока не лезем в формат MCP‑сообщений, но держим в голове: ресурсы — это адресуемые сущности, на которые сервер MCP может сослаться, а клиент — прочитать и использовать как часть контекста.
Prompts: заготовленные подсказки
Prompts в контексте MCP — это шаблоны запросов или инструкций, которые сервер может предоставить клиенту. Например, вы можете объявить промпт gift_followup, который описывает, как модель должна уточнять у пользователя детали про получателя подарка, прежде чем вызывать инструмент.
Типичный пример в духе протокола: сервер даёт имя промпта, его назначение, иногда параметры. Клиент может запросить список промптов, выбрать нужный и подставить в запрос к модели.
Зачем это нужно ChatGPT App? Во‑первых, это единый способ переиспользовать сложные подсказки между клиентами. Во‑вторых, MCP делает такие промпты явными и «подконтрактными», а не спрятанными в случайных местах кода.
Capabilities: объявление того, что вы вообще поддерживаете
Наконец, есть четвёртый элемент — capabilities. Это просто декларация: сервер говорит, какие из сущностей он поддерживает (tools, resources, prompts, нотификации и т.д.) и какие именно методы он реализует. Для клиента это способ не гадать, что можно делать, а что нельзя, и аккуратно адаптировать своё поведение под возможности сервера.
На практике ChatGPT, подключаясь к вашему MCP‑серверу, сначала выполняет «рукопожатие», получает список capabilities, а уже потом спрашивает: «Окей, покажи мне свои инструменты и ресурсы».
5. Как MCP встраивается в ваш текущий App
Всё это звучит немного абстрактно, но на самом деле вы уже сталкивались с MCP через Apps SDK. Думаю стоит начать с того, что разобраться, а как это все стыкуется с тем, что вы уже написали в рамках Apps SDK? Давайте свяжем только что введённые сущности с тем, как сейчас устроен ваш шаблон App.
Вспомним цепочку, которую вы уже реализовали в шаблоне:
- Виджет через window.openai или готовые хуки вызывает callTool с именем инструмента и аргументами.
- Apps SDK внутри ChatGPT превращает это в обращение к серверной части App.
- Сервер выполняет инструмент и возвращает ToolOutput, включающий structuredContent, content и _meta.
- Виджет получает ToolOutput и рисует UI.
Секрет в том, что шаги 2–3 реализованы как диалог по MCP. Ваш Next.js‑шаблон содержит эндпоинт (обычно app/mcp/route.ts или похожий), который именно и является MCP‑сервером. Он:
- регистрирует ваши инструменты;
- описывает их через JSON Schema;
- реализует обработчики;
- отвечает ChatGPT на MCP‑запросы list tools и call tool.
То есть фактически даже сейчас, пользуясь шаблоном, вы уже работаете с MCP, просто в «автоматически»: большая часть протокольной магии спрятана в SDK.
Модуль 6 нужен затем, чтобы перестать относиться к MCP как к «магическому чёрному ящику» и начать осознанно проектировать его:
- добавлять и версионировать инструменты;
- использовать resources и prompts, а не только tools;
- читать и понимать логи MCP;
- при необходимости поднимать отдельные MCP‑сервера вне Next.js‑шаблона (например, Python‑сервис для работы с ML‑моделью или отдельный сервис доступа к корпоративной базе).
6. MCP с точки зрения разных ролей: продакт vs разработчик
Полезно отдельно сформулировать, что даёт MCP продакт‑менеджеру и что — инженеру.
MCP для продакта
С точки зрения продукта MCP — это способ сделать ваш сервис «подключаемым модулем» для целого зоопарка клиентов: ChatGPT, другие LLM‑клиенты, IDE‑плагины, собственные агенты. Один раз описав возможности сервера в виде набора tools/resources/prompts, вы позволяете любому клиенту:
- автоматически обнаружить ваш сервис;
- понять, какие задачи он решает;
- безопасно вызывать необходимые операции.
В случае с ChatGPT App это ещё и повышает вероятность выбора вашего приложения: модель использует метаданные о ваших инструментах, чтобы решать, когда предлагать ваш App пользователю и как правильно его представить.
Если совсем коротко: MCP делает ваш сервис стандартным «кирпичиком» экосистемы, а не кастомной интеграцией на один‑два клиента.
MCP для разработчика
С точки зрения инженера MCP — это контракт и протокол. Он отвечает на вопросы:
- В каком формате я должен объявить инструмент?
- Как описать аргументы и вернуть результат?
- Как клиент поймёт, что я поддерживаю ресурсы и промпты?
- Какой JSON вообще будет гулять по сети?
Когда у вас есть такой протокол, становится проще:
- писать серверы на разных языках (есть официальные SDK для TypeScript и Python);
- отлаживать приложение через MCP Inspector или аналогичные тулзы;
- делить ответственность между командами: одна команда делает MCP‑сервер с данными и инструментами, другая — виджет на Apps SDK, третья — может строить своих агентов поверх этого же MCP‑сервера.
7. Маленькая практическая перспектива: наш первый MCP‑сервер
В этой лекции мы намеренно не уходим в детали формата сообщений и реализации сервера — это материал следующих тем. Но чтобы вы заранее понимали, к чему идём, полезно увидеть общую структуру минимального MCP‑сервера на TypeScript.
В реальности официальная TypeScript‑библиотека MCP даёт вам примитивы для создания сервера, регистрации tools/resources/prompts и запуска транспорта (обычно HTTP или SSE).
Условный псевдо‑пример может выглядеть так:
// Это концептуальный пример, API SDK мы разберём позже
import { createServer } from "@modelcontextprotocol/sdk";
const server = createServer({
name: "gift-genius",
version: "1.0.0",
});
// Регистрируем инструмент
server.tool("suggest_gifts", {
description: "Подбирает подарки по предпочтениям получателя",
inputSchema: {/* ... */},
handler: async (input) => {
// ваша логика
return { items: [] };
},
});
// Запускаем транспорт (например, HTTP)
server.listen(3001);
Важный момент: здесь нигде не упоминается ChatGPT, Apps SDK или ваш конкретный фронтенд. MCP‑сервер самодостаточен. Он просто умеет отвечать на MCP‑запросы. ChatGPT App — лишь один из типов клиентов, которые такой сервер могут использовать.
В рамках курса мы будем держаться Next.js‑шаблона, где MCP‑сервер живёт как часть проекта, но это не единственно возможный вариант.
8. MCP в экосистеме: Apps SDK, Agents SDK и ACP
Чтобы не воспринимать MCP как «фичу только для Apps SDK», полезно увидеть его в более широкой картине.
Во‑первых, Apps SDK прямо опирается на MCP как на стандартный мост между ChatGPT и внешними сервисами. Официальная документация подчёркивает: Apps SDK работает с любыми MCP‑серверами. Сам протокол позволяет описывать инструменты, возвращать структурированные данные и указывать компонент для рендеринга в UI.
Во‑вторых, Agents SDK, который вы будете разбирать в отдельном модуле, тоже умеет подключаться к MCP‑серверам. Это значит, что один и тот же MCP‑сервер с бизнес‑логикой может быть использован:
- внутри ChatGPT как часть вашего App;
- внутри автономного агента, работающего, например, в фоне вашего продукта или в batch‑режиме.
В‑третьих, ACP (Agentic Commerce Protocol), который понадобится вам для покупок и Instant Checkout, логически строится поверх MCP‑подхода: модель и агенты вызывают commerce‑инструменты, которые тоже описаны через стандартизированные контракты.
Таким образом MCP становится фундаментом, на котором уже строятся UI (Apps SDK), агентные сценарии (Agents SDK) и коммерция (ACP). Если вы уверенно чувствуете MCP, всё остальное становится понятнее и предсказуемее.
Примечание: Формально ACP не зависит от MCP как спецификация, но в реальной реализации инструменты ACP, скорее всего, будут вызываться моделью именно через MCP-интерфейсы. Один подход очень красиво накладывается на второй, так что ждать нам осталось совсем не долго.
9. Небольшие упражнения «в голове» перед практикой
Прежде чем в следующей лекции нырять в формат MCP‑сообщений, полезно прогнать пару мысленных упражнений. Это поможет «переключить» мышление с «типичного REST» на «протокол + контракт».
Представьте, что к вашему Gift‑App хочет подключиться не только ChatGPT, но и IDE‑плагин для VS Code, и внутренний корпоративный ассистент в Slack. Опишите одним предложением, что им всем нужно знать про ваш сервис. Скорее всего ответ будет примерно: «У нас есть инструмент suggest_gifts с такими‑то параметрами, и каталог подарков, доступный через такой‑то ресурс». Это и есть то, что MCP формализует.
Попробуйте также сформулировать двумя фразами:
- что такое MCP для продакта вашего App (подсказка: стандартный способ «упаковать» функциональность для разных клиентов);
- что такое MCP для разработчика (подсказка: JSON‑RPC протокол с чёткими примитивами tools/resources/prompts).
Если вы можете это сделать без заикания — вы уже на полпути к уверенной работе с MCP.
Если свести всё выше к одному тезису: MCP — это не ещё один надстройочный API, а базовый контракт между вашей логикой и LLM‑клиентами. В следующих лекциях мы заглянем внутрь самого протокола: разберём формат MCP‑сообщений, handshake/capabilities и научимся смотреть на трафик через инспекторы, чтобы все эти принципы были не абстракцией, а рабочим инструментом.
10. Типичные ошибки и заблуждения вокруг MCP
Ошибка №1: считать MCP «ещё одним API‑слоем поверх моего REST».
Иногда возникает соблазн: «Ну у меня уже есть REST, давайте я просто накручу тонкий адаптер, который превратит MCP‑вызовы в REST и обратно, и забуду». Формально так можно сделать, но тогда вы часто начинаете «протаскивать» особенности старого API внутрь MCP: странные типы, неструктурированные ответы, отсутствие явных схем. Со временем адаптер разрастается, а выигрыш от MCP снижается. Лучше воспринимать MCP как основной контракт, а старый REST — как внутреннюю деталь реализации, если он вам ещё нужен.
Ошибка №2: думать, что MCP «только для ChatGPT Apps».
MCP — это общий открытый протокол для любых LLM‑клиентов: ChatGPT, IDE‑плагины, автономные агенты. Если вы проектируете MCP‑сервер с прицелом только на один App, вы ограничиваете себя в будущем. Гораздо выгоднее сразу думать: «этот сервер смогут использовать и другие клиенты», и проектировать инструменты и ресурсы чуть более универсальными.
Ошибка №3: игнорировать JSON Schema и описывать аргументы «на словах».
Даже если SDK позволяет вам где‑то передать «любой JSON», не ленитесь описывать схемы аргументов и результатов. От этого напрямую зависят способность модели правильно вызывать ваш инструмент, качество автодополнения и дискавери, а также удобство отладки через инспекторы. Неописанные или плохо описанные аргументы — прямой путь к загадочным tool‑call‑ошибкам.
Ошибка №4: воспринимать MCP как «магический транспорт» и не смотреть в логи.
Пока всё работает, кажется, что MCP — какая‑то невидимая штука, о которой не нужно думать. Проблема в том, что как только что‑то ломается, без понимания MCP‑структуры вы будете долго гадать: «это Apps SDK? это модель? это мой бэкенд?». Привычка смотреть на MCP‑сообщения и логи на раннем этапе убережёт от часов бессмысленного шаманства.
Ошибка №5: пытаться проектировать сложный workflow только через REST, игнорируя MCP‑примитивы.
Когда у вас появляются многошаговые сценарии (поиск подарка → уточнение предпочтений → выбор → оформление заказа), хочется просто «сделать один большой REST‑эндпоинт». В контексте ChatGPT Apps это часто ухудшает управляемость: модель хуже понимает промежуточные шаги, а MCP‑клиент теряет возможность переиспользовать ресурсы и промпты. Гораздо лучше разбивать функциональность на несколько хорошо описанных tools/resources, а логику связывать системными промптами и корректными описаниями.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ