Русский
MCP Federation
MCP Federation соединяет вашу базу знаний trip2g с другими MCP-совместимыми базами. AI-агент обращается к одному эндпоинту (вашему хабу) и ищет по всем подключённым базам: публичным справочникам, базам партнёров и внешним адаптерам (GitHub, Telegram).
flowchart LR
Agent["AI-агент\n.mcp.json: только хаб"]
Hub["Ваш trip2g хаб\n/_system/mcp\n(ваши заметки + KB-заметки)"]
Pub["Публичная база\nбез аутентификации"]
Peer["Приватный пир\nHMAC-секрет"]
Ext["Внешний адаптер\nHMAC-секрет"]
Agent -->|"search / federated_search"| Hub
Hub -->|"веерный federated_search"| Pub
Hub -->|"веер + исходящий секрет → JWT"| Peer
Hub -->|"веер + исходящий секрет → JWT"| Ext
Peer -->|"входящий секрет фильтрует результаты"| Hub
Ext -->|"входящий секрет фильтрует результаты"| Hub
Топология федерации: агент видит один MCP-эндпоинт; хаб рассылает запрос по всем подключённым пирам и объединяет результаты.
Как это работает
┌─────────────────────────┐
│ Ваш AI-агент │
│ .mcp.json: ваш хаб │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ Ваш trip2g хаб │
│ /_system/mcp │
│ • ваши заметки │
│ • KB-заметки на пиров │
│ и адаптеры │
└─┬──────────┬───────────┬┘
│ │ │
▼ ▼ ▼
Публичная Партнёр Внешний
база (HMAC) адаптер
(без auth) (HMAC)
Хаб не хранит удалённый контент: только ваши заметки, KB-заметки для роутинга и federation secrets в базе данных.
Основные понятия
KB-заметка: обычная заметка Obsidian с полем mcp_federation_kb_url в frontmatter. Это поле регистрирует пира. Тело заметки содержит произвольный текст с описанием, когда использовать эту базу; агент читает его во время поиска.
Federation secret: общий HMAC-ключ для аутентификации вашего хаба у приватного пира (и наоборот). Для публичных баз секрет не нужен.
kb_id: короткий slug для идентификации пира. По умолчанию совпадает с hostname URL; переопределяется полем mcp_federation_kb_id.
Добавить публичного пира
Создайте заметку в хранилище с таким frontmatter:
---
mcp_federation_kb_url: https://philosophers.example.com/_system/mcp
mcp_federation_kb_id: philosophy
---
Использовать для: поиска философских отсылок к инженерным решениям.
Не использовать для: срочных задач и узкоспециализированных тем.
Нажмите Sync. Готово. Агент обращается к этой базе через federated_search с kb_id="philosophy" или автоматически при веерном поиске по всем базам.
Поле mcp_federation_kb_id необязательно. Если его нет, kb_id будет равен hostname URL (philosophers.example.com).
Добавить приватного пира (двусторонний обмен)
Приватные пиры аутентифицируются через общий HMAC-секрет. Это однократный обмен ключами.
Шаг 1: Боб генерирует секрет для вас.
Боб открывает Администрирование → Federation → «Добавить входящий секрет». Задаёт короткий идентификатор (alice-2026), при необходимости выбирает, какие подграфы вы можете видеть, и нажимает «Сгенерировать». Секрет в формате hex показывается один раз. Боб отправляет вам kid и secretHex по доверенному каналу (например, личным сообщением в Telegram).
Шаг 2: Вставьте данные как исходящий секрет.
В вашем Администрирование → Federation → «Добавить исходящий секрет» укажите:
kid: идентификатор от Боба (например,alice-2026)secretHex: hex-строка от Бобаkb_url: MCP-эндпоинт Боба (https://bob.team.io/_system/mcp)
Шаг 3: Создайте KB-заметку.
---
mcp_federation_kb_url: https://bob.team.io/_system/mcp
mcp_federation_kb_id: bob
---
Использовать для: статусов задач Боба, общих заметок по дизайну.
Шаг 4: Настройте обратное направление (опционально).
Если Боб тоже хочет запрашивать вашу базу, повторите процесс в обратную сторону: вы генерируете входящий секрет, отправляете Бобу kid и secretHex, Боб вставляет их как исходящий секрет со ссылкой на ваш /_system/mcp.
Каждое направление независимо. Можно дать Бобу доступ к подграфу team-status, не открывая остальное.
Инструменты федерации
Хаб всегда предоставляет шесть MCP-методов, независимо от количества подключённых пиров:
| Метод | Описание |
|---|---|
search(query) |
Локальный поиск по вашим заметкам |
similar(note_id) |
Похожие заметки локально |
note_html(note_id) |
Содержимое локальной заметки |
expand(pid, toc_path?) |
Обход оглавления локальной заметки по уровням, см. ru/user/expand |
federated_search(query, kb_id?) |
Поиск по пирам (веерный или точечный) |
federated_similar(note_id, kb_id) |
Похожие заметки у конкретного пира |
federated_note_html(note_id, kb_id) |
Содержимое заметки у конкретного пира |
federated_expand(kb_id, pid, toc_path?) |
Обход оглавления удалённой заметки у конкретного пира, тот же интерфейс, что expand, применённый к удалённой базе |
federated_search без kb_id веерно обращается ко всем доступным пирам параллельно и объединяет результаты. С kb_id="bob" обращается только к базе Боба. С kb_ids=["bob","philosophy"] обращается ровно к этим двум.
Когда локальный search находит KB-заметку, он возвращает её с маркером kind: "federation_kb" и инструкцией агенту вызвать federated_search с соответствующим kb_id. Агент собирает контекст по мере запросов, без выгрузки всего заранее.
Права доступа
Федерация использует существующую систему подграфов trip2g.
Исходящий доступ (что видят пиры у вас). Когда хаб Боба обращается к вашему с валидным JWT, ваш экземпляр проверяет, какие подграфы привязаны к его kid, и фильтрует результаты. Заметки вне этого scope невидимы для Боба, так же как для любого другого читателя без доступа.
Входящий доступ (что видите вы у пиров). KB-заметки являются обычными заметками, им можно назначить подграф. Если позднее вы откроете хаб коллегам, они увидят только те KB-заметки, подграф которых им доступен локально.
Уровни видимости KB-заметок. KB-заметка подчиняется тем же правилам видимости, что и обычная заметка:
| Frontmatter KB-заметки | Анонимный MCP-агент | Аутентифицированный подписчик | Администратор |
|---|---|---|---|
free: true |
✓ маршрутизация работает | ✓ маршрутизация работает | ✓ |
| (нет флагов) | ✗ "not configured" | ✓ маршрутизация работает | ✓ |
subgraphs: team |
✗ "not configured" | только при подписке на team |
✓ |
KB-заметка без free: и без subgraphs: не является «только для администратора»: её видит любой аутентифицированный подписчик. Чтобы KB-заметка была доступна только администраторам, поместите её в подграф, к которому у обычных пользователей нет доступа (например, subgraphs: admin-only). Ответ federated_search на недоступный kb_id всегда «not configured», неотличим от несуществующего kb_id, поэтому существование пира не раскрывается.
Граф федерации (панель self-hosted)
Если trip2g запущен за simplepanel, в разделе Администрирование → Federation есть страница с графом, отображающим текущее состояние всех инстансов пула в виде направленного графа. Каждый узел соответствует инстансу, каждое ребро соответствует обнаруженной federation-связи.
Цвет ребра отражает статус соединения:
| Статус | Значение |
|---|---|
ok |
KB-заметка, исходящий секрет и совпадающий неотозванный входящий секрет с хотя бы одним подграфом. Связь работает. |
no_auth |
KB-заметка есть, исходящего секрета нет. Агент попытается позвонить пиру, пир ответит 401. Добавьте исходящий секрет. |
orphan_secret |
Исходящий секрет записан, но KB-заметка не указывает на пира. Агент никогда не обнаружит этот маршрут. Добавьте KB-заметку. |
one_way |
Исходящий секрет и KB-заметка есть, но у пира нет входящего секрета для этого kid. Пир ответит 401. Попросите пира добавить входящий секрет для вашего kid. |
no_access |
Связь установлена, но входящий секрет не даёт доступа ни к одному подграфу, пир получает пустые результаты. Расширьте scope. |
revoked |
Исходящий секрет отозван. Маршрут нерабочий, запись следует удалить. |
external |
URL назначения не является инстансом пула (публичная или внешняя база). Только информативно. |
На странице также выводится список Issues: ошибки конфигурации, обнаруженные при сканировании, с уровнем важности (error / warning / info) и описанием по каждому ребру. Это позволяет диагностировать проблемы, не читая логи.
Отозвать доступ
Администрирование → Federation → найдите строку → «Отозвать». Строка становится серой. Все последующие запросы с этим kid получают ответ 401. Координация с пиром не нужна: его вызовы просто начнут завершаться ошибкой.
Чтобы сузить scope без полного отзыва, удалите отдельные подграфы из kid в панели «Управление scope».
Ограничения
- Аутентификация: только HMAC-SHA256. mTLS и OAuth не поддерживаются в текущей версии.
- Таймаут веерного поиска: 2 секунды на каждый вызов пира. Медленные или недоступные пиры пропускаются; результаты от остальных возвращаются.
- Глубина рекурсии: по умолчанию 3 уровня (настраивается через
MCP_FEDERATION_MAX_DEPTHна self-hosted). Защищает от петель, когда пиры сами имеют пиров. - TLS: хаб не форсирует HTTPS. Используйте HTTPS-URL пиров в продакшене.
Диагностика
federation_not_configured в ответе агента. В хранилище нет KB-заметок или поле mcp_federation_kb_url отсутствует либо написано с ошибкой.
Ошибки 401 в логах хаба. Исходящий секрет не совпадает с тем, что ожидает пир, или пир отозвал ваш kid. Повторите обмен секретами с партнёром.
Пир не возвращает результатов, ошибки нет. Scope вашего kid у пира пуст. Бобу нужно добавить хотя бы один подграф к вашему kid в его Администрирование → Federation → «Управление scope».
Веерный поиск всегда занимает 2 секунды. Один или несколько пиров недоступны. Проверьте логи хаба с префиксом mcp:federation: там будут предупреждения с указанием конкретного пира и временем ожидания.
Дополнительно
- Хаб: базы знаний, подключённые к этому хабу
- MCP-сервер: как работает локальный MCP-сервер
- Self-hosted: переменная
MCP_FEDERATION_MAX_DEPTHи другие настройки - Расширенные настройки: подграфы и управление доступом