Вчера я наткнулся на submission на Reddit про MCP vs CLI.
Автор поднимает вопрос, который сейчас всё чаще обсуждается среди разработчиков AI-агентов: а нужен ли нам вообще MCP, если обычный CLI во многих задачах оказывается дешевле, быстрее и надёжнее?
Тема напрямую пересекается с тем, над чем я сейчас работаю в Arcanada: архитектурой автономных агентов, технологией управления смыслами и концепцией Knowledge Contract.
Чем дольше я смотрел на спор в комментариях, тем сильнее приходил к мысли, что MCP vs CLI — неправильный вопрос. Оба лагеря во многом правы: обсуждение идёт уровнем ниже той абстракции, на которой эту проблему в итоге нужно решать.
Начнём с самого спора.
Откуда взялось «CLI лучше MCP»
Автор поста ссылается на benchmark Scalekit: 75 тестовых запусков, в которых сравнивалась работа AI-агента через MCP и CLI.
Результаты получились довольно жёсткими для MCP.
В зависимости от задачи CLI требовал в разы, а иногда в десятки раз меньше токенов.
Особенно показателен простой пример с определением языка репозитория: CLI потребовал 1 365 токенов, а MCP — 44 026.
В отдельной проверке надёжности Scalekit, где было по 25 запусков, CLI успешно завершил 25 из 25 (100%), а MCP — 18 из 25 (72%).
Отсюда возникает вопрос:
зачем мы вообще строим тысячи MCP-серверов?
Не происходит ли сейчас очередная история, когда вся индустрия бросилась внедрять новый стандарт просто потому, что он модный?
В комментариях есть точная формулировка:
MCP нравится людям, которые создают инструменты. CLI нравится людям, которые этими инструментами пользуются.
Довольно точно.
Почему агентам действительно так хорошо подходит CLI
При разборе аргументов сторон нужно учитывать, что CLI — это не просто ещё один интерфейс вызова функции.
При прямом вызове агент получает ответ инструмента сразу. CLI добавляет между моделью и результатом shell и программируемую обработку данных.
Верхняя дорожка показывает прямой вызов инструмента и полный ответ. В нижней дорожке агент запускает shell, CLI получает данные, промежуточные программы их фильтруют, и в контекст попадает только выбранный результат.
Между моделью и инструментом появляется программируемая вычислительная среда.
Это позволяет уменьшить ответ до того, как он попадёт в контекст модели.
Предположим, агент запросил несколько мегабайт логов.
Если обычный tool вернёт ему всё это в контекст, модель должна каким-то образом прочитать и обработать огромный ответ.
Но через CLI агент может сделать:
deployment list --json \
| jq '.[] | select(.status == "failed") | {id, reason}' \
> /tmp/failed.jsonи прочитать уже только результат.
Он может использовать:
- grep
- jq
- awk
- sed
- sort
- head
- SQL
- Python
- pipes
- files
То есть AI не просто вызывает инструмент.
Он программирует промежуточную обработку информации.
И это, на мой взгляд, одна из причин, почему coding agents настолько хорошо чувствуют себя в терминале.
Есть даже хороший комментарий под постом:
CLI makes the agent more capable.
Сначала фраза кажется немного громкой.
Но если вдуматься — в ней есть смысл.
CLI даёт агенту не каталог функций.
Он даёт ему маленький компьютер.
Но у MCP тоже есть очень сильный аргумент
Теперь представим другую ситуацию.
Ваш AI-агент работает не на вашем сервере и не с вашим Git.
Он работает от имени тысячи клиентов.
Он ходит в:
- GitHub
- Gmail
- Slack
- Salesforce
- корпоративные базы
- внутренние SaaS
И здесь возникают совершенно другие проблемы.
От имени какого пользователя сейчас действует агент?
Какие permissions у этого пользователя?
К какой организации он относится?
Какие credentials нужно использовать?
Разрешено ли ему только читать информацию или ещё и изменять её?
Как отозвать доступ?
Как потом установить, кто и почему совершил действие?
Когда агент действует от имени других пользователей, идея «просто дать ему shell» сталкивается с требованиями authentication, authorization, tenant isolation и audit.
Один из комментариев в обсуждении довольно хорошо сформулировал границу:
CLI подходит для персональных инструментов и внутренней автоматизации.
Но когда агент действует от имени чужих пользователей, появляются authentication, authorization, tenant isolation и audit.
И MCP здесь действительно решает другую задачу.
То есть оба лагеря правы?
В значительной степени — да.
CLI хорош как execution mechanism.
MCP хорош как integration mechanism.
Поэтому мне очень понравился ещё один комментарий:
We use both. Core product is full CLI, remote access and A2A sessions use MCP.
Это уже намного ближе к тому, что сейчас проектируется у меня в Arcanada.
Даже выбор «CLI или MCP?» слишком низкоуровневый для самого агента.
А почему агент вообще должен об этом думать?
Это связано с темой, которой я занимаюсь последние месяцы.
Одна из проблем современных AI-агентов заключается в том, что на модель постепенно сваливают практически всю сложность системы.
Модель получает задачу, prompt, RAG, 150 tools, 20 MCP-серверов, permissions, документацию и дополнительные правила, а затем должна сама разобраться во всей этой инфраструктуре.
И мы потом удивляемся, почему контекст разрастается до сотен тысяч токенов и агент начинает путаться.
Я всё сильнее прихожу к противоположной модели:
чем больше система может определить до запуска агента, тем меньше этой инфраструктурной сложности должен видеть сам агент.
И отсюда появилась одна из идей, над которыми я сейчас работаю в Arcanada, — Knowledge Contract.
Что такое Knowledge Contract
Я пока не буду здесь полностью раскрывать всю конструкцию — ей будет посвящена отдельная публикация.
Базовая конструкция такая.
Агент не должен получать просто:
«Вот тебе задача. Разберись».
До выполнения задача проходит через отдельный Resolver Pipeline.
Система пытается определить, какие смыслы необходимы агенту для выполнения конкретной работы.
В результате формируется структурированный Knowledge Contract.
В текущей модели он включает:
- Task
- Role
- Skills
- Blueprints
- Constraints
- Success Criteria
Например, есть задача:
Определить причину падения production deployment и подготовить исправление.
Для неё система может определить:
- Role: Software Engineer
- Skills: debugging, deployment analysis, testing
- Blueprints: production incident investigation; safe code modification; maker-checker validation
- Constraints: production read-only; deployment только после approval
- Success Criteria: root cause найден; исправление подготовлено; тесты проходят
То есть агенту передаётся уже не просто prompt.
Ему передаётся контракт смысла и исполнения задачи.
Это связано с моей более широкой задачей — управлением смыслами.
Мы пытаемся не просто положить в context побольше информации.
Мы пытаемся определить:
какая именно информация, роль, навык, паттерн поведения и ограничение нужны для решения именно этой задачи.
Разбор Reddit подсказал ещё один элемент
Разбирая спор MCP vs CLI, я понял, что в Knowledge Contract, скорее всего, не хватает ещё одного фундаментального измерения.
Capabilities.
То есть возможностей, которые необходимы агенту для выполнения задачи.
Для нашего примера это может выглядеть так:
Capabilities: repository.read, repository.diff, logs.query, deployment.status, tests.run.
В Knowledge Contract перечислены capabilities, но не указано, будут ли они предоставлены через MCP или CLI. Это определяет Capability Resolver.
Capability — это «что», а механизм исполнения — это «как»
Допустим, агенту необходима capability repository.diff. Агенту не нужно самому выбирать протокол: Capability Resolver создаёт binding между capability, исполнителем и механизмом доступа.
Каждая строка на схеме — отдельное соответствие, а не последовательность вызовов. OAuth задаёт способ доступа к MCP-сервису, а Research Agent остаётся исполнителем; A2A используется для делегирования между агентами.
На уровне reasoning агент оперирует набором требуемых capabilities:
repository.diffcustomer.crm.readdeployment.statusresearch.deep
Ему не нужно знать, будут ли они предоставлены через CLI, MCP, API или с помощью другого агента.
Это и есть граница абстракции, которую я считаю правильной.
Агент должен мыслить действиями, а не протоколами
Представьте человека.
Когда программист думает:
Мне нужно посмотреть изменения в репозитории,
он не размышляет на уровне системных вызовов ядра Linux.
Когда мы открываем файл, мы не думаем о секторах SSD.
Когда выполняем SQL-запрос, мы не думаем о страницах B-tree.
Хорошая архитектура постоянно создаёт такие границы абстракций.
Почему с AI-агентами мы вдруг решили, что модель должна понимать всю инфраструктуру целиком?
Я считаю, что агент должен мыслить примерно так:
Мне необходимо получить deployment logs.
А не:
Сейчас мне нужно найти MCP server №17, выбрать tool №43, изучить его JSON Schema и сформировать правильный payload.
И не:
Сейчас мне нужно вспомнить конкретную команду CLI конкретного vendor.
Это инфраструктура.
А не reasoning.
Capability Resolver
В архитектуре Arcanada Capability Resolver связывает задачу и Knowledge Contract с конкретным execution plan.
Knowledge Contract фиксирует, что агенту нужно знать и уметь. Resolver определяет, кто выполнит каждую capability, каким способом и с какими правами. Эти маршруты являются альтернативными binding-ами и сходятся только после получения observations.
Если для задачи нужны три capabilities, агенту незачем вообще знать о существовании остальных трёхсот инструментов системы.
Он получает только repository.diff, logs.query и tests.run.
Это уже не только экономия токенов
На первый взгляд может показаться, что мы опять вернулись к проблеме стоимости context window.
Но последствия выходят за пределы стоимости context window.
Чем меньше capability surface получает агент, тем меньше:
- расход токенов;
- вероятность выбрать неправильный инструмент;
- количество потенциальных ошибок;
- поверхность атаки;
- набор permissions;
- сложность reasoning.
То есть Capability Resolver становится одновременно:
оптимизатором контекста, маршрутизатором исполнения и элементом security architecture.
Поэтому Capability Resolver одновременно уменьшает capability surface, маршрутизирует исполнение и участвует в security architecture.
Есть ещё третий путь — Code Mode
В комментариях Reddit есть сильный аргумент в пользу CLI:
CLI позволяет направлять большой output в файл, фильтровать его, обрабатывать другими программами и только потом показывать модели.
Традиционные tool calls делают это значительно хуже.
Есть и другой подход — Code Mode. Вместо нескольких последовательных обменов между моделью и инструментами агент выполняет промежуточную обработку в одной программе:
const deployments = await deployment.list();
const failed = deployments
.filter(x => x.status === "failed")
.map(x => ({
id: x.id,
reason: x.failureReason,
}));
return failed;Она выполняется внутри sandbox.
А модель получает только итог.
Так Code Mode сохраняет преимущество CLI — возможность программировать промежуточное вычисление — и отделяет его от конкретного shell-интерфейса. В Arcanada Code Execution Runtime относится к этому слою.
А иногда capability — это вообще не инструмент
Capability может означать делегирование работы другому агенту.
Предположим, агент понимает:
Мне необходимо глубокое исследование этой гипотезы.
Почему он обязан вызывать tool?
Например, capability research.deep может означать делегирование работы Research Agent через A2A. В этом случае A2A не является исполнителем: он передаёт работу другому автономному исполнителю.
CLI, MCP, API и A2A не обязаны конкурировать. Они обслуживают разные способы исполнения capabilities.
Какой уровень нужен агенту
Я уже некоторое время пытаюсь подняться на уровень выше традиционного разговора:
Model + Prompt + Tools
Меня не очень устраивает подход, когда проектирование агента начинается с выбора harness или списка инструментов.
Сначала необходимо определить смысл задачи и условия её выполнения.
После этого система подбирает модель агента, skills, knowledge, tools и execution mechanism. Поэтому я много работаю над Knowledge Contract: MCP vs CLI показывает, зачем нужен такой уровень.
При таком подходе сначала определяется необходимая capability, а затем система выбирает способ её предоставить. Для меня это принципиальное различие.
Что сейчас проектируется в Arcanada
В Arcanada и связанных с ним проектах я сейчас проектирую и постепенно реализую примерно такую модель:
Схема разделяет пять уровней. Task Intake формулирует задачу и проводит Semantic Analysis. Knowledge Contract хранит параллельные поля: роль, навыки, blueprints, ограничения, критерии успеха и требуемые capabilities. Затем Orchestration связывает Capability Resolver с Planning.
На уровне Execution Runtime доступны адаптеры CLI, MCP, API, Code и A2A. После исполнения система передаёт observations на Validation и формирует Result.
При этом отдельные части этой архитектуры распределены между несколькими компонентами Arcanada.
- Задачи, их состояние и жизненный цикл управляются отдельно.
- Знания и blueprints хранятся отдельно.
- Подбор контекста выполняется отдельным слоем.
- Исполнение и контроль результата разделены.
Мне важно не построить одного гигантского «умного агента».
Я пытаюсь вынести как можно больше сложности из головы агента в архитектуру вокруг него.
Так всё-таки MCP или CLI?
После чтения Reddit мой ответ такой:
CLI — отличный механизм исполнения.
MCP — отличный кандидат на стандартизированный слой интеграции.
API и SDK никуда не исчезают.
Code Mode может оказаться одним из лучших способов композиции операций.
A2A нужен для взаимодействия автономных исполнителей.
Выбирать одного победителя не нужно.
В Arcanada я сейчас иду в сторону гибридной модели:
Knowledge Contract фиксирует capabilities, а Capability Resolver выбирает лучший доступный Execution Mechanism.
Сегодня capability может выполняться через CLI.
Завтра тот же контракт может использовать MCP.
Через год появится более хороший протокол — поменяем adapter.
Самому агенту всё равно.
MCP vs CLI — это спор о реализации
Вопрос выше реализации — что должно оставаться неизменным при смене протокола?
Мой текущий ответ: смысл задачи, Knowledge Contract и необходимые capabilities. CLI, MCP, API, Code Mode и A2A — способы воплотить этот смысл в действие.
Возможно, через несколько лет мы вообще перестанем обсуждать, какой протокол использует агент для доступа к конкретному инструменту.
Так же как сегодня разработчик приложения редко думает о том, каким способом контроллер SSD записывает конкретный блок данных.
Если архитектурная граница выбрана правильно, эта сложность должна исчезнуть с верхнего уровня.
Такую границу я сейчас пытаюсь построить в Arcanada.