Как сократить расход токенов на MCP: мы урезали определения инструментов на 60%
Каждый инструмент MCP, который может вызвать твой агент, это блок JSON, который модель может читать при каждом запросе. Наши весили около 95 000 токенов. Как измерить свои за две минуты, что мы урезали, не убрав ни одного инструмента, и проверка бюджета, которая не даёт им снова разрастись.
27 октября платящий пользователь отменил подписку на AgentsRoom и назвал причиной токены. Прежде чем спорить с этим, мы измерили, что наше приложение добавляет к каждому агенту, которого оно запускает.
Самое большое число оказалось не там, где мы ждали. Наши стартовые инструкции были небольшими. А инструменты MCP, которые мы даём каждому агенту (бэклог, память проекта, почта между агентами, терминалы, SSH, базы данных и всё остальное), это 191 инструмент и около 380 КБ JSON. При примерно 4 байтах на токен это около 95 000 токенов определений инструментов. Неделей раньше было 78 000. Никто этого не решал: каждый новый инструмент просто добавлял свой абзац.
Мы делаем AgentsRoom, десктопное приложение, которое запускает Claude Code, Codex и другие CLI для программирования бок о бок и даёт им эти инструменты. Вот что мы измерили, что урезали, не убрав ни одного инструмента, и проверка, которая не даёт этому вернуться. Всё это можно применить к твоим собственным серверам MCP.
Короткий ответ
- Определение инструмента это JSON, который модель может читать при каждом запросе: имя, описание, схема входных данных. Считай около 4 байт на токен.
- Платишь ли ты за него на каждом ходу, зависит от CLI. Claude Code по умолчанию откладывает загрузку инструментов MCP и подгружает определение, когда оно нужно. Некоторые CLI отправляют все схемы с каждым запросом.
- Сначала измерь, потом режь.
/contextв Claude Code или скрипт из 40 строк, который запрашивает у любого сервера список инструментов. - Сокращай текст, сохраняй инструменты. Описание говорит, что и когда. Инструкция по применению переезжает в документ, который агент читает по запросу. Наши определения уменьшились примерно с 95 000 до примерно 38 000 токенов, в 2,5 раза.
- Поставь потолок в сборку. Без него определения разрастаются снова сами собой.
Сколько стоит определение инструмента и кто за него платит
Когда клиент MCP подключается к серверу, он запрашивает список инструментов. Каждая запись это имя, описание, написанное для модели, и JSON-схема параметров. Клиент превращает этот список в определения инструментов, которые отправляются модели: так модель узнаёт, что инструмент существует и как его вызвать.
Значит, каждое слово описания это вход, который читает модель. Как часто она его читает, зависит от клиента:
- Claude Code по умолчанию откладывает загрузку инструментов MCP. Его документация, прочитанная 3 ноября 2026 года с установленным Claude Code 2.1.314, говорит, что в начале сессии загружаются только имена инструментов и инструкции серверов, а определение подгружается через поиск инструментов, когда Claude нужен этот инструмент. С
ENABLE_TOOL_SEARCH=false, сautoниже порога в 10% контекстного окна, на моделях старше Claude Opus 4 и Sonnet 4 или для сервера с пометкойalwaysLoadопределения загружаются сразу при старте. - Другие CLI ведут себя иначе. В нашем собственном тесте 28 октября агента просили ответить «OK»: Claude Code стартовал с 67 500 токенами при отложенных наших инструментах, Codex CLI 0.164 стартовал с 25 000 токенами и не отправлял наши схемы одним блоком, а OpenCode при подключении загружал наши 175 инструментов плюс 19 инструментов браузера и отправлял их с каждым запросом. Один и тот же сервер, совсем разные счета.
Кэширование промпта смягчает стоимость, когда список инструментов не меняется: после первого запроса стабильный префикс читается из кэша за долю цены входа. Места оно не возвращает. Определения всё равно занимают контекстное окно при каждом запросе, рядом с твоим кодом и твоим разговором. А у отложенного режима есть своя цена: шаг поиска перед первым использованием каждого инструмента.
Измерь свои за две минуты
В Claude Code запусти /context. Команда раскладывает окно по источникам и помечает инструменты MCP, загрузка которых отложена или выполняется по запросу. Запусти её в новой сессии в своём проекте, прежде чем что-либо вводить, и увидишь, сколько стоит твоя конфигурация ещё до начала работы.
Для любого сервера и любого CLI спроси сервер напрямую. Сервер MCP через stdio говорит на JSON-RPC, одно сообщение на строку: ты отправляешь initialize, затем tools/list и измеряешь то, что вернулось. Этот скрипт делает ровно это, на Node и без единой зависимости:
// Usage: node mcp-tool-cost.mjs <command that starts the server> [args...]
import { spawn } from 'node:child_process';
const [cmd, ...args] = process.argv.slice(2);
const server = spawn(cmd, args, { stdio: ['pipe', 'pipe', 'ignore'], shell: process.platform === 'win32' });
const tools = [];
let buffer = '';
const send = (msg) => server.stdin.write(JSON.stringify({ jsonrpc: '2.0', ...msg }) + '\n');
const listTools = (cursor) => send({ id: 2, method: 'tools/list', params: cursor ? { cursor } : {} });
server.stdout.on('data', (chunk) => {
buffer += chunk;
let end;
while ((end = buffer.indexOf('\n')) >= 0) {
const line = buffer.slice(0, end).trim();
buffer = buffer.slice(end + 1);
if (line) handle(JSON.parse(line));
}
});
function handle(msg) {
if (msg.id === 1) {
send({ method: 'notifications/initialized' });
listTools();
} else if (msg.id === 2) {
tools.push(...msg.result.tools);
if (msg.result.nextCursor) listTools(msg.result.nextCursor);
else { report(); server.kill(); }
}
}
function report() {
const rows = tools
.map((tool) => ({ name: tool.name, bytes: Buffer.byteLength(JSON.stringify(tool)) }))
.sort((a, b) => b.bytes - a.bytes);
const total = rows.reduce((sum, row) => sum + row.bytes, 0);
for (const row of rows.slice(0, 10)) {
console.log(`${String(row.bytes).padStart(7)} bytes ~${Math.round(row.bytes / 4)} tokens ${row.name}`);
}
console.log(`${rows.length} tools, ${total} bytes, about ${Math.round(total / 4)} tokens`);
}
send({
id: 1,
method: 'initialize',
params: { protocolVersion: '2025-06-18', capabilities: {}, clientInfo: { name: 'tool-cost', version: '1.0.0' } },
});
Запусти его с той же командой, которой твой CLI запускает сервер, например node mcp-tool-cost.mjs npx -y @playwright/mcp@latest. Он выводит десять самых тяжёлых инструментов и итог. Вот что мы получили 3 ноября 2026 года:
| Сервер | Инструменты | JSON | Примерно |
|---|---|---|---|
@modelcontextprotocol/server-filesystem 2.1.0 | 14 | 12 554 байт | 3 100 токенов |
@playwright/mcp 0.0.84 | 25 | 21 034 байт | 5 300 токенов |
| Инструменты AgentsRoom, 28 октября до сокращения | 191 | около 380 000 байт | 95 000 токенов |
| Инструменты AgentsRoom, 28 октября после сокращения | 191 | около 152 000 байт | 38 000 токенов |
| Инструменты AgentsRoom, 3 ноября | 203 | 159 957 байт | 40 000 токенов |
Четыре байта на токен это оценка: её достаточно, чтобы сравнивать серверы и видеть тенденцию, но не чтобы предсказать счёт. Настоящие токенизаторы зависят от модели и текста, как мы убедились, когда посчитали 3,8 миллиарда собственных токенов.
Файловые серверы выше вполне разумны. Проблема в сумме: пять серверов такого размера это уже 20 000 токенов, ещё до сервера вроде нашего.
Что мы урезали и чего не трогали
Правило, которое мы себе поставили: ни одного удалённого инструмента, ни одного удалённого параметра, ни одного удалённого допустимого значения или обязательного поля. Агенты должны были сохранить все возможности. Меняться мог только текст.
- Описание инструмента говорит, что и когда, в одном-трёх предложениях. Не как. Именно в «как» и сидели байты: правила, значения по умолчанию, крайние случаи, примеры, предупреждения, написанные после того, как агент однажды неправильно использовал инструмент.
- Параметру достаточно одного предложения или ничего, когда его имя, тип и список допустимых значений уже всё говорят. Параметры, которые повторяются от инструмента к инструменту (
project,author, идентификаторы тикетов), получили везде одну и ту же стандартную фразу. - Инструкция по применению переехала, а не была удалена. У каждого семейства инструментов есть файл инструкций, который агент читает перед первым вызовом этого семейства. Для нашего самого большого инструмента, того, что сохраняет команду агентов, полный справочник полей теперь возвращается вызовом инструмента, когда агент его запрашивает, вместо того чтобы ехать внутри схемы.
- Второй проход проверил каждый факт. Каждое предложение, убранное из описания, искали в файлах инструкций и, если его там не было, возвращали туда.
Некоторые результаты, в байтах JSON на инструмент:
| Инструмент | До | После |
|---|---|---|
teams_save | 19 705 | 9 791 |
triggers_save | 16 014 | 4 071 |
backlog_update | 13 150 | 4 253 |
backlog_create | 11 565 | 4 399 |
Итого 380 КБ превратились в 152 КБ. Тринадцать инструментов были больше 4 КБ; четыре всё ещё больше, из-за количества полей, которые они несут. Идея всего прохода: чтобы выбрать инструмент, модели нужно знать, что он существует и когда его вызывать. Детали могут подождать до момента, когда она его использует.
Если ты пишешь сервер MCP, Claude Code даёт ещё одну причину. Он обрезает описание инструмента, загруженное сразу при старте, на 4 096 символах, а когда сопоставляет поисковый запрос с описанием, читает только часть в пределах этого лимита. Всё важное после этой границы может так и остаться непрочитанным.
Тот же приём для стартового файла
Схемы инструментов не единственная постоянная стоимость. Наши агенты также читают файл инструкций по инструментам, прежде чем ими пользоваться, и он разросся до 57,7 КБ, около 14 000 токенов, которые читались целиком при каждом запуске и каждом возобновлении. Пользователь сообщил, что возобновлённый агент Codex упирался в свой лимит рабочего контекста за несколько минут.
Исправление следовало той же идее. Файл стал индексом примерно на 11 КБ: правила, которые действуют для всех инструментов, и по одной строке на семейство инструментов со ссылкой на его собственный файл. 31 файл семейств читается только перед первым вызовом соответствующего семейства. Их текст не изменился, слово в слово. Агент, который работает только с бэклогом, никогда не читает раздел о базах данных.
Это работает и для любого длинного CLAUDE.md или AGENTS.md: держи в постоянно загружаемом файле то, что нужно каждой задаче, а на остальное ставь ссылку. Подробнее мы писали об этом в нашем руководстве по AGENTS.md и файлам контекста.
Бюджет, который проваливает push
Больше всего нас беспокоило не число 95 000. А 78 000 неделей раньше. Каждый инструмент добавлял абзац, каждый абзац был разумным, а сумма выросла на 20% за семь дней.
Поэтому размер стал проверкой в сборке. Бюджет хранится в одном JSON-файле:
{
"totalBytes": 160000,
"perToolBytes": 4000,
"oversized": {
"teams_save": 9791,
"triggers_save": 4071,
"backlog_update": 4253,
"backlog_create": 4399
}
}
Скрипт запускает наши серверы MCP в песочнице, запрашивает у каждого его инструменты, измеряет JSON.stringify(tool) в байтах и завершается с ошибкой, когда итог превышает totalBytes или когда инструмент превышает perToolBytes. Четыре инструмента, которые уже были слишком большими, перечислены со своим размером: это храповик. Они могут уменьшаться, но не расти, а когда один из них уменьшается, скрипт просит понизить число. Он запускается перед каждым push и в релизной сборке. Поднять потолок можно, но это решение, записанное в файле, а не способ заставить проверку пройти.
3 ноября, шесть дней спустя, та же проверка показывает 203 инструмента и 159 957 байт: двенадцать инструментов добавлено, 43 байта ниже потолка. Следующему инструменту придётся самому освободить себе место. Именно для этого проверка и нужна.
Отключи то, чем не пользуешься
Самый дешёвый токен тот, что принадлежит инструменту, которого твой агент никогда не видит.
- Ограничь серверы проектами, которым они нужны. Сервер, объявленный на уровне пользователя, следует за тобой в каждый репозиторий. В Claude Code
.mcp.jsonпроекта держит его там, где он полезен. - Оставь
alwaysLoadдля горстки инструментов. Документация Claude Code говорит прямо: каждый инструмент, загруженный сразу при старте, занимает контекст, который иначе был бы доступен для твоего разговора. - Следи за тем, что добавляют результаты инструментов, а не только определения. Инструмент, который возвращает целую страницу или таблицу, может стоить за один вызов больше, чем его определение за весь день.
В AgentsRoom раздел Настройки > Инструменты AgentsRoom показывает каждое семейство наших инструментов с его весом, и ты можешь отключить семейство или отдельный инструмент для всех проектов, одного проекта, папки или одного агента. Отключённый инструмент вообще не показывается агенту, поэтому не стоит никакого контекста. Страница AgentsRoom MCP описывает инструменты, а трассировка сессии показывает, чем был заполнен контекст агента, включая инструменты MCP, по убыванию размера.
Что мы не меняли
Из того же замера вышли ещё две статьи расходов, и мы оставили их как есть, намеренно.
- Стартовый бриф, который сообщает каждому агенту его роль и то, как отчитываться о своём статусе: медиана около 5 000 токенов для Claude, примерно 2,5% окна в 200 000 токенов, и со второго запроса он читается из кэша.
- Файл статуса, который каждый агент пишет в конце хода: по замеру на 71 локальном транскрипте Claude, около 2,5% токенов контекста.
Сокращение любого из них сэкономило бы меньше 3% окна и поставило бы под угрозу качество работы агентов. Определения инструментов весили 95 000 токенов. Туда и ушло время.
Вопросы, которые нам действительно задают
Сколько токенов тратят инструменты MCP?
Каждый инструмент стоит целого своего определения: имя, описание и схема входных данных, отправленные в виде JSON. Грубое правило: 4 байта на токен. Замер от 3 ноября 2026 года: официальный сервер filesystem отдаёт 14 инструментов примерно на 3 100 токенов, Playwright MCP 25 инструментов примерно на 5 300. Инструменты AgentsRoom весили около 95 000 токенов до того, как мы их сократили, сегодня около 40 000.
Загружает ли Claude Code все инструменты MCP в контекстное окно?
Не по умолчанию. Поиск инструментов Claude Code (tool search) откладывает загрузку определений инструментов MCP: в начале сессии загружаются только имена инструментов и инструкции серверов, а определение Claude подгружает, когда ему нужен этот инструмент. ENABLE_TOOL_SEARCH=false, модель старше Claude Opus 4 и Sonnet 4 или сервер с пометкой alwaysLoad возвращают определения в контекст сразу при старте.
Сокращают ли серверы MCP расход токенов?
Могут, когда инструмент возвращает короткий ответ вместо того, что агент иначе прочитал бы целиком, например запрос к базе данных вместо полного дампа. Но определения стоят контекста, и результаты тоже: Claude Code предупреждает, когда один результат MCP превышает 10 000 токенов, и по умолчанию обрезает его на 25 000. Сервер MCP экономит токены, только если его результаты меньше того, что он заменяет.
Как посмотреть, сколько контекста занимают мои инструменты MCP?
В Claude Code запусти /context: команда раскладывает контекст по источникам и помечает отложенные инструменты MCP. Для любого сервера и любого CLI запроси у сервера список инструментов и измерь JSON, именно это делает скрипт из 40 строк в этой статье.
Каким должно быть хорошее описание инструмента MCP?
Одно-три предложения о том, что делает инструмент и когда его вызывать, со словами, которые агент стал бы искать, ближе к началу. Параметру достаточно одного предложения или ничего, если его имя, тип и допустимые значения уже всё говорят. Правила, крайние случаи и длинные примеры уходят в документ, который агент читает по запросу. К тому же Claude Code обрезает описание, загруженное сразу при старте, на 4 096 символах.
Как не дать определениям инструментов снова разрастись?
Дай им бюджет, который проверяет сборка. У нас есть JSON-файл с общим потолком и потолком на один инструмент и скрипт, который запускает наши серверы MCP, измеряет каждый инструмент и завершается с ошибкой при превышении любого из пределов, и мы запускаем его перед каждым push. Инструменты, которые уже были слишком большими, могут уменьшаться, но не расти.
Коротко
Твои инструменты MCP это текст, который читает модель, и никто не проверяет этот текст так, как проверяют код. Измерь его один раз: /context в Claude Code или скрипт выше для любого сервера. Затем сделай так, чтобы каждое описание говорило, что и когда, перенеси «как» в файл, который агент читает, когда ему нужно, и поставь число в свою сборку, чтобы всё это не расползлось обратно.
Мы перешли примерно с 95 000 на примерно 38 000 токенов, не убрав ни одного инструмента. Если ты запускаешь несколько агентов с одними и теми же инструментами, AgentsRoom можно скачать бесплатно, а страница серверов MCP показывает, как объявить сервер один раз для всех CLI и проектов.
Скачать AgentsRoom
Запускай всех своих ИИ-агентов во всех проектах из одного окна.
Приложение-компаньон: следите за агентами на ходу
Используйте Claude, Codex, Antigravity CLI или другого поставщика AI.
Отправляйте баги и запросы прямо в ваш публичный бэклог.
Читать далее
Как увидеть, что ваш ИИ-агент для кода выполняет на ваших серверах
Ваш агент работает на продакшен-сервере, а терминал сообщает лишь, что он вызывает инструмент. Какую команду он запустил и что ответила машина? Транскрипт расскажет об этом задним числом. Вот как мы сделали это видимым прямо во время работы, что попробовали сначала и как получить то же самое без нашего приложения.
Читать статьюКак дать кодинг-агенту секрет, не вставляя его в промпт
Агенту нужен ключ Stripe или пароль от базы, чтобы запустить свою команду. Вставьте его в чат, и он окажется в транскрипте на вашем диске, у провайдера модели, а иногда и в коммите. Правило, к которому мы пришли после трёх собственных ошибок: секрет попадает к агенту через переменную окружения и никак иначе.
Читать статьюОдин аккаунт Claude на двух компьютерах или на двоих: что работает
В один аккаунт Claude можно войти на всех твоих устройствах, и все они расходуют одни и те же лимиты на 5 часов и на неделю, Claude и Claude Code вместе. Пользоваться одним аккаунтом вдвоём запрещают условия Anthropic, а семейного тарифа нет. Что мы проверили 25 октября 2026 года и как увидеть, какой компьютер сколько потратил.
Читать статью