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

11 KiB
Executable File
Raw Blame History

[!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):

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:

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):

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.

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 стартует не в том каталоге

Проверка

# /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 теперь содержит оба сервера:

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 — УСТАРЕЛ, не отражает реальность