MCP или REST API: полвека одного вопроса
Как программы учились объяснять себя и почему редакция 2026 года развернула MCP обратно к REST
Написано 5 августа 2026 года. MCP меняется очень быстро: за неполные два года — пять редакций спецификации, и последняя из них, от 28 июля 2026-го, переписала основы. Если вы читаете это через полгода, сверьтесь с первоисточником: часть написанного здесь уже может быть неправдой.

Как программы договариваются между собой
Есть спор, который в 2026 году встречается в каждой второй технической дискуссии: «MCP или REST API?». Спор устроен неудачно — он сравнивает вещи разной природы.
REST — это архитектурный стиль интерфейса между двумя программами, описанный в 2000 году. Model Context Protocol, опубликованный в ноябре 2024-го, — это способ рассказать языковой модели прямо по ходу разговора, что умеет программа. Их гораздо чаще складывают друг на друга, чем выбирают между ними: MCP снаружи, тот же самый REST API внутри. А в июле 2026-го MCP стал stateless — принял то самое ограничение, на котором REST стоит с 2000 года.
Но за спором стоит настоящий вопрос, и он интереснее: как программа объясняет другой программе, что она умеет? За полвека ответ переписывали четыре раза — в 1970-е, в 1990-е, в 2000-м и снова в 2024-м, — и каждый раз казалось, что вот этот уже окончательный.
Эта статья — про то, как мы сюда пришли. Без кода. Если вы не программист, но хотите понимать, о чём спорят вокруг вас, — она написана для вас.
Задача, которой полвека
Задача, которой полвека
Две программы, две машины. Одной нужно, чтобы другая что-то сделала: прочитала запись, списала деньги с карты, отдала файл. Всё остальное в этой статье вырастает из этой фразы — и полвека оказывается сложнее, чем она звучит.
Трудностей три, и ни одна никуда не делась. Сеть отказывает, причём отказывает особым образом: не говорит «нет», а молчит. Машины разные: порядок байтов, размер числа, кодировка строки. И договориться надо до того, как обе программы запустятся, потому что программа не может ответить на вопрос, которого её не научили слышать.
Первый серьёзный ответ появился в 1970-е, и он был красив. RFC 707, опубликованный в 1976 году, предложил считать запрос по сети обычным вызовом процедуры: вызывающий называет функцию и передаёт аргументы, а где она выполняется — чужая забота. Xerox PARC довёл идею до рабочей практики: Cedar RPC Бирелла и Нельсона, описанный в 1984-м, с компилятором, который сам порождал обвязку с обеих сторон.
Идея красива тем, что вычёркивает целый пласт работы. Программист пишет balance(account) и думает про счета, а не про сокеты, таймауты и порядок байтов; код, написанный под одну машину, можно разрезать пополам и разнести на две почти без правок. Для большей части кода и большую часть времени маскировка держится.
Почему RPC не выжил: частичный отказ
Почему RPC не выжил: частичный отказ
Разбилась она в единственном шве, где маскировка тоньше всего. В 1994 году четверо инженеров Sun — Уолдо, Уайант, Уоллрат и Кендалл — написали статью, закрывшую спор: «A Note on Distributed Computing», где перечислено то, что костюм не переживает, — задержка, доступ к памяти, параллелизм и частичный отказ. Главное здесь — частичный отказ. У локального вызова два исхода: он возвращает результат или падает так, что вместе с ним умирает весь процесс. У сетевого есть третий, и третий — это тишина. Тишина не говорит, списались деньги с карты или нет. А код, который с ней разбирается — повторить, сверить, спросить человека, — это ровно тот код, который абстракция бралась спрятать. RPC сделал невидимыми лёгкие девяносто пять процентов и заодно оставил невидимыми оставшиеся пять.
Эпоха тяжёлых договорённостей
Эпоха тяжёлых договорённостей
1990-е отвечали на другой вопрос. Не «как сделать так, чтобы сетевой вызов выглядел локальным», а «как записать договорённость настолько точно, чтобы ни одна сторона не могла её нарушить».
Первой была CORBA. Object Management Group собралась в 1989-м, спецификация вышла в 1991-м, и её сердцевиной был IDL — Interface Definition Language, язык, предназначенный только для описания интерфейсов. Интерфейс писали на IDL, компилятор порождал из него клиентскую заглушку и серверный каркас, а вызовы переносил Object Request Broker. SOAP повторил ту же форму в XML: XML-RPC в 1998-м, SOAP 1.1, поданный в W3C как Note в 2000-м (рекомендацией W3C SOAP стал только в версии 1.2, в 2003-м), и контракт под названием WSDL — сам такой же Note, годом позже, — где перечислены операции, форма каждого сообщения, типы и адрес, куда всё это слать. Вокруг него вырос выводок WS-* — WS-Security, WS-Addressing, WS-ReliableMessaging, — десятки спецификаций, каждая решала настоящую проблему, а вместе они были больше большинства систем, которые на них строили.
Контракт в этом смысле — машиночитаемое описание всего, что одна программа готова принять от другой: имена, аргументы, типы, ошибки. Он жил на отдельном языке потому, что исходный код ни одной из сторон не годился на роль договора: стороны обычно писали разные компании на разных языках, и весь смысл был в том, чтобы никому не приходилось читать чужой код. Выигрыш был настоящий: расхождение между вызывающим и вызываемым превращалось в ошибку сборки во вторник днём, а не в аварию в три часа ночи.
«Громоздкость и негибкость» — это то, что пишут в ретроспективах, и оно ничего не объясняет. Вот счёт. Добавление одного необязательного поля означало перегенерацию заглушек с обеих сторон и синхронный выкат обеих — мелкая правка превращалась в задачу согласования между двумя компаниями. WSDL скромного сервиса занимал тысячи строк, которых не читал ни один человек. А два инструментария разных вендоров, прочитав один и тот же WSDL, порождали клиентов, которые не понимали друг друга; ответом отрасли стал WS-I Basic Profile 2004 года — документ о том, каким подмножеством стандартов всем следует пользоваться. Контракт о том, как писать контракты.
Чем строже договорённость, тем труднее её менять. Это вернётся ещё до конца статьи. Строгость никогда не бесплатна. Её оплачивают позже — тот, кому понадобится добавить поле.
2000 год: диссертация, изменившая веб
2000 год: диссертация, изменившая веб
В 2000 году Рой Филдинг защитил диссертацию в Калифорнийском университете в Ирвайне. Он ничего не предлагал и ничего не продавал: он был соавтором HTTP/1.1 и спецификации URI, а пятая глава объясняет задним числом, почему веб отмасштабировался там, где тщательно спроектированные архитектуры вокруг него — нет. Объяснению он дал имя: REST.
Необычен здесь метод. Филдинг начинает с системы, у которой нет вообще никаких ограничений, и добавляет их по одному, каждый раз отнимая возможность и получая взамен свойство. Обязательных ограничений пять. Шестое необязательное, и им почти никто не пользуется.
Шесть ограничений REST
Шесть ограничений REST
Разделить стороны — чтобы клиент и сервер можно было переписывать и выкатывать независимо. Не хранить память между вызовами — чтобы всё нужное для понимания запроса ехало внутри самого запроса. Помечать, можно ли переиспользовать ответ, — чтобы отдать его мог кто-то, кроме источника. Держать интерфейс единообразным: небольшой фиксированный словарь — адресуемые ресурсы, горстка глаголов, самоописательные сообщения — вместо своего набора операций у каждого сервиса. Разрешить посредника — чтобы прокси, шлюз или кэш встали в цепочку, а обе стороны об этом не знали. Необязательное шестое — код по требованию, и оно так и осталось сноской.
Почему REST — stateless
Почему REST — stateless
Ограничение, которое понимают неправильно чаще прочих, — отсутствие памяти. Если сервер ничего не помнит между запросами, любой запрос может обслужить любой сервер. Поставьте за одним адресом сорок машин — и балансировщик отдаст запрос той, что свободна; потеряйте одну под нагрузкой — потеряется этот запрос и больше ничего, потому что больше на ней ничего и не лежало. А кэш перед ними ответит так, что источник об этом не узнает. Это не ограничение, которое веб терпит: это свойство, на котором стоит вся остальная инфраструктура веба, и любой CDN на свете — его следствие. Цена, которую Филдинг называет прямо, — повторы: учётные данные в каждом запросе, контекст в каждом запросе, запросы толще, чем были бы у протокола с памятью. Четверть века инфраструктуры — доказательство того, что размен был выгодный.
REST победил по причине, не имеющей отношения к красоте: он не требовал ничего нового. Ни компилятора IDL, ни брокера, ни реестра, ни шага генерации кода, ни вендора. Там, где CORBA и SOAP предлагали организации принять на вооружение целый стек, REST предлагал заметить, что она уже делает, и делать этого больше. Машиночитаемый контракт вернулся позже — как OpenAPI, родившийся в 2011-м под именем Swagger и стандартизованный как OpenAPI 3.0 в 2017-м, — но вернулся добровольным, необязательным и, что важно для дальнейшего, читаемым до запуска программы. Никто не обнаруживает эндпойнт посреди разговора.
Запомните это. Всё сказанное выше держится на одном допущении, и допущение сейчас сломается.

Проблема N×M
Что сломалось, когда появились модели
Что сломалось, когда появились модели
Допущение состоит в том, что документацию прочитал человек — до того, как программа запустилась. Заглушки RPC, IDL, WSDL, OpenAPI: всё это потребляется на этапе сборки, программистом или генератором, который работает за него. К моменту первого запроса обе стороны знают друг о друге всё, что вообще узнают. У языковой модели этапа сборки нет.
- Отличие принципиальное, а не количественное: на другом конце REST-вызова сидит программист, который заранее прочитал документацию и зашил результат в исходный код
- Модель читает инструкции там же, где читает всё остальное, — в разговоре, пока разговор идёт. Про свои возможности она должна узнать тогда же, словами, внутри запроса
- Каждый вендор решал это по-своему, и решения не стыковались: вызов функций (function calling), манифесты плагинов, самодельные форматы инструментов — у каждого своя схема для одной и той же идеи
- Отсюда сразу проблема «N на M». Три модели и три сервиса — это девять отдельных переходников, и каждый новый сервис с любой стороны не прибавляет, а умножает
Ноябрь 2024: появляется MCP
Ноябрь 2024: появляется MCP
25 ноября 2024 года Anthropic опубликовала Model Context Protocol. Первая редакция спецификации помечена датой 2024-11-05 — отсюда расхождение в три недели между ярлыком версии и анонсом, и о нём полезно знать до того, как читать список редакций ниже. Что для запуска протокола редкость, Anthropic прямо назвала образец, вместо того чтобы объявить себя изобретателем.
- Образцом был Language Server Protocol, восемью годами раньше решивший ту же по форме задачу для редакторов кода. До LSP каждому редактору нужен был свой плагин под каждый язык; после — язык писал один сервер, и его использовали все редакторы. «N на M» стало «N плюс M»
- Три вещи, которые MCP-сервер может предложить: инструменты (действия, которые модель может вызвать), ресурсы (данные, которые она может прочитать), промпты (prompts) — заготовленные запросы, которые выбирает пользователь
- Ключевое расхождение со всем сказанным выше: список возможностей запрашивается во время работы, а не читается заранее. Клиент спрашивает у живого сервера, что тот умеет, и передаёт ответ модели текстом
- Что это дало — рычаг. Сервис пишет один сервер; Claude Desktop, Cursor и VS Code разговаривают с ним, ничего не зная о нём заранее. Один разъём вместо девяти переходников
Пять редакций за двадцать месяцев
Пять редакций за двадцать месяцев
Список изменений — обычно самый скучный документ протокола. Этот читается как пересказ сюжета.
- Ноябрь 2024 — основа: JSON-RPC, stdio и HTTP+SSE
- Март 2025 — OAuth 2.1, новый транспорт, пакетная отправка
- Июнь 2025 — структурированный вывод; пакетную отправку убирают, не прожив и трёх месяцев
- Ноябрь 2025 — иконки, значения по умолчанию в схемах, JSON Schema 2020-12
- Июль 2026 — самая крупная переделка за всю историю протокола
Читать здесь надо даты, а не строки. Возможность, добавленная в марте и удалённая в июне, ничего не держала на себе, а вот переделка основ на двадцатом месяце означает, что основы были неверны, и это новость другого рода. Протокол не устоялся. Строить на нём — значит соглашаться переписывать.
Разворот 2026 года
Разворот 2026 года
Редакция от 28 июля 2026 года убрала из MCP сессии, а вместе с ними — рукопожатие, которым открывалось каждое соединение. В исходной конструкции клиент подключался, объявлял свою версию протокола и возможности, получал в ответ серверные, и дальше обе стороны ссылались на разговор, который помнили совместно. Этого разговора больше нет. Каждый запрос теперь несёт свою версию и свой контекст, и сервер вправе ответить на него, не видя ничего из предыдущего.
По-человечески: MCP стал stateless, то есть «без памяти». Это второе ограничение Филдинга, принятое на двадцать месяцев позже и под давлением обстоятельств — протоколом, который начинал с противоположной посылки. Всё, что из отсутствия памяти следует, последовало и здесь, в той же редакции: кэширование ответов, чтобы клиенту можно было сказать «пока не переспрашивай», и заголовки, в которых достаточно данных для маршрутизации, чтобы посредник не заглядывал внутрь тела. Это то, что дописывают, когда протоколу приходится выживать при встрече с обычной инфраструктурой.
Что редакция 2026-07-28 объявила устаревшим
Что редакция 2026-07-28 объявила устаревшим
В той же редакции устарели три собственные возможности протокола, и общее у них одно: каждая предполагала долгие отношения между двумя процессами. Обращение сервера к модели, доступ к папкам, логирование на уровне протокола. (Устаревшего в редакции больше — полный список разбирает третья статья, — но остальное хозяйственные мелочи. Эти три следуют прямо из отмены сессий.)
Считаю разворот запоздалым и правильным. Сессии в протоколе, который живёт между двумя чужими процессами, были ошибкой с самого начала: стороны выкатываются, перезапускаются, масштабируются и обновляются по разным расписаниям, а общая память между ними — обязательство, которое в итоге всегда несёт кто-то один. Это тот самый урок эпохи тяжёлых договорённостей, пришедший точно по расписанию: чем строже договорённость, тем труднее её менять. Только строгой частью тут была не схема, а требование, чтобы обе стороны помнили один и тот же разговор, — и распутать его удалось не сменой версии, а переписыванием основ.
Катастрофы для тех, кто выпускает продукт сегодня, в этом нет. Редакция 2026-07-28 вышла как Release Candidate, а не как окончательный стандарт, реализующие её SDK — в бете, у всего объявленного устаревшим есть год на переход, и 28 июля ничего не сломалось. Обратная сторона того же факта приятна меньше: серверы, написанные под сессионную модель, продолжают работать, руководства продолжают учить рукопожатию, и разрыв между тем, что написано в спецификации, и тем, что делают инструменты, сейчас самый широкий за всю историю протокола.

Схождение
MCP или REST API: чем они на самом деле различаются
MCP или REST API: чем они на самом деле различаются
Если MCP перенял отсутствие памяти, кэширование и посредников, законно спросить, что вообще осталось. Честный ответ — обнаружение возможностей, но его придётся переформулировать: расхожая версия «сервер может посреди разговора объявить о новом инструменте» плохо уживается с протоколом, у которого разговоров больше нет. Сессии, в которую сервер мог бы протолкнуть уведомление, не существует, поэтому надёжный механизм здесь — не push, а pull: клиент сам спрашивает у живого сервера, что тот умеет, и в редакции 2026 года для этого появился отдельный вызов, а к нему подсказка кэша — когда можно не переспрашивать. Сервер по-прежнему может сообщить, что его список изменился, пока открыт поток, но держать поток открытым никто не обязан, так что рассчитывать на такое уведомление клиент не вправе. Настоящего аналога в REST не имеет вовсе не объявление. Его не имеет то, что список доступных действий — значение времени выполнения, добываемое по ходу работы, тогда как OpenAPI — документ, прочитанный до её начала.
- Типизированный ответ: текст, картинка, звук или ссылка на ресурс, объявленные именно так, — вместо тела ответа, о смысле которого вызывающий должен знать заранее
- Две ступени ошибок: «сломался протокол» и «инструмент отработал и вернул неудачу». Это разные вещи, потому что вторую должна прочитать и учесть модель, а не поймать и записать в журнал программа
- Человек в контуре: спецификация прямо требует давать возможность увидеть вызов до его выполнения и отказать. Ни одному стандарту API такой пункт не был нужен — потому что ни один вызывающий не импровизировал
- Описания инструментов — недоверенный ввод. Если сервер чужой, его самоописание не доказательство, а утверждение, — и модель читает это утверждение как инструкцию. Это и есть форма промпт-инъекции (prompt injection): инструкция, приехавшая под видом данных
Рядом, с учётом редакции 2026 года:
| Вопрос | REST | MCP |
|---|---|---|
| Кто вызывает | Программист, прочитавший документацию до того, как написан код | Модель, выбирающая инструмент по ходу разговора |
| Когда известен список действий | До запуска программы; OpenAPI читают один раз при интеграции | Во время работы; клиент спрашивает живой сервер, что тот умеет |
| Формат сообщения | Глаголы HTTP, у каждого ресурса свой адрес | JSON-RPC; любой вызов идёт на один адрес как `tools/call` |
| Где лежит смысл | В адресе: `GET /articles/17` | В теле; снаружи все конверты выглядят одинаково |
| Память между вызовами | Нет с 2000 года (stateless), по замыслу | Нет с 2026-07-28 (stateless), после удаления сессий |
| Кэширование | HTTP-кэш, ETag, условные запросы, CDN | Подсказки кэша в ответе, добавлены редакцией 2026-07-28 |
| Ошибки | Код статуса HTTP, адресованный отсутствующему программисту | Две ступени: сломался протокол или инструмент отработал и принёс плохую новость модели |
| Авторизация | Обычно ключ в заголовке | OAuth 2.1, обязательный PKCE, токен привязан к получателю |
| Стоимость вызова | Предсказуемая, её можно занести в таблицу | Описания инструментов оплачиваются токенами в каждом запросе |
| Человек в контуре | Ни одному стандарту API этот пункт не был нужен | Спецификация прямо требует дать возможность увидеть вызов и отказать |
Чем всё это кончилось
Чем всё это кончилось
MCP не заменил REST и не собирался. Почти в любой живой системе они не противостоят друг другу, а стоят друг на друге: MCP-сервер — тонкий переводчик, с которым разговаривает модель, а за ним тот же самый REST API, который был там и раньше, нетронутый, по-прежнему обслуживающий мобильное приложение и веб-фронтенд. Заменять API никто и не собирался. Собирались дать новому типу вызывающего способ узнать, что этот API предлагает, — и выяснилось, что для этого нужен отдельный слой.
Интереснее направление движения. REST начинал с отсутствия памяти, кэшируемости и единообразия и четверть века добирал описание: призрак WSDL вернулся как OpenAPI, эндпойнты записали в машиночитаемом виде, чтобы инструменты читали их без человека посередине. MCP начинал с описания как единственного смысла своего существования и двадцать месяцев добирал отсутствие памяти, кэширование и возможность поставить прокси в цепочку. Они стартовали с противоположных концов и встречаются посередине. Именно это и зафиксировал разворот 2026 года: не поражение MCP, а схождение — пришедшее с той стороны, куда никто не смотрел.
Это нормальный ход вещей, а не чья-то ошибка. Выживают не те ограничения, которые нравятся проектировщику, а те, которые навязывает сеть. Между двумя процессами, принадлежащими разным людям и выкатываемыми, перезапускаемыми и обновляемыми по разным расписаниям, работают всего несколько схем. Вези контекст с собой и считай, что другая сторона может исчезнуть и вернуться другим экземпляром, который о тебе ничего не слышал. Остальное обсуждаемо — в том числе, как только что выяснил MCP, и то, позволено ли помогать тому, кто стоит посередине. RPC проигнорировал частичный отказ — и расплатился десятилетием логики повторов, которую никто не закладывал в смету. CORBA и SOAP проигнорировали стоимость изменений; WS-I Basic Profile — это квитанция. Счёт MCP пришёл 28 июля 2026 года и оказался дешевле обоих: протоколу было двадцать месяцев, и построить на нём толком ничего не успели. Каждое поколение выучивало одно и то же на своём словаре — и каждое считало, что его ответ последний.
Поэтому в следующий раз, когда очередная статья объявит об «убийце API», полезно спрашивать не о том, какая технология победит. Спрашивайте лучше, от какого из этих ограничений новинка отказалась и кто за это заплатит. Иногда ответ — «какое-то время никто». «Никто» надолго не случалось ни разу.
Во что это обходится на практике, в токенах и в деньгах, — тема второй части: сколько токенов стоит MCP. Из чего сделан MCP-сервер — транспорты, описания инструментов, авторизация — тема третьей.
Источники
Источники
Спецификация MCP публикуется на modelcontextprotocol.io; здесь использованы редакции 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25 и 2026-07-28, и официальный список изменений последней. Roy Fielding, «Architectural Styles and the Design of Network-based Software Architectures» (2000), глава 5. Jim Waldo, Geoff Wyant, Ann Wollrath, Sam Kendall, «A Note on Distributed Computing» (Sun Microsystems Laboratories, 1994). Andrew Birrell, Bruce Nelson, «Implementing Remote Procedure Calls» (1984). RFC 707. Спецификация Language Server Protocol.