Когда вы ставите в VS Code популярные агентные расширения (Cline, Roo Code, Kilo), быстро выясняется одна мерзкая вещь. Обычно начинаешь подключать к ним новые инструменты быстрее , чем LLM под их капотом способна их адекватно переварить.

Сначала все выглядит безобидно. Вы подключаете к редактору пару MCP-серверов: один для файлов, другой для поиска. Агент радуется, вы радуетесь, всё работает. Но потом начинается: "О, прикручу-ка я еще сервер для базы данных... и GitHub... и внутреннюю Jira... и вон тот OpenAPI-каталог".

В какой-то момент вы открываете свой mcp.json и видите там 25 серверов. А агент начинает творить дичь.

На практике этот "зоопарк" приводит к вполне конкретным болям:

  • Инструменты начинают конфликтовать именами (у вас три разных search).

  • Описания функций (description blobs) становятся настолько длинными, что занимают больше места, чем сам код, который вы просите написать.

  • Модель выжигает контекстное окно (и ваши деньги) просто на то, чтобы вспомнить, какие ручки у нее вообще есть.

  • Агент путается в монструозных JSON-схемах и начинает галлюцинировать аргументами.

В итоге вы платите космические счета за токены не за "интеллект" GPT или Claude, а за то, что каждый раз показываете им мусорную свалку из сырых API.

Я устал платить за этот мусор и написал toolc - прокси-шлюз на Go, который встает между агентом и зоопарком серверов, жестко фильтруя и сжимая всё, что видит модель.

Что я сделал

Было: десятки сырых MCP-серверов и OpenAPI-спецификаций, которые напрямую "орут" в контекст модели.

Стало: один компактный слой, который сам решает, что показать модели сразу, что раскрыть только по запросу, а что вообще спрятать от греха подальше (например, ручку DROP TABLE).

Я не стал писать "убийцу MCP" или очередной тяжелый фреймворк. toolc - это совместимый runtime-фасад. Для вашего VS Code он выглядит как обычный, но единственный MCP-сервер. Для поддерживаемых локальных MCP stdio серверов и скомпилированных OpenAPI-поверхностей он прячет зоопарк за одним MCP-сервером.

Как это выглядит на практике (Сценарий: VS Code + MCP)

Представьте, что у вас есть стандартный, раздутый конфиг от Cline или Roo Code. Вы просто скармливаете его моей утилите:

./toolc optimize-mcp \
  -input .vscode/mcp.json \
  -emit vscode \
  -out-dir dist/mcp-optimized

Вопрос, где взять бинарник ?

У вас два пути. Либо забрать готовый бинарник из раздела Releases на GitHub (есть под Windows, Linux, Mac), либо собрать из исходников, если на машине стоит Go: go install github.com/aak204/Tool-Catalog-Compiler/cmd/toolc@v1.0.0

Далее утилита читает ваш конфиг, пингует все сервера, собирает их инструменты, выкидывает дубликаты, сжимает маркетинговую воду из описаний и генерирует один новый конфиг.

Вы скармливаете этот новый конфиг редактору, и запускаете шлюз:

./toolc mcp-serve -catalog dist/mcp-optimized/toolc.compiled.json

Всё. Агент больше не видит хаоса. Он видит один сервер toolc, который выдает ему аккуратное меню.

Под капотом: три режима жадности

Я перевожу все спецификации (OpenAPI, функции, MCP) в единое внутреннее представление (IR). А дальше компилятор применяет магию, которую я разделил на три режима:

  • direct (сырой режим): показываем всё как есть. Нужен только для дебага и бенчмарков, чтобы поплакать над тем, как всё было плохо.

  • flat (мой фаворит): основной рабочий режим. Модель получает "плоский", сжатый и дедуплицированный список. Минимум токенов, максимум пользы, ноль лишних запросов.

  • staged (параноидальный режим): сначала отдаем модели только короткие названия инструментов (discovery). Если агент решает что-то вызвать, он делает отдельный запрос за точной схемой аргументов. Добавляет задержку сети, но спасает, когда схемы очень сложные или рискованные.

Спойлер: flat оказался лучшим дефолтным режимом по соотношению стоимости и полезности, но не универсальным победителем в каждом сценарии.

Кстати, парсить гигантские спецификации оказалось тем еще квестом. Когда я попытался скормить компилятору официальную OpenAPI‑спеку Stripe (а это монстр на мегабайты YAML/JSON с кучей рекурсивных ссылок), мой парсер просто сожрал десятки гигабайт памяти и упал с Out of Memory (OOM). Пришлось писать жесткие depth guards (ограничители глубины), лимитировать экспансию нод и переиспользовать ссылки (shallow ref-shell reuse), чтобы компилятор не пытался развернуть бесконечную рекурсию. Теперь Stripe переваривается за миллисекунды и жрет всего ~48 МБ памяти.

Меньше слов, больше метрик (или почему я сэкономил 60% денег)

Я инженер, поэтому прогнал всё это через жесткие бенчмарки на реальных спецификациях (включая GitHub API на 1100 эндпоинтов и монструозный Stripe API). Использовал OpenRouter и четыре топовые модели (Qwen-3.6-plus, GLM-5.1, GPT-5.4, Claude Sonnet 4.6).

Самый приятный график - это стоимость на миллион вызовов.

Вот сухие цифры по экономии:

Модель

Цена без шлюза (direct)

Цена с toolc (flat)

Сэкономили

qwen/qwen3.6-plus

$1807.26

$1199.13

33.65%

z-ai/glm-5.1

$3102.53

$1593.14

48.65%

openai/gpt-5.4

$8819.46

$4291.96

51.34%

anthropic/claude-sonnet-4.6

$10736.57

$4290.21

60.04%

Я не сделал модели умнее. Я просто перестал заваливать их мусором в системном промпте. За счет режима flat объем контекста (token proxy) падает драматически, а Success Rate у сильных моделей часто остается высоким, но не является универсальными 100% на всех сценариях.

Галлюцинации и боль (Случай с GLM)

Я не буду врать, что "всё всегда работает идеально". У меня был интересный кейс с z-ai/glm-5.1.

На ранних прогонах эта модель вела себя как студент после бессонной ночи: обрывала ответы, уходила в "размышления" и забывала вернуть JSON, ломала контракты.

Я начал копать. Выяснилось, что:

  1. Я сам косячил, скармливая ей один и тот же системный промпт для разных шагов оркестрации. Claude это прощал, а GLM сыпалась.

  2. Ей тупо не хватало лимита токенов на завершение (completion budget).

Я вынес это в отдельный изолированный эксперимент (dist/glm-controlled). Развел контракты промптов, поднял лимиты. В итоге Success Rate в режиме flat вырос с 0.78 до 0.92.

Вывод: компиляция каталогов спасает от шума, но если модель "капризная", ей все равно нужны индивидуальные профили (request shaping). Магии не бывает.

Что дальше? (И чего я НЕ обещаю)

Я не строю "Control Plane для всего AI". Это был бы буллшит.

Сегодня toolc отлично справляется с:

  • Локальными MCP-серверами через stdio.

  • Скомпилированными OpenAPI-поверхностями.

  • Защитой контекста редакторных агентов.

Чего я НЕ обещаю прямо сейчас:

  • Магической поддержки удаленных MCP-транспортов (пока только локалка).

  • Полноформатного рантайма для обычных функций (generic functions).

  • Production-ready шлюза для OpenAI-compatible форматов (это в планах).

Итог

Если ваш агент в VS Code захлебывается от количества подключенных серверов, а счета за API вызывают нервный тик - попробуйте поставить между ними мой шлюз. Вам не придется переписывать код или сносить инфраструктуру. Вы просто уменьшите уровень шума.

Исходники, графики и инструкция по установке - всё лежит на GitHub. Я выложил v1.0.0, который закрывает главную боль с локальными MCP и OpenAPI. Но архитектура позволяет сделать из этого ультимативный Control Plane для любых агентов. Если вы пишете на Go, страдаете от зоопарка тулзов и у вас есть идеи - залетайте в репозиторий. Буду рад любым PR, баг-репортам и просто критике кода. Давайте сделаем этот инструмент еще мощнее вместе!

Репозиторий toolc на GitHub

Комментарии (12)


  1. jetnet
    13.04.2026 14:41

    А почему надо было самому велик изобретать? Этот (https://gitlab.com/gitlab-org/ai/lazy-mcp), например, не подошел?


    1. aak204 Автор
      13.04.2026 14:41

      Спасибо за ссылку! Да, lazy-mcp я смотрел. Проект классный и бьет ровно в ту же боль: не вываливать на агента весь зоопарк инструментов разом и беречь стартовый контекст.

      Но у меня задача стояла шире. Я хотел не просто прикрутить ленивую загрузку к MCP-серверам, а решить проблему комплексно:

      • Переваривать не только MCP, но и огромные OpenAPI-спеки.

      • Свести всё это в единый слой с жестким контролем (рулить политиками доступа и отрезать опасные ручки еще до того, как их увидит модель).

      • Сделать основным режимом быстрый плоский список (flat), а ленивую подгрузку схем (staged) оставить как запасной вариант для самых тяжелых случаев.

      Так что lazy-mcp - отличный сфокусированный инструмент. Просто под мой замес из OpenAPI, десятков серверов и желания жестко контролировать то, что в итоге долетает до VS Code, готового решения я для себя не нашел.


  1. Prikalel
    13.04.2026 14:41

    Были бы ещё круче если бы прокси мог детектить результаты команд mcp серверов и перед возвращением значения выполнять преобразование из JSON в toon - так ещё лучше было бы


    1. headliner1985
      13.04.2026 14:41

      Надо поверх писать агентный MCP/tool который обрабатывает запрос, дёргает MCP несколько раз и отдает финальный ответ


      1. aak204 Автор
        13.04.2026 14:41

        Спасибо за идеи! Обе фичи - крутые. В текущем релизе v1.0 их пока нет, но с удовольствием забираю обе в бэклог для следующих версий.

        @Prikalel (про конвертацию вывода): абсолютно согласен. Сейчас toolc жестко сжимает схемы на входе, но результаты выполнения от серверов возвращает агенту «как есть». Если перехватывать жирные JSON-ответы и на лету конвертить их во что-то компактное перед отдачей в LLM - это сэкономит еще гору токенов на возврате. Забираю в бэклог.

        @headliner1985 (про агентную оркестрацию): тоже крутая идея. Сейчас у меня честный stateless-прокси, чтобы не усложнять ядро на старте. А то, что вы описываете - это макро-инструменты: когда модель дергает одну ручку, а шлюз под капотом сам прогоняет нужный цикл вызовов и отдает готовую выжимку, экономя дорогие сетевые раундтрипы к Claude/GPT.

        Короче, идеи отличные. Забрал их себе, хочется сделать реально интересный инструмент