Срезы каталога
Как отдавать ассистенту только нужную часть инструментов и не тратить контекст на остальное.
Полный каталог — 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=structurehttps://ваш-сервер/mcp?tools=layers_task_list_smart,layers_task_updateЗаголовок сильнее адреса: он задан под конкретный запуск, а адрес живёт в настройках долго и переживает то, ради чего его когда-то выбрали.
Обнаружению OAuth строка запроса не мешает: метаданные ресурса называют
канонический /mcp без неё, а запросы клиент шлёт по своему адресу — со срезом.
Зачем это нужно, кроме экономии токенов
Заголовок раздела «Зачем это нужно, кроме экономии токенов»Некоторые клиенты подгружают схемы по мере надобности. Ошибка «схема ещё не загружена» может относиться к клиентскому каталогу, но одного сообщения недостаточно, чтобы установить причину или утверждать, что сервер не получил запрос. Срез уменьшает каталог, но не гарантирует отсутствие таких ошибок. Записи с неизвестным исходом не повторяют без проверки результата.
Отдельно стоит readonly: это срез не по разделу, а по действию — только
читающие инструменты из всех разделов сразу. Он для подключений, у которых
токен и так без права записи: раньше такой клиент получал весь каталог и
половину не мог вызвать физически, то есть платил за инструменты, каждая
попытка вызвать которые заканчивалась отказом.
Что сильнее чего
Заголовок раздела «Что сильнее чего»Побеждает первое заданное, сверху вниз:
X-Mcp-Tools, иначе параметрtools— поимённый список;X-Mcp-Profile, иначе параметрprofile— срез или список семейств;- каталог процесса, созданный по
mcp.tools.families, иначеmcp.tools.profile; - если при запуске ничего не задано — весь каталог.
Заголовок не дополняет свойство, а заменяет его целиком — иначе объяснить заранее, что придёт в ответе, было бы нельзя.
Заголовок только сужает
Заголовок раздела «Заголовок только сужает»Инструмент, которого при запуске не создали, заголовком не вернуть: фильтр при старте убирает его из приложения, и возвращать нечего. Запрос несуществующего инструмента или раздела — ошибка с именем в тексте, а не молча укороченный каталог.
Инструмент вне среза нельзя и вызвать: иначе список обещал бы одно, а сервер позволял другое.
Чего пока нет
Заголовок раздела «Чего пока нет»Переключения среза посреди разговора. Протокол работает без сессии, и канала,
по которому сервер сообщил бы клиенту «каталог изменился», в нём нет: при
рукопожатии сервер честно отвечает tools.listChanged: false. Значит клиент
перечитает каталог только при новом подключении, и смена среза на лету пока
ничего не сэкономила бы — старый список остался бы у него в контексте.