Как Claude Code, Codex и другие AI Coding Agent вызывают MCP Tools: JSON-RPC, Tool Schema и права (2026)
Текст про протокол уже развёл Schema и Function Calling. Этот садится только на coding agent: модель заполняет аргументы; хозяин шлёт JSON-RPC. Подключить, перечислить, Schema, потом права — четыре шага, не фраза «подключи MCP».
Перед чтением
| Шаг | Что запирает | Кто исполняет |
|---|---|---|
| Конфиг | .mcp.json / config.toml | stdio или http; url нужен type |
| Открытие | tools/list + inputSchema | Хозяин перечисляет; модель провод не видит |
| Вызов | arguments в tools/call | Модель заполняет JSON; хозяин шлёт RPC |
| Права | mcp__server__tool / enabled_tools | Подключено ≠ автозапуск |
MCP — протокол хозяина и сервера. Модель видит имена инструментов и Schema параметров.
MCP зовёт хозяин, не модель
Claude Code, Codex и Cursor — клиенты MCP. После старта сессии хозяин подключается, шлёт JSON-RPC 2.0 tools/list и отдаёт модели каждый inputSchema. Модель выдаёт только JSON аргументов. Хозяин шлёт tools/call и даёт побочные эффекты. Без этого прыжка MCP — файл конфига.
- Конфиг: как стартует сервер. stdio — локальный процесс. http — удалённо. Оба — объекты, не устный договор.
- Schema:
order_idдолжен пройтиinputSchema. Широкий object приглашает выдуманные ключи. - Права: Claude пишет
mcp__сервер__инструмент. Codex держитenabled_toolsи режим одобрения. Cursor —mcpAllowlist. Подключить сервер эти двери не открывает.
Schema против Function Calling на слое протокола: MCP Tool Schema vs Function Calling. Свой JSON инструментов coding agent: AI coding agent и JSON-вызовы инструментов. Почему Schema — дверь: Зачем ИИ нужен JSON Schema. Этот текст слова не переопределяет. Он только показывает, как хозяин гоняет MCP.
Первый объект: конфиг сервера
Проектный файл Claude Code — .mcp.json в корне репозитория. Его можно класть в систему версий. Личные записи живут в ~/.claude.json. У url должен быть type: http (streamable-http — псевдоним) или sse / ws. url без type считают сломанным stdio и пропускают. Вымышленный сервис заказов — без настоящих секретов:
{
"mcpServers": {
"orders": {
"type": "stdio",
"command": "node",
"args": ["./servers/orders-mcp.js"]
}
}
}
Codex пишет тот же факт в ~/.codex/config.toml или в .codex/config.toml доверенного проекта, таблица [mcp_servers.orders]. stdio — command / args. Удалённое — url. Cursor — .cursor/mcp.json или пользовательский файл; редактор и CLI делят его. Новый сервер проекта в Claude Code ждёт одобрения. Сам не подключается.
Второй объект: tools/list и inputSchema
После подключения хозяин спрашивает, какие инструменты есть. Это JSON-RPC, не HTTP от модели:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
Сервер возвращает таблицу. Каждая строка — имя, описание и JSON Schema. Спека требует способность tools. Список может меняться с авторизацией. Не должен дрожать на каждое соединение. Coding agent превращает таблицу в инструменты для модели. В Claude Code вызываемое имя — mcp__orders__lookup_order. Сервер из плагина ещё вкладывает имя плагина. Если таблица большая, официальные клиенты откладывают инструменты и раскрывают поиском. Не сыпать всю таблицу в контекст по умолчанию.
{
"name": "lookup_order",
"description": "Look up an order by ID. Confirm before any refund.",
"inputSchema": {
"type": "object",
"properties": {
"order_id": { "type": "string", "pattern": "^[A-Z]-\\d{4}$" }
},
"required": ["order_id"],
"additionalProperties": false
}
}
Третий объект: модель заполняет, хозяин tools/call
Модель видит имя, которое опубликовал хозяин. В сессии Claude Code вызов выглядит так:
{
"type": "tool_use",
"id": "call_3c91",
"name": "mcp__orders__lookup_order",
"input": { "order_id": "A-1042" }
}
Хозяин гоняет input через inputSchema и переводит в RPC серверу. Имя на проводе — зарегистрированное lookup_order, без префикса mcp__:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "lookup_order",
"arguments": { "order_id": "A-1042" }
}
}
При успехе вернуть content. При провале поставить isError и записать причину объектом. Не бросать одну фразу прозы. Модель читает запись назад, не сокет.
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{ "type": "text", "text": "{\"order_id\":\"A-1042\",\"status\":\"paid\"}" }
],
"isError": false
}
}
Четвёртый объект: права исполнения
Спека MCP говорит: вызов инструмента должен быть отклоняемым. Coding agent пишет отказ правилами, не prompt. Claude Code использует полное вызываемое имя:
{
"permissions": {
"allow": ["mcp__orders__lookup_order"],
"ask": ["mcp__orders__create_note"],
"deny": ["mcp__orders__refund_order"]
}
}
Официальный порядок всё ещё deny, ask, allow. Голый deny mcp__* вынимает MCP из контекста. Codex держит enabled_tools как белый список, disabled_tools как поздний чёрный и auto / prompt / approve по умолчанию, с перекрытием на инструмент. Cursor по умолчанию спрашивает; mcpAllowlist в permissions.json пишется как orders:lookup_order. Двери Shell / Git / файлы: Модель прав coding agent. MCP — четвёртая таблица, не замена тех трёх.
Пять шагов к исполняемому MCP
Не начинать с «пожалуйста, подключи MCP». Писать объекты:
- Сначала конфиг сервера. Выбрать stdio или http. type на каждый url. Секреты — в переменных среды, не в репозитории.
- Самим прогнать tools/list. Записать имена и required. Инструмент без Schema модели не отдавать.
- Затянуть inputSchema. pattern, enum,
additionalProperties: false. Поиск не должен обрастать ключом возврата. - Права писать на инструмент. Только чтение — allow. Запись — ask. Возврат — deny. Codex: сначала резать таблицу enabled_tools.
- Три JSON-следа одного успеха: tool_use, tools/call, result. Если сходятся — прыжок настоящий.
Как Schema становится дверью: Agents API + JSON Schema. Этот текст требует лишь, чтобы каждый шаг MCP на coding agent был объектом, который шлёт хозяин.
Разбирать сбой MCP — разложить три JSON-следа
Провал обычно — имя, Schema или права, не модель, которая «не умеет MCP».
- формат
inputSchemaрядом сarguments. Искать дыры и лишние ключи. - извлечь JSONPath вытащить
$.params.nameи$.input.order_id. - JSON Diff проход и отказ. Сначала правило и Schema, потом prompt.
- Сверить имя хозяина
mcp__orders__lookup_orderс именем RPClookup_order. У серверов плагина есть ещё сегмент плагина. - Не вставлять конфиг, токены и логи сессии в публичный форматтер. JSONSort работает в браузере локально.
Если три следа собираются по Schema, вы собрали MCP. Иначе собрали «я нажал подключить».
Частые ловушки
- Считать подключение вызовом. Подключение значит лишь: процесс или HTTP живы. Без list, Schema и прав модель всё ещё не зовёт.
- Считать MCP Function Calling. Для модели оба — заполнить JSON. Для хозяина MCP добавляет прыжок JSON-RPC. Текст протокола уже развёл слова. Здесь нужно только увидеть прыжок.
- url без type. Claude Code пропускает его как сломанный stdio. Удалённый сервер пропадает.
- Настроить сервер и не резать инструменты. Большая таблица входит в контекст. Официальная отсрочка и enabled_tools существуют из-за этого.
- Ставить «автоодобрить все MCP» по умолчанию. Полное одобрение Cursor, bypass Claude и auto везде у Codex — для изолированных сред. Будни пишут по инструменту.
- Считать проектный .mcp.json личным файлом. Он общий в системе версий. Коллеги увидят ожидание одобрения. Секреты остаются в пользовательском конфиге.
FAQ
Шлёт ли coding agent JSON-RPC сам?
Нет. Модель заполняет имя инструмента и arguments. Хозяин собирает id, method и params. Если в логе tools/call — это клиент, не модель.
Какая дверь первая: inputSchema или права?
Сначала форма, потом исполнение. Schema не прошла — RPC не слать. Прошла — ask или deny всё ещё могут сработать. Двери запирают разное.
stdio или http?
Локальные файлы или процесс: stdio. Размещённый сервис: http. Claude Code для удалённого предпочитает http; SSE устарел. WebSocket — если сервер сам толкает события.
Слишком много инструментов?
Claude Code может отложить инструменты MCP и раскрыть поиском. Codex режет таблицу enabled_tools. Не сыпать пятьдесят инструментов в одну сессию.
Может ли субагент пользоваться этими MCP?
Зависит от продукта. Права и allowed-tools Claude Code хотят полное вызываемое имя. Субагенты Agents API наследуют MCP, не ваши function. Не считать, что одна таблица копируется в каждую дочернюю сессию.
Вывод
Coding agent, который зовёт MCP, — не модель, бьющая в сервер. Хозяин перечисляет, модель заполняет JSON, хозяин затем tools/call. Schema и права — две двери.
Запишите, какое имя инструмента, какая Schema и какое правило возьмёт A-1042. Если можете указать на три объекта, MCP подключён. Модели сменятся. Эти три должны устояться раньше.
Дальше
- MCP Tool Schema vs Function Calling Сравнение протоколов, не вызов coding agent
- Зачем coding agent нужен контроль прав Три двери: Shell / Git / файлы
- Как AI coding agent зовёт инструменты JSON-ом JSON встроенных инструментов, ещё не MCP
- Agents API + JSON Schema на практике Стабильно, проверяемо, исполняемо
- Зачем ИИ нужен JSON Schema Schema / Function Calling / Structured Output
- Локальный ящик JSONSort Формат, проверка, Diff
- Все статьи Ещё заметки про JSON и ИИ
Журнал изменений: Первая публикация