Перейти к содержимому
MCP-сервер

Срезы каталога

Как отдавать ассистенту только нужную часть инструментов и не тратить контекст на остальное.

Полный каталог — 73 инструмента. Его стоимость по выбранной методике приведена ниже; клиент может загружать описания сразу или по мере надобности. Срез сокращает набор для текущей работы, но не ограничивает права доступа к данным.

Срез оставляет в каталоге одно семейство и всё, без чего оно не работает.

Срез Инструментов Токенов Экономия
весь каталог 73 26 293 —
core (ядро) 16 6 690 75 %
projects (проекты) 25 9 391 64 %
folders (папки) 29 10 472 60 %
sprints (спринты) 30 11 555 56 %
structure (структура) 34 12 636 52 %
forms (формы) 27 11 780 55 %
tasks (задачи) 34 13 796 48 %
pages (страницы) 38 13 531 49 %
disk (диск) 20 8 126 69 %
readonly 34 10 445 60 %

Числа сняты с живого сервера запросом tools/list, а не посчитаны по коду, и пересчитываются одной командой — python3 scripts/slices.py. Способ счёта держится один и тот же намеренно: пересчитать таблицу иначе значит молча подменить смысл её чисел. Считается сумма по каждому описанию инструмента вместе со схемой аргументов, кодировкой cl100k_base. Служебная обёртка ответа в счёт не входит — поэтому цифра меньше той, что покажет счётчик всего тела ответа целиком.

Инструмент layers_toolsets тоже называет цену наборов, но считает иначе — по длине описаний, без токенизатора, с подобранным коэффициентом. Расхождение с таблицей до девяти процентов, и в его ответе цена честно названа приблизительной. Точные числа здесь.

Свойство при запуске:

Окно терминала
java -jar layers-mcp-server.jar --mcp.tools.profile=forms

Готовые срезы:

Срез Что входит
full всё; значение по умолчанию, если ничего не задано
core только общее: кто вы, какие пространства и проекты, люди, поиск, переход по ссылке
forms формы
pages страницы, папки
tasks задачи, комментарии, пакетные операции над ними, списки задач
projects проекты
sprints списки задач и проекты, в которых они живут
folders папки и проекты — папка внутри проекта устроена как вложенный проект
structure перекладывание структуры: проекты, списки задач, папки. Задачи не входят: перекладывают контейнеры, а не содержимое
disk чтение диска и его структуры
readonly только читающие инструменты из всех разделов; задаётся заголовком

Ядро — user, workspace, search — остаётся в любом срезе. Без него ассистент не сможет ни понять, в каком пространстве работает, ни найти сущность по имени.

Состав срезов не произволен, и правило одно: в срез входит семейство и только то, без чего оно физически не работает. Не «то, что рядом по смыслу» — иначе срезы расползутся обратно в полный каталог.

tasks включает списки задач потому, что задача обязана лежать в списке: бэкенд не примет её без него. А проекты и теги — не включает: список проектов с именами отдаёт инструмент из ядра, а имена тегов инструменты задач разрешают сами. А projects не включает ничего: проект заводится сам, и спринт по умолчанию создаётся при этом внутри бэкенда, а не чужим инструментом; участников отдаёт инструмент из того же семейства. У pages в составе папки, но не теги — инструменты страниц про теги ничего не знают, теги живут у задач.

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

После смены набора переподключитесь или обновите каталог в клиенте: автоматического подключения недостающих инструментов сервер не обещает.

Что бывает дальше, ассистент узнаёт у самого сервера — инструмент layers_toolsets входит в ядро и отвечает тремя вещами: какой набор действует прямо сейчас (читается из заголовка живого запроса, а не предполагается), список наборов с описанием на языке дел, и цена каждого в инструментах и токенах.

Описания в нём намеренно обещают только то, что человек может сделать руками в интерфейсе. У форм, например, сказано про сборку, правку полей и статистику ответов — но не про публикацию, хотя инструмент публикации существует.

Переключает набор человек, в настройках подключения. Ассистент может понять, чего ему не хватает, и назвать это — подключить себе сам он не может, и layers_toolsets говорит об этом прямо, а не делает вид, что умеет.

Когда готовый срез не подходит, семейства перечисляются вручную:

Окно терминала
java -jar layers-mcp-server.jar --mcp.tools.families=pages,tags

Список семейств сильнее имени среза: если заданы оба, действует список.

Семейства: forms, pages, tasks, projects, sprints, folders, tags, membership, bulk.

Тот же список принимает и заголовок X-Mcp-Profile — см. ниже.

Неизвестное имя среза — отказ на старте, а не молчаливый откат к полному каталогу:

Неизвестный срез тулов «form». Есть: full, forms, pages, tasks, projects.
Либо перечисли семейства в mcp.tools.families.

Так сделано намеренно. Сервер, поднявшийся с полным каталогом вместо запрошенного среза, выглядит работающим — и разница обнаруживается только счётом токенов.

Каждый класс инструментов помечен семейством:

@ToolFamily("forms")
public class FormTools { … }

Аннотация несёт условие регистрации бина. Семейство не входит в срез — бин не создаётся, а tools/list собирается из бинов. Значит каталог физически не может разойтись с тем, что работает: инструмента нет ни в списке, ни в вызове.

Фильтровать выдачу отдельно не нужно, и это важнее, чем кажется. Фильтр на выдаче рано или поздно расходится с фильтром на вызове, и появляется инструмент, которого в каталоге нет, но вызвать его можно — или наоборот.

Срез удобен для текущей работы, но человек может переключаться между темами. Посреди работы со страницами регулярно случается другое: «нашёл ошибку — заведи задачу». Чистый срез в этот момент ответил бы отказом, и прерываться на смену подключения пришлось бы ровно тогда, когда это хуже всего.

Поэтому в обычных тематических срезах, кроме собственных инструментов, есть короткий список того, что делают мимоходом из любого места:

  • завести задачу и убедиться, что завелась;
  • завести страницу и открыть её;
  • оставить комментарий — замечание часто оставляют им;
  • найти по названию, понять, где вы сейчас, пройти по дереву;
  • назвать проект один раз на разговор.

readonly исключает записи, а явно заданный поимённый список не дополняется этим набором.

Это имена инструментов, а не семейства. В семействе задач их два десятка; втянув его целиком в каждый срез, мы вернулись бы к полному каталогу, ради ухода от которого всё и затевалось. Мимоходом нужно завести — вести задачу дальше человек будет в своей фазе.

Срез можно назвать словом занятия: ?profile=pages, ?profile=forms, ?profile=projects, ?profile=tasks. Русские имена тоже приняты (страницы, формы, проекты, задачи), но в адресе надёжнее английские: клиент, подставляющий адрес без преобразования, получит от сервера «Bad Request» на русское слово, и выглядеть это будет как поломка подключения.

Свойство при запуске годится, когда у поверхности свой процесс. Общий адрес, куда приходят разные люди, так не разделить: всем достанется один срез. Для этого есть заголовки — они выбирают срез на конкретный запрос.

Окно терминала
curl -H 'X-Mcp-Profile: forms' ...
curl -H 'X-Mcp-Profile: forms,tags' ...
curl -H 'X-Mcp-Tools: tool_name,tool_name' ...

X-Mcp-Profile принимает имя готового среза или перечисление семейств через запятую. X-Mcp-Tools перечисляет инструменты поимённо, через запятую — самый узкий вариант; имена берутся из ответа tools/list.

Срез адресом, когда заголовок задать негде

Заголовок раздела «Срез адресом, когда заголовок задать негде»

Заголовок доступен там, где конфигурацию клиента правят руками. Но подключение, описанное одним адресом, — обычный случай, и заголовку там взяться неоткуда. Поэтому то же самое задаётся строкой запроса:

https://ваш-сервер/mcp?profile=structure
https://ваш-сервер/mcp?tools=layers_task_list_smart,layers_task_update

Заголовок сильнее адреса: он задан под конкретный запуск, а адрес живёт в настройках долго и переживает то, ради чего его когда-то выбрали.

Обнаружению OAuth строка запроса не мешает: метаданные ресурса называют канонический /mcp без неё, а запросы клиент шлёт по своему адресу — со срезом.

Некоторые клиенты подгружают схемы по мере надобности. Ошибка «схема ещё не загружена» может относиться к клиентскому каталогу, но одного сообщения недостаточно, чтобы установить причину или утверждать, что сервер не получил запрос. Срез уменьшает каталог, но не гарантирует отсутствие таких ошибок. Записи с неизвестным исходом не повторяют без проверки результата.

Отдельно стоит readonly: это срез не по разделу, а по действию — только читающие инструменты из всех разделов сразу. Он для подключений, у которых токен и так без права записи: раньше такой клиент получал весь каталог и половину не мог вызвать физически, то есть платил за инструменты, каждая попытка вызвать которые заканчивалась отказом.

Побеждает первое заданное, сверху вниз:

  1. X-Mcp-Tools, иначе параметр tools — поимённый список;
  2. X-Mcp-Profile, иначе параметр profile — срез или список семейств;
  3. каталог процесса, созданный по mcp.tools.families, иначе mcp.tools.profile;
  4. если при запуске ничего не задано — весь каталог.

Заголовок не дополняет свойство, а заменяет его целиком — иначе объяснить заранее, что придёт в ответе, было бы нельзя.

Инструмент, которого при запуске не создали, заголовком не вернуть: фильтр при старте убирает его из приложения, и возвращать нечего. Запрос несуществующего инструмента или раздела — ошибка с именем в тексте, а не молча укороченный каталог.

Инструмент вне среза нельзя и вызвать: иначе список обещал бы одно, а сервер позволял другое.

Переключения среза посреди разговора. Протокол работает без сессии, и канала, по которому сервер сообщил бы клиенту «каталог изменился», в нём нет: при рукопожатии сервер честно отвечает tools.listChanged: false. Значит клиент перечитает каталог только при новом подключении, и смена среза на лету пока ничего не сэкономила бы — старый список остался бы у него в контексте.