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

MCP-федерация ​

Аудитория: команды, чей сервис умеет (или хочет уметь) отдавать тулы по MCP и попасть в общий MCP-канал Aseller — тот, что подключают в Claude.

Идея ​

У платформы один MCP-эндпоинт для пользователя. Тулы в нём двух сортов: собственные (сгенерированы из роутов api-new) и федеративные — проксируемые в MCP-каналы сервисов экосистемы.

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

Ваша сторона — обычный stateless MCP-сервер по HTTP (JSON-RPC 2.0). Никаких SDK платформы, никаких вебхуков.

Что платформа спрашивает у сервиса ​

Сборка списка ​

Раз в MCP_FEDERATION_REFRESH_SEC (по умолчанию 300 секунд) и один раз при старте платформа делает на ваш mcpUrl два запроса подряд:

json
// 1) POST <mcpUrl>
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{
  "protocolVersion":"2025-03-26",
  "capabilities":{},
  "clientInfo":{"name":"aseller-mcp-gateway","version":"1.0.0"}}}

// 2) POST <mcpUrl>
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
  • Оба запроса идут без Authorization: список тулов не считается пользовательскими данными, авторизуется сам вызов.
  • Если на initialize вы вернули заголовок Mcp-Session-Id, платформа пришлёт его обратно в tools/list. Требовать сессию не обязательно — stateless-сервер тоже подходит.
  • Ждём ответ формы {"result":{"tools":[{"name":…,"description":…,"inputSchema":…,"annotations":…}]}}.

Вызов тула ​

http
POST <mcpUrl>
Authorization: Bearer <synth ACCESS пользователя, 60 секунд>
X-Trace-Request-Id: mcp:<kind>:<id>:<timestamp>
Content-Type: application/json

{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"calc_unit_economics","arguments":{…}}}

Bearer здесь — настоящий пользовательский ACCESS-токен платформы (синтетический: выпущен на этот вызов, живёт 60 секунд, под него создана эфемерная сессия, которая гасится сразу после ответа). Проверяйте его ровно так же, как любой другой — через POST /auth/validate; см. Подключение сервиса. В payload есть email — по нему линкуется ваш аккаунт.

Ответ ждём в виде MCP-результата:

json
{"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"…"}],"isError":false}}

Если result не содержит массива content, платформа завернёт его целиком в один текстовый блок — работать будет, но читаемость в клиенте пострадает.

Имена тулов ​

Имя в общем списке — <code сервиса>_<имя тула у вас>:

У васВ федерации
calc_unit_economicsidea_calc_calc_unit_economics
keepa_lookupidea_calc_keepa_lookup

Ограничения на итоговое имя: не длиннее 64 символов и только [a-zA-Z0-9_-]. Тул с именем, которое после префикса не проходит проверку, молча пропускается — в логах платформы остаётся mcp federation: tool name invalid/too long, skipped. Учитывайте длину своего code: чем он короче, тем больше места остаётся именам.

Если два сервиса отдали одинаковое итоговое имя, побеждает тот, кого обошли раньше.

Права: кто видит ваш тул ​

Каждый федеративный тул получает виртуальный URL ext/<code>/<имя тула> с методом POST. Видимость и право вызова решаются обычным механизмом permissions платформы: у пользователя должен быть пермишен, в allowed_urls которого лежит

json
{"url":"ext/idea_calc/calc_unit_economics","httpMethod":"POST"}

Полный админ платформы (роль 0 без мастера) видит и зовёт все федеративные тулы без пермишенов. Остальным права выдаёт администратор — руками их набирать не нужно, есть ручка, которая собирает пермишен из вашего же tools/list: Реестр external_tools.

Тул, на который у пользователя нет права, не просто не вызывается — он не показывается в tools/list этого пользователя.

Гарды шлюза ​

Платформа защищает себя от медленного или разговорчивого сервиса. Значения по умолчанию:

ЧтоСборка спискаВызов тула
Таймаут10 сmin(mcpTimeoutMs из реестра, MCP_FEDERATION_CALL_TIMEOUT_MS) = 30 с
Максимум запроса16 КБMCP_FEDERATION_MAX_REQUEST_BYTES = 256 КБ
Максимум ответа2 МБMCP_FEDERATION_MAX_RESPONSE_BYTES = 5 МБ
Одновременных вызовов—MCP_FEDERATION_MAX_CONCURRENT = 16, очередь MCP_FEDERATION_MAX_QUEUE = 200

Превышение не роняет ни платформу, ни соседние сервисы — вызов возвращается пользователю как ошибка тула:

codeЗначение
request_failedНе достучались: DNS, отказ соединения, таймаут, обрыв
request_too_largeАргументы вызова больше лимита запроса
response_too_largeВаш ответ больше лимита ответа — платформа обрывает чтение
invalid_jsonОтвет не разобрался как JSON
http_errorHTTP-статус ≥ 400 без тела JSON-RPC
overloadedОчередь шлюза переполнена, повторите позже

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

Дуал-стек

Платформа подключается и по IPv6, и по IPv4. Если ваш mcpUrl резолвится в оба, а слушаете вы только на одном — причина отказа доедет в текст ошибки целиком, не подменяясь последней попыткой. Проверяйте, что сервис слушает тот адрес, который отдаёт DNS.

Требования к вашему MCP-серверу ​

  1. HTTP POST, JSON-RPC 2.0. Один эндпоинт, принимающий initialize, tools/list, tools/call.
  2. Stateless или с сессией по заголовку. Платформа не хранит состояние между циклами обновления.
  3. Токен проверяется через /auth/validate. Не пытайтесь разобрать подпись сами — ключ симметричный и наружу не выдаётся.
  4. Короткие ответы. Держитесь в пределах лимитов, большие выгрузки отдавайте ссылкой, а не телом.
  5. Идемпотентность там, где возможно. Таймаут на стороне шлюза не означает, что ваш обработчик не доработал.
  6. Имена тулов стабильны. Переименование = потеря выданных прав: пермишены привязаны к ext/<code>/<имя>.

Порядок включения ​

  1. Админ заводит строку реестра с code, mcpUrl, mcpEnabled: true, isActive: true.
  2. Админ открывает каталог ваших тулов — GET /admins/tools/:guid/mcp-tools опрашивает ваш канал живьём, так что проверить связность можно сразу, не дожидаясь пересборки снапшота.
  3. Админ собирает пермишен на нужные тулы и выдаёт его пользователям или группе.
  4. В общий MCP тулы попадают в течение MCP_FEDERATION_REFRESH_SEC (по умолчанию 5 минут) либо сразу после рестарта платформы.

Диагностика ​

СимптомГде смотреть
Тулов нет ни у кого, включая админаСтрока реестра: isActive, mcpEnabled, mcpUrl. Затем GET /admins/tools/:guid/mcp-tools — он покажет реальную причину (502 с текстом ошибки)
Каталог в админке есть, в MCP тулов нетЕщё не пересобрался снапшот — подождите цикл обновления
Админ видит, пользователь нетНет пермишена с ext/<code>/<tool>
Часть тулов пропалаДлина имени после префикса или недопустимые символы
Вызовы падают с request_failedТаймаут или сеть; сверьте mcpTimeoutMs в реестре с реальным временем работы тула

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