[2026-09-26] eagle: personal/plans/balda-mm-phase4-agents.md personal/projects/personal-os/obsidian-mcp-setup.md personal/tech/balda-executor-mcp.md personal/tech/hermes-secret-redaction-bypass.md

This commit is contained in:
Alexey Martemyanov committed 2026-09-26 22:13:08 +06:00
1 parent ef0d21f271
commit c3ced58ee1
4 files changed
+254 -62

No files matched your search

+84 -40
View File
@@ -11,11 +11,11 @@
| # | Шаг | Статус |
|---|---|---|
| 1 | `~/agents` + `~/cli-auth` + контейнер | ✅ собрано, запущено |
| 2 | Мост FastAPI :8790 | ✅ работает под launchd |
| 3 | Сеть Kraken → Mac | ✅ **LAN напрямую**, туннель не нужен |
| 2 | Мост FastAPI :8790 | ✅ работает под launchd, туннель `agents-bridge.qentra.top` заведён Alex'ом |
| 3 | Сеть Kraken → Mac | ✅ **Cloudflare Tunnel** (постоянно); LAN остаётся для отладки |
| 4 | Секция «Agents» в Dashboard | ✅ активирована и проверена |
| 5 | Связка Балда → мост | 🟡 **связка работает**; конфиг Балды ждёт переключения на `type: http` — одним заходом с Obsidian |
| 6 | Obsidian MCP для Балды | 🟡 контейнер `obsidian-mcp` **поднят на Kraken**, в конфиг Балды ещё не прописан |
| 5 | Связка Балда → мост | ✅ конфиг переведён на `type: http`, образ 0.2.0, `tools/list` из docker-сети |
| 6 | Obsidian MCP для Балды | ✅ контейнер `obsidian-mcp` на Kraken + `type: sse` в конфиге Балды |
| 7 | Приёмка от аккаунта Alex | 🔴 блокер: авторизация CLI |
---
@@ -28,8 +28,10 @@
| 2 | Подтверждения | Full access → `permissions.mode: allow_all` |
| 3 | Управление линками в `~/agents` | Секция «Agents» в Eagle Dashboard |
| 4 | Auth CLI (claude/codex) | на хосте, `~/cli-auth`, **вне** `~/agents`; логинит **Alex вручную** |
| 5 | Сеть Kraken → Mac | ✅ **LAN напрямую** (`http://192.168.1.57:8790`); Cloudflare Tunnel — резерв |
| 5 | Сеть Kraken → Mac | 🟢 **Cloudflare Tunnel `agents-bridge.qentra.top`** — постоянный путь (Alex завёл маршрут); LAN `192.168.1.57:8790` — только для отладки |
| 6 | Провайдер исполнителя | `claude` (дефолт в `.env`); `codex` собирается в том же образе, переключается переменной |
| 7 | Тип MCP-транспорта в конфиге Балды | `http` (валидатор: `stdio \| http \| sse`); Obsidian — `sse` |
| 8 | Туннель для Obsidian MCP | ❌ **не нужен** — контейнер стоя́т на Kraken рядом с Балдой, ходят по docker-сети |
---
@@ -191,32 +193,38 @@ diff + тесты + коммит → Балда → Mattermost
---
## 7. Сеть Kraken → Mac — ✅ РЕШЕНО, туннель НЕ нужен
## 7. Сеть Kraken → Mac — 🟢 Cloudflare Tunnel (постоянно), LAN — отладка
### Итог: обычный HTTP по локальной сети
### Итог: постоянный путь — туннель, не IP
Kraken и Mac **стоят в одной LAN и видят друг друга напрямую** — проверено
`ping` с Kraken на `192.168.1.57` (RTT ~2.4 мс, 0% потерь). Никакой туннель,
никакой проброс и никакая Access Application не нужны.
🔴 **Alex потребовал убрать LAN-IP из постоянного конфига** — домашний IP не является
стабильным адресом: сменится адрес Mac или уедет роутер, и MCP отвалится молча.
Туннель даёт стабильное имя и не привязан к топологии сети.
```
BRIDGE_URL=http://192.168.1.57:8790
```env
BRIDGE_URL=https://agents-bridge.qentra.top
```
Проверки, подтвердившие связь:
Маршрут `agents-bridge.qentra.top` → `http://localhost:8790` заведён Alex'ом в
Cloudflare Zero Trust. Проверено из docker-сети Kraken:
| Проверка | Результат |
|---|---|
| `ping` Kraken → `192.168.1.57` | 2/2, RTT 2.4 мс ✅ |
| `curl` с Kraken на `:8790/healthz` | `status: ok` ✅ |
| `curl` из контейнера в `mattermost_mm-net` на `:8790/healthz` | `status: ok` ✅ |
| `curl https://agents-bridge.qentra.top/healthz` из `mattermost` | HTTP 200, `{"status":"ok","container":"balda-executor",…}` ✅ |
| заголовки ответа | `server: cloudflare`, `cf-ray: …-FRU`, `HTTP/2 200` ✅ |
| `ping` Kraken → `192.168.1.57` (LAN, резерв) | 2/2, RTT 2.4 мс ✅ |
⚠️ **На момент записи Access Application на `agents-bridge` не задан** — туннель
отвечает 200 без авторизации. Пока защита — `X-Bridge-Secret` и
непредсказуемое имя поддомена. **Завести Access Application** (или подтвердить, что
она есть), иначе мост фактически открыт в интернет.
### Что НЕ сработало и почему (чтобы не повторять)
| Путь | Почему отпал |
|---|---|
| Cloudflare Tunnel (`agents-bridge.qentra.top`) | Требует правки маршрута в CF-панели — ручная работа Alex, а LAN работала сразу. Остаётся резервным вариантом, если Mac уедет из этой сети |
| Обратный SSH-туннель (`ssh -R`) | 🔴 **На Kraken в sshd стоит `AllowTcpForwarding no`.** Симптом: `Error: remote port forwarding failed for listen port 18790`, в verbose — `debug1: Remote: Server has disabled port forwarding.` Не диагностировать как «порт занят»: порт свободен, форвард выключен администратором |
| LAN как постоянный адрес | Alex против: IP не стабилен. Годится только для отладки |
📌 Если понадобится туннель в будущем — сначала проверить `AllowTcpForwarding` на Kraken,
потом уже ставить форвард. Cloudflare Tunnel этот запрет обходит (исходящее соединение,
@@ -264,29 +272,35 @@ lsof -nP -iTCP:8790 -sTCP:LISTEN
## 9. Открыто
1. **Переключить конфиг Балды на HTTP-MCP** — сейчас там stdio-вариант с `docker run`,
который не может работать (нет `docker.sock` и нет shell в образе Балды).
Нужен `type: http` → `http://balda-executor-mcp:8890/mcp`. См. [[personal/tech/balda-executor-mcp]] §7.
2. **Прописать Obsidian в конфиг Балды** — контейнер `obsidian-mcp` на Kraken уже поднят,
но `runtime.mcp_servers.obsidian` ещё не добавлен. Делается тем же заходом, что п. 1:
1. ✅ **Конфиг Балды переведён на HTTP-MCP** — `type: http` →
`http://balda-executor-mcp:8890/mcp`. Плюс образ на Kraken обновлён до `0.2.0`
(в `0.1.0` нет `uvicorn` → рестарт-петля). См. [[personal/tech/balda-executor-mcp]] §10e-10f.
2. ✅ **Obsidian прописан в конфиг Балды** — контейнер `obsidian-mcp` на Kraken поднят,
`runtime.mcp_servers.obsidian` добавлен. ⚠️ Тип — **`sse`**, не `http`:
```yaml
runtime:
mcp_servers:
obsidian:
executor-mcp:
type: http
url: "http://balda-executor-mcp:8890/mcp"
obsidian:
type: sse
url: "http://obsidian-mcp:3101/sse"
balda:
mcp_servers:
- executor-mcp
- obsidian
```
См. [[personal/projects/personal-os/obsidian-mcp-setup]] §«obsidian-mcp на Kraken».
3. Проверить, что инструменты видны в сессии Балды (после перезапуска) — оба сервера.
4. Логин CLI (Alex вручную) — без него сквозная приёмка невозможна.
5. Cloudflare Tunnel — **не нужен** на текущей схеме; держать как резерв, если Mac
уедет из LAN. ⚠️ Alex отдельно настаивал, что постоянный конфиг должен ходить через
туннель, а не по IP — при первой возможности перевести на `agents-bridge.qentra.top`
(нужны 2 маршрута в CF Zero Trust + Access Application, заводит Alex).
См. §11 ниже.
3. 🟡 Проверить, что инструменты видны в сессии Балды — **постом от админа** в
Mattermost. ⚠️ Пост **от имени самого бота** Балда игнорирует (правильно);
для теста нужен пост от админского токена (`mattermost mmctl --local token generate admin …`).
4. 🔴 Логин CLI (Alex вручную) — без него сквозная приёмка невозможна.
5. 🔴 **Завести Access Application** на `agents-bridge.qentra.top` — сейчас туннель
отвечает 200 без авторизации (проверено). Защита — только `X-Bridge-Secret`.
6. ⚠️ **`~/Developer/balda-executor-mcp/docker-compose.yml` в репо → `0.2.0`**;
на Kraken compose лежит в `/home/kraken/balda-executor-mcp/docker-compose.yml`
(был `/home/kraken/mcp/` — путь изменился, старый compose мёртв).
## 9a. 🔴 Obsidian на Kraken — существовал ДО этой сессии
@@ -308,26 +322,56 @@ mcpvault /vault (PID 1168741, UID 10000)
📌 **Правило поиска: `docker ps` не является доказательством отсутствия сервиса.**
Сначала `ps aux | grep <name>`, потом порты (`ss -tlnp`), и только потом контейнеры.
## 10. Шаг 5 — связка Балда → мост (что сделано 2026-09-26)
## 10. Шаг 5 — связка Балда → мост (обновлено 2026-09-26)
| Компонент | Где | Статус |
|---|---|---|
| MCP-сервер `balda-executor-mcp` | `~/Developer/balda-executor-mcp/` | ✅ код + образ |
| Образ | `balda-executor-mcp:0.1.0`, загружен на Kraken | ✅ |
| Контейнер MCP | Kraken, `/home/kraken/mcp/docker-compose.yml` | ✅ Up |
| Конфиг Балды | `runtime.mcp_servers.executor-mcp` + `balda.mcp_servers` | 🟡 ждёт `type: http` |
| `.env` Балды | `+ BRIDGE_URL`, `+ BRIDGE_SECRET` | ✅ |
| MCP-сервер `balda-executor-mcp` | `~/Developer/balda-executor-mcp/` | ✅ код + образ `0.2.0` |
| Образ на Kraken | `balda-executor-mcp:0.2.0` (0.1.0 оставлен для отката) | ✅ загружен, хеш сверен |
| Контейнер MCP | Kraken, `/home/kraken/balda-executor-mcp/docker-compose.yml` | ✅ Up, `tools/list` = 3 инструмента |
| Конфиг Балды | `runtime.mcp_servers.{executor-mcp: http, obsidian: sse}` | ✅ залит |
| `.env` Балды | `BRIDGE_URL=https://agents-bridge.qentra.top` + `BRIDGE_SECRET` | ✅ туннель, не IP |
Бэкапы на Kraken: `config.yaml.bak-mcp-20260926-194313`, `.env.bak-mcp-*`, `.env.bak-url-*`.
Бэкапы на Kraken: `config.yaml.bak-mcp-20260926-194313`, `config.yaml.bak-obsidian-20260926-214849`,
`.env.bak-mcp-*`, `.env.bak-url-*`.
Проверено живьём: MCP-handshake (stdio и HTTP), `tools/list` с 3 инструментами,
`executor_health` из docker-сети Kraken вернул живые данные моста на Mac,
Балда после правки конфига стартовала без ошибок.
Проверено живьём: `/healthz` = `{"status":"ok",…}`, `tools/list` из docker-сети отдаёт
`executor_run` / `executor_status` / `executor_health`, туннель до моста отвечает 200 через Cloudflare.
📌 **Ключевой вывод по архитектуре:** MCP-сервер обязан быть **отдельным контейнером
с HTTP-транспортом**. Вариант «stdio + `docker run` изнутри Балды» нерабочий:
в образе Балды нет shell и не смонтирован `docker.sock`.
## 11. Obsidian MCP на Kraken — контейнер (сделан в этой сессии)
Балде нужен Obsidian **не по туннелю**: контейнер стоит рядом, в той же docker-сети.
Туннель к Obsidian Alex заводить не надо — это была моя ошибка в предложении.
| Что | Значение |
|---|---|
| Проект | `~/Developer/obsidian-mcp-kraken/` (Dockerfile) |
| Образ | `obsidian-mcp-image:0.1.0` (node + `mcp-proxy` + `mcpvault`) |
| Контейнер на Kraken | `obsidian-mcp`, сеть `mattermost_mm-net` |
| Внутренний порт | `3101` (`--port 3101 -- mcpvault /vault`), **наружу не публикуется** |
| Том | `/srv/dev-disk-by-uuid-49e8f586-…/obsidian:/vault:ro` (только чтение) |
| Endpoint для Балды | `http://obsidian-mcp:3101/sse`, `type: sse` |
⚠️ **Порт именно 3101, не 8080.** `mcp-proxy` слушает порт из `--port`; проба на 8080
даёт `Connection refused` при живом контейнере. Проверять так:
```bash
# из контейнера в mattermost_mm-net (там есть curl)
docker exec mattermost sh -c 'curl -sS -m 8 -H "Accept: text/event-stream" http://obsidian-mcp:3101/sse'
# ожидаем: event: endpoint / data: /messages?sessionId=…
```
📌 **`mcpvault` — только stdio.** HTTP-режима у него нет, поэтому и нужен обёртка
`mcp-proxy` (`ENTRYPOINT mcp-proxy`, `CMD --port 3101 -- mcpvault /vault`).
Проверено на живом контейнере: `mcp-proxy --port 3101 -- mcpvault /vault`.
📌 У `mcp-proxy` **нет флага `--host`** — в отличие от Python-моста. Передавать только
`--port` + `--`. Лишний `--host` роняет контейнер.
## Связанные заметки
- [[personal/projects/balda/balda-mm-delegation-plan]] — общий план (Фазы 4-5)
- [[personal/projects/balda/balda-kraken-mm-deploy]] — Фаза 3 (✅)