Files
obsidian-vault/wiki/obsidian-mcp-wrapper.md
T

3.5 KiB
Raw Blame History

obsidian-mcp-wrapper

Файл: ~/scripts/obsidian-mcp-wrapper.js
Назначение: прокси-обёртка над obsidian-mcp, решает два системных бага


Проблемы, которые решает

1. ZodError при инициализации (obsidian-mcp v1.0.6)

obsidian-mcp падал с ZodError сразу после запуска. Причина: Hermes отправляет
notifications/initialized с полем "id": null, а obsidian-mcp v1.0.6 использует
.strict() валидацию и не принимает лишние поля.

Fix: wrapper перехватывает все notification-сообщения (без result/error) с id === null
и удаляет поле id перед передачей в child.

2. Race condition при gateway restart

При рестарте Hermes gateway поднимает новый процесс obsidian-mcp-wrapper. Первые
параллельные tool-вызовы приходят пока child ещё инициализируется (~500ms) → они
тайм-аутились, circuit breaker открывался (3 фейла → 60s cooldown).

Fix: wrapper буферизует все tool-вызовы до завершения handshake
(initialize → ответ → notifications/initialized), потом флашит очередь.


Как работает

Hermes (stdin) → wrapper → obsidian-mcp (child)
                              ↑ auto-restart при краше (до 5 раз)

Состояния:

  • ready = false — child стартует, все tool-вызовы в очередь
  • ready = true — handshake завершён, очередь флашится, всё проходит напрямую

Restart логика:

  1. Child упал → ready = false, restarts++
  2. Новый child спавнится
  3. Wrapper реплеит сохранённый initialize → ждёт ответа с serverInfo
  4. Отправляет notifications/initialized (не форвардит Hermes — он не просил)
  5. ready = true → флаш очереди

Логи (все в stderr с timestamp):

[obsidian-wrapper] 2026-05-09T12:00:00.000Z Spawning obsidian-mcp (vault=/Users/admin/obsidian)
[obsidian-wrapper] 2026-05-09T12:00:00.500Z Hermes → child (handshake complete): notifications/initialized
[obsidian-wrapper] 2026-05-09T12:00:00.501Z Child ready — flushing queue (3 items)
[obsidian-wrapper] 2026-05-09T12:00:01.200Z Stripped id:null from notification: notifications/initialized

Конфиг Hermes

~/.hermes/config.yaml:

obsidian:
  command: node
  args: [/Users/admin/scripts/obsidian-mcp-wrapper.js]

Wrapper сам вызывает /opt/homebrew/bin/obsidian-mcp /Users/admin/obsidian.


Производительность

  • Инициализация: ~587ms (без ZodError)
  • Overhead wrapper: negligible (pure Node.js child_process, нет npm-зависимостей)

История

2026-05-09 — создан после диагностики 58 ошибок obsidian/... call failed в логах Hermes.
Корневая причина — ZodError + race condition при старте. Wrapper написан вместо патча
исходников obsidian-mcp (патч не нужен, wrapper чище и не ломается при обновлении пакета).