Files
obsidian-vault/personal/projects/personal-os/obsidian-mcp-setup.md
T

217 lines
11 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
> [!IMPORTANT] Актуальная конфигурация для Balda (2026-10-09)
> Текущая Balda использует Codex ACP и Streamable HTTP: `type: http`, URL `http://host.docker.internal:3101/mcp`.
> Указания ниже про Balda + SSE или `/sse` относятся к прежним клиентам/развёртываниям. Канонический runbook: [[personal/projects/balda/setup]].
# Obsidian MCP — текущая архитектура
## Факт: что стоит сейчас
**Hermes native MCP client** (встроен в Hermes Agent, не wrapper).
Конфиг в `~/.hermes/config.yaml` (и в `~/.hermes/hermes-whale/config.yaml`):
```yaml
mcp_servers:
obsidian:
command: mcpvault
args:
- /Users/admin/obsidian
```
Пакет: **`@bitbonsai/mcpvault`** v0.12.1 (npm). Команда `mcpvault`.
Hermes на старте:
1. Читает `mcp_servers` из config.yaml
2. Спавнит `mcpvault /Users/admin/obsidian` как subprocess
3. Init + list_tools → регистрирует инструменты как `mcp_obsidian_*`
4. Агент видит инструменты `mcp_obsidian_read_note`, `mcp_obsidian_patch_note`, и т.д.
**Схема:**
```
Hermes (native MCP client) → spawn: mcpvault → reads/writes /Users/admin/obsidian/
```
### Инструменты, доступные через эту связку
`read_note`, `write_note`, `patch_note`, `list_directory`, `delete_note`, `search_notes`, `move_note`, `move_file`, `read_multiple_notes`, `update_frontmatter`, `get_notes_info`, `get_frontmatter`, `manage_tags`, `get_vault_stats`, `list_all_tags`.
## Факт: что такое ~/scripts/obsidian-mcp-wrapper.js и почему он НЕ используется
**Создан** 2026-05-09, когда вместо `mcpvault` стоял `npx obsidian-mcp` (старый пакет, автор Steven, ещё до переименования в `@bitbonsai/mcpvault`). Пакет постоянно падал:
- ZodError на `"id": null` в notifications — `.strict()` валидация
- Race condition при рестарте gateway
- UTF-8 chunk split портил большие JSON
- Зависания без watchdog
Wrapper решал всё это. **Сейчас НЕ используется.** Конфиг в `~/.hermes/config.yaml`:
```yaml
mcp_servers:
obsidian:
command: mcpvault # ← не node wrapper.js
args:
- /Users/admin/obsidian
```
**Почему:** после перехода на `@bitbonsai/mcpvault` (пришёл на смену старому obsidian-mcp), пакет стабильно работает с Hermes native MCP client. Wrapper стал не нужен. Конфиг поменяли, а doc не обновили.
**Файл `~/scripts/obsidian-mcp-wrapper.js`** лежит на диске, не используется. Надо удалить.
## Факт: корень проблем с patch_note
`mcp_obsidian_patch_note` падает с `"String not found"` — это **НЕ проблема транспорта**. Это проблема **самого mcpvault**:
- Файл: `dist/src/filesystem.js`, строка 217
- Механизм: `fullContent.split(oldString).length - 1`
- **Exact string match** — без trim, без fuzzy, без нормализации whitespace
Workaround: использовать Hermes `patch()` (fuzzy matching, 9 стратегий) для сложных строк. `mcp_obsidian_patch_note` — только для простого текста без спецсимволов.
## Fact: Obsidian MCP на Kraken — есть, и это stdio-процесс Hermes
Проверено 2026-09-26. На Kraken MCP-сервер **не является отдельным контейнером** —
его спавнит агент Hermes как дочерний процесс. Первый поиск «нет контейнера →
нет MCP» был **ошибочным**: искать надо было процессы, а не `docker ps`.
```
# на хосте Kraken
ps aux | grep mcpvault
→ UID 10000 1168741 ... node /opt/data/.local/bin/mcpvault /vault
PPID 5039 → /opt/hermes/.venv/bin/hermes gateway (контейнер hermes-kraken)
```
Конфиг (`/opt/data/config.yaml` **внутри** контейнера `hermes-kraken`):
```yaml
mcp_servers:
obsidian:
command: /opt/data/.local/bin/mcpvault
args:
- /vault
```
`mcpvault` там — симлинк на npm-пакет: `/opt/data/.local/lib/node_modules/@bitbonsai/mcpvault/dist/server.js`.
### Волт на Kraken — реальный, не пустой
```
/home/kraken/obsidian -> /srv/dev-disk-by-uuid-49e8f586-…/obsidian
(тот же HDD, что и docker-data)
```
Внутри: `personal/`, `family/`, `.obsidian/`, `.git/`, `_index.md` — полноценная
git-реплика волта Mac. То есть **волт существует в обоих местах**, а не только на Mac.
### Итог: два независимых Obsidian MCP
| Где | Как | Транспорт | Порт |
|---|---|---|---|
| Mac | контейнер `obsidian-mcp` (`mcp-proxy` → `mcpvault`) | SSE | `:3101`, публикуется на `0.0.0.0` |
| Kraken | `mcpvault` как дочерний процесс `hermes-kraken` | **stdio** | нет |
| Kraken (для Балды) | контейнер `obsidian-mcp` — **создан 2026-09-26** | SSE | `:3101`, только внутри `mattermost_mm-net` |
📌 `mcpvault` **не умеет HTTP** — только stdio (`--help` подтверждает: только `[vault-path]`).
Чтобы отдать его по сети, нужен `mcp-proxy` (обёртка stdio → SSE). Именно так сделано
на Mac и повторено на Kraken.
---
## Fact: obsidian-mcp на Kraken для Балды (создан 2026-09-26)
Собрано для шага 5 [[personal/plans/balda-mm-phase4-agents]]: Балде нужен доступ к
волту, чтобы читать документацию при формировании ТЗ.
**Точная копия рабочей схемы с Mac** — пара `mcp-proxy` + `mcpvault`:
| Что | Путь / значение |
|---|---|
| Проект (Mac) | `~/Developer/obsidian-mcp-kraken/` |
| Dockerfile | `node:24-bookworm` + `@bitbonsai/mcpvault@0.11.0` + `mcp-proxy@6.4.4` |
| Образ | `obsidian-mcp-image:0.1.0` (загружен на Kraken) |
| Compose (Kraken) | `/home/kraken/obsidian-mcp/docker-compose.yml` |
| Контейнер | `obsidian-mcp`, сеть `mattermost_mm-net` |
| Волт | `/srv/dev-disk-by-uuid-49e8f586-…/obsidian` → `/vault` **`:ro`** |
| Команда | `mcp-proxy --port 3101 -- mcpvault /vault` |
🔴 **Волт смонтирован только для чтения (`:ro`).** Балда читает документацию, но не
правит её. Запись в волт через Балду — отдельное решение, требует апрува Alex.
```yaml
services:
obsidian-mcp:
image: obsidian-mcp-image:0.1.0
container_name: obsidian-mcp
restart: unless-stopped
command: ["--port", "3101", "--", "mcpvault", "/vault"]
volumes:
- /srv/dev-disk-by-uuid-49e8f586-…/obsidian:/vault:ro
networks:
- mm-net # mattermost_mm-net, external
```
### Питфоллы, пройденные при сборке
| # | Питфолл | Симптом | Фикс |
|---|---|---|---|
| 1 | `--host` у `mcp-proxy` **нет** | контейнер падает на разборе аргументов | только `--port N -- <cmd> <args>`; слушает `0.0.0.0` по умолчанию |
| 2 | Точка монтирования должна существовать в образе | `mkdir -p /vault` в Dockerfile + `WORKDIR /vault` | иначе mcpvault стартует не в том каталоге |
### Проверка
```bash
# /sse отвечает 200 (и локально, и из docker-сети Kraken)
curl -s -o /dev/null -w "%{http_code}\n" http://obsidian-mcp:3101/sse
# ⚠️ Порт именно 3101, НЕ 8080. Проба на 8080 даёт "Connection refused" при живом
# контейнере — mcp-proxy слушает порт из --port.
```
✅ **ПРИМЕНЕНО 2026-09-26.** Конфиг Балды на Kraken теперь содержит оба сервера:
```yaml
runtime:
mcp_servers:
executor-mcp:
type: http # ⚠️ НЕ streamable-http — валидатор: stdio|http|sse
url: "http://balda-executor-mcp:8890/mcp"
obsidian:
type: sse # ⚠️ НЕ http — у obsidian-mcp SSE-транспорт
url: "http://obsidian-mcp:3101/sse"
balda:
mcp_servers:
- executor-mcp
- obsidian
```
🔴 **Тип транспорта — источник двух подряд ошибок.** Obsidian отдаёт **SSE**, поэтому
`type: sse`. Если поставить `type: http`, Балда упадёт с
`failed to init MCP session: … session not found`.
Полная таблица типов — [[personal/tech/balda-executor-mcp]] §10e.
Бэкапы: `config.yaml.bak-obsidian-20260926-214849` (на Kraken, рядом с `config.yaml`).
⚠️ Туннель к Obsidian MCP **не нужен** — Балда ходит по docker-сети по имени
`obsidian-mcp`. Наружу порт не публикуется.
---
## Эволюция Obsidian MCP у нас
| Период | Что было | Проблемы |
|--------|----------|----------|
| До 2026-05-09 | `npx obsidian-mcp` (пакет Steven, прямой) | ZodError, race condition, UTF-8 chunk split, зависания |
| 2026-05-09 → ? | `npx obsidian-mcp` через wrapper | Wrapper решил проблемы |
| Сейчас | `mcpvault` (Hermes native MCP client) | Стабильно. patch_note exact match — единственная боль |
## Рекомендация по замене (2026-06-24)
При проблемах с mcpvault (зависания, память, exact match) — **cyanheads/obsidian-mcp-server**:
- `obsidian_replace_in_note` с regex + flexible whitespace (решает exact match)
- 9.7K dl/week, dual transport (stdio + HTTP), active
- Требует Obsidian Local REST API plugin (Obsidian должен быть открыт)
- Есть Docker support (`ghcr.io/cyanheads/obsidian-mcp-server`)
Подробнее: `personal/tech/obsidian-mcp-ecosystem.md`
## См. также
- `personal/tech/obsidian-mcp-ecosystem.md` — обзор всех 6 реализаций
- ⚠️ `personal/projects/personal-os/obsidian-mcp-wrapper.md` — **УСТАРЕЛ**, не отражает реальность