Skip to main content
Glama
README.md
# obsidian-sync-mcp

MCP-сервер (streamable HTTP) над репликой Obsidian-волта (`/srv/vault`, Syncthing) с CAS-записью.

## Инструменты

- `list_notes(dir?)` — рекурсивный список `.md` (скрыты `.git`, `.stversions`, `.stfolder`, `.trash`)
- `read_note(path)` → `{ content, rev }`, `rev = sha256(content)[:12]`
- `write_note(path, content, base_rev?)` — CAS: файл существует → `base_rev` обязателен, не совпал → `CONFLICT` + свежие `{ content, rev }`; файла нет → создание без `base_rev`
- `patch_note(path, old_str, new_str)` — `old_str` ровно один раз, иначе ошибка + свежие `{ content, rev }`
- `search_notes(query, dir?)` — ripgrep, путь + номер строки + строка

## Гарантии

- Мьютекс на путь: записи в один файл сериализуются
- Atomic write: tmp в той же директории (`.syncthing.*` — Syncthing игнорирует) + rename
- Path traversal: resolve + проверка префикса волта; запись в `.git`, `.stversions`, `.stfolder`, `.obsidian` запрещена
- Auth: Bearer-токен (env `AUTH_TOKEN`), иначе 401

## Деплой

```
/opt/obsidian-sync-mcp        код (git clone + npm install --omit=dev)
/etc/obsidian-sync-mcp/env    AUTH_TOKEN=... VAULT_DIR=/srv/vault PORT=8787
deploy/obsidian-sync-mcp.service → /etc/systemd/system/
```

Наружу — через cloudflared tunnel: `https://obsidian-mcp.example.com/mcp` → `localhost:8787`.

```
claude mcp add --transport http vault https://obsidian-mcp.example.com/mcp --header "Authorization: Bearer <токен>"
```