Skip to content
страница целиком, в Markdown — вставьте в чат с моделью

Реестр external_tools ​

Аудитория: фронтенд админки Aseller и администраторы платформы.

Всё, что раньше заливалось SQL-скриптом — sso-поля, mcp-канал, права на федеративные тулы — заводится этими ручками. SQL для заведения сервиса больше не нужен.

Все пути — от базового URL платформы, с префиксом /api/v1. Каждая ручка требует Authorization: Bearer <ACCESS админа>; не-админ получает 409 Only admin can call this method, а пользователь без права на URL — 403 ещё на уровне permissions.

Модель ​

Одна строка external_tools = один сервис экосистемы. Она обслуживает три роли сразу, и какие поля заполнены — те роли и включены:

Роль строкиВключающие поля
Плитка микрофронта в Host UIallowedRoles (непустой), mfName, mfRemoteEntry, mfExposedModule, permissionKey
SSO-клиентcode, ssoEnabled, ssoRedirectUris, serviceSecretHash
MCP-канал для федерацииcode, mcpEnabled, mcpUrl, mcpTimeoutMs

Чисто сервисная строка (SSO + MCP, без плитки) заводится с allowedRoles: [] — такая запись не показывается в /mf-registry и в интерфейсе не появляется.

Поля ​

ПолеТипНазначение
title *string ≤128Название. Обязательное
toolUrl *string ≤2048URL инструмента. Обязательное
allowedRoles *string[]Роли, которым показывать плитку. Для сервисной строки — []
codestring ≤64Slug сервиса: префикс имён федеративных тулов, идентификатор SSO-клиента. Уникален
isActivebooleanГлавный рубильник: строка участвует в реестре кредов и в федерации
ssoEnabledbooleanPOST /sso/grant выдаёт код только при true
ssoRedirectUrisstring[] | nullAllowlist адресов возврата. Сравнение префиксное, каждый элемент обязан начинаться с http:// или https://. null очищает
serviceSecretHashstring | nullsha256 сервисного секрета, 64 hex-символа. null очищает
mcpUrlstring | nullEndpoint MCP-канала сервиса. null очищает
mcpEnabledbooleanВключает сервис в сборку федеративного снапшота
mcpTimeoutMsinteger 1000…120000Таймаут федеративного вызова. Эффективный = min(это, MCP_FEDERATION_CALL_TIMEOUT_MS)
permissionKeystring ≤128Ключ пермишена плитки. Пермишен создаётся автоматически при заведении строки. Уникален
mfName, mfRemoteEntry, mfExposedModulestringModule Federation: контейнер, remoteEntry.js, exposed-модуль
backendBaseUrl, swaggerUrl, standaloneUrl, guideUrlstring ≤2048Служебные ссылки сервиса
imagesstring[]Иллюстрации карточки
commentstring ≤2048Комментарий администратора

* — обязательные при создании.

Секрет платформе не передаётся

В serviceSecretHash кладётся хеш: printf %s "$SECRET" | sha256sum. Сам секрет считает и хранит команда сервиса. В GET возвращается тот же хеш — по нему админ сверяет, тот ли секрет прописан на стороне сервиса, но восстановить секрет из него нельзя.

Ручки реестра ​

Создать сервис ​

http
POST /api/v1/admins/tools
Content-Type: application/json

{
  "title": "Калькулятор юнит-экономики",
  "toolUrl": "https://calc.aseller.cat",
  "allowedRoles": [],
  "code": "idea_calc",
  "isActive": true,
  "ssoEnabled": true,
  "ssoRedirectUris": ["https://calc.aseller.cat/sso/callback"],
  "serviceSecretHash": "3b1f…64 hex",
  "mcpEnabled": true,
  "mcpUrl": "https://calc.aseller.cat/mcp",
  "mcpTimeoutMs": 30000
}

201 → {"_id": "d559628a-…"}. Дубль code или permissionKey → 409 Tool with the same code already exists.

Если передан permissionKey, под него автоматически создаётся пермишен (для плитки микрофронта) — отдельно заводить не нужно.

Изменить ​

http
PATCH /api/v1/admins/tools/:guid
{ "mcpUrl": "https://calc.aseller.cat/mcp/v2", "mcpTimeoutMs": 45000 }

204. Любое подмножество полей — обязательных при правке нет. null в ssoRedirectUris, serviceSecretHash, mcpUrl очищает поле.

Прочитать ​

http
GET /api/v1/admins/tools?limit=15&offset=0&sortField=title&sortType=ASC&filters=[title][$contains]=калькул
GET /api/v1/admins/tools/:guid

Список — {"count": 42, "rows": [ … ]}, одна строка — объект целиком, вместе с toolPlaces, sso- и mcp-полями. Фильтры — стандартный синтаксис платформы ($eq, $contains, $null, $any, or[0][…]).

Удалить ​

http
DELETE /api/v1/admins/tools/:guid

204. Связанный пермишен плитки не удаляется — переводится в status = 100.

Места отображения ​

Только для плиток микрофронтов; на SSO и MCP не влияют.

http
POST   /api/v1/admins/tools/places      { toolId, showPlace, windowHeight, windowWidth, multipleProductData, … }
PATCH  /api/v1/admins/tools/places/:guid
DELETE /api/v1/admins/tools/places/:guid

Права на тулы ​

Федеративный тул виден пользователю, если у того есть пермишен с allowed_url вида {"url":"ext/<code>/<tool>","httpMethod":"POST"}. Набирать эти строки руками не нужно — есть две ручки.

Каталог тулов сервиса ​

http
GET /api/v1/admins/tools/:guid/mcp-tools

Платформа опрашивает MCP-канал сервиса живьём (initialize + tools/list) и возвращает его тулы:

json
{
  "serviceCode": "idea_calc",
  "mcpUrl": "https://calc.aseller.cat/mcp",
  "count": 2,
  "tools": [
    {
      "name": "idea_calc_calc_profit_forecast",
      "remoteName": "calc_profit_forecast",
      "description": "Прогноз прибыли",
      "permissionUrl": "ext/idea_calc/calc_profit_forecast",
      "httpMethod": "POST"
    },
    {
      "name": "idea_calc_calc_unit_economics",
      "remoteName": "calc_unit_economics",
      "description": "Юнит-экономика",
      "permissionUrl": "ext/idea_calc/calc_unit_economics",
      "httpMethod": "POST"
    }
  ]
}

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

Ошибки: 400 — у строки нет code или mcpUrl; 404 — строки нет; 502 — канал не ответил, в тексте причина (MCP channel of "idea_calc" is unavailable: …).

Собрать пермишен ​

http
POST /api/v1/admins/tools/:guid/mcp-permission
Content-Type: application/json

{}

Пустое тело — весь каталог сервиса одним пермишеном с ключом EXT_<CODE>_TOOLS:

json
{
  "guid": "dbe463a2-…",
  "key": "EXT_IDEA_CALC_TOOLS",
  "created": true,
  "tools": ["calc_profit_forecast", "calc_unit_economics"],
  "allowedUrls": [
    "{\"url\":\"ext/idea_calc/calc_profit_forecast\",\"httpMethod\":\"POST\"}",
    "{\"url\":\"ext/idea_calc/calc_unit_economics\",\"httpMethod\":\"POST\"}"
  ]
}

Полное тело:

ПолеТипПо умолчанию
keystring ≤128EXT_<CODE>_TOOLS
titlestring ≤255Тулы сервиса <название>
descriptionstring ≤255Федеративные MCP-тулы сервиса <code>
role0, 10, 20, 30, 35, 40, 45, 6010 (клиент)
hierarchyinteger 0…2000
status0 | 1000 (100 — публичный, выдаётся всем)
toolsstring[] из remoteNameпусто = весь каталог
modereplace | appendreplace

replace заменяет список url у пермишена целиком, append дописывает недостающие, не трогая остальные. Повторный вызов с тем же key обновляет существующий пермишен — в ответе "created": false, дубликаты не плодятся.

Ошибки: 400 Unknown tools for "<code>": … — в tools имя, которого сервис не отдаёт (в тексте перечислены все неизвестные); 400 Service "<code>" exposes no tools — каталог пуст; 502 — канал недоступен.

Дальше — обычная выдача прав ​

Получившийся пермишен назначается пользователю или группе штатно, как любой другой. Полному админу (роль 0 без мастера) федеративные тулы доступны без пермишенов.

Если пермишен нужно собрать вручную (например, смешать тулы двух сервисов в один ключ) — это обычный POST /api/v1/permissions со своим allowedUrls:

json
{
  "key": "EXT_MIXED_TOOLS",
  "title": "Расчёты и хаб",
  "description": "Тулы калькулятора и platform_hub",
  "role": 10,
  "allowedUrls": [
    {"url": "ext/idea_calc/calc_unit_economics", "httpMethod": "POST"},
    {"url": "ext/platform_hub/read_ds_execute", "httpMethod": "POST"}
  ]
}

Что стоит сделать в интерфейсе ​

Минимум, который закрывает ручную работу администратора:

  1. Карточка сервиса — форма по таблице полей выше. Отдельной вкладкой sso-блок (ssoEnabled, список ssoRedirectUris с добавлением строк, поле хеша с подсказкой про sha256sum) и mcp-блок (mcpEnabled, mcpUrl, mcpTimeoutMs).
  2. Кнопка «Загрузить тулы» на карточке — зовёт GET …/mcp-tools, показывает список с описаниями. Ошибку 502 показывать текстом как есть: там реальная причина, с которой идут к команде сервиса.
  3. Выбор галочками поверх этого списка + кнопка «Выдать» → POST …/mcp-permission с tools. Кнопка «Выдать все» — тот же запрос с пустым телом.
  4. В экране пермишена — вместо ручного ввода строк ext/… показывать те же чекбоксы, сгруппированные по сервисам.

Пока интерфейса нет, администратор закрывает задачу двумя запросами: создать строку и выдать весь список одним пермишеном.

Когда правка вступает в силу ​

Что менялиЧерез сколько действует
Секрет, ssoRedirectUris, isActive, ssoEnabledСразу: кэш реестра сервисных кредов сбрасывается на POST/PATCH/DELETE этих ручек (иначе жил бы 60 секунд)
Пермишены на тулыПри следующем запросе пользователя
Появление тулов в общем MCPДо MCP_FEDERATION_REFRESH_SEC (по умолчанию 300 с) или сразу после рестарта платформы. Каталог в админке при этом уже актуален

Документация по инфраструктуре