惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
博客园_首页
IT之家
IT之家
Engineering at Meta
Engineering at Meta
量子位
宝玉的分享
宝玉的分享
MyScale Blog
MyScale Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
爱范儿
爱范儿
WordPress大学
WordPress大学
F
Full Disclosure
T
Tailwind CSS Blog
GbyAI
GbyAI
Recorded Future
Recorded Future
美团技术团队
S
SegmentFault 最新的问题
A
About on SuperTechFans
小众软件
小众软件
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
Apple Machine Learning Research
Apple Machine Learning Research
D
DataBreaches.Net
J
Java Code Geeks
The Cloudflare Blog
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
D
Docker
Vercel News
Vercel News
H
Help Net Security
博客园 - 叶小钗
B
Blog
阮一峰的网络日志
阮一峰的网络日志
N
Netflix TechBlog - Medium
Blog — PlanetScale
Blog — PlanetScale
腾讯CDC
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Register - Security
The Register - Security
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
Jina AI
Jina AI

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Как я подключил Obsidian к Claude и Codex: домашний сервер, CouchDB, MCP и баг, который съедал заметки
Григорий · 2026-06-23 · via Все публикации подряд на Хабре

Средний

11 мин

61

Я веду Obsidian как доску со стикерами: набрасываю идеи, фиксирую мысли на ходу, собираю технические заметки и черновики. Claude Code использую как думалку: разбираю архитектуру, пишу код, обсуждаю решения и иногда прошу превратить хаос в нормальный план.

Проблема в том, что они жили в параллельных мирах. Claude не видел мои заметки, и каждый раз, когда мне нужен был контекст, приходилось вручную копировать куски из Obsidian. Это долго, неудобно, а по дороге легко забыть важную деталь или скормить ассистенту не тот фрагмент.

Конечно, для Obsidian уже существуют готовые MCP-серверы. MCP (Model Context Protocol) — это стандарт, через который AI-клиент может вызывать внешние инструменты. Например, искать файлы, читать документы, создавать записи, ходить в базы и так далее. Но большинство готовых решений для Obsidian работают с локальными файлами, а значит, vault должен лежать рядом с агентом на той же машине.

Мне же хотелось, чтобы заметки синхронизировались между устройствами, AI-агент был доступен из разных клиентов, всё self-hosted, без облачной подписки на синхронизацию и запущенного Obsidian Desktop на сервере.

В итоге получился remote MCP-сервер, который ходит напрямую в CouchDB, где уже лежат данные Obsidian LiveSync. Сейчас проект даёт AI-клиентам 20 инструментов для работы с vault: поиск, чтение, создание и обновление заметок, теги, свойства, граф связей, canvas, шаблоны. Первым клиентом был Claude, потом добавился Codex. Но путь туда оказался не совсем прямым. Пришлось разобраться с форматом LiveSync, OAuth 2.1, bearer-токенами и багом, который однажды тихо удалил куски заметки.

Шаг первый: домашний сервер и CouchDB

У меня дома стоит небольшой сервер на Ubuntu. Роутер Keenetic с KeenDNS даёт внешний домен, SSH уже был настроен, поэтому туда всё и поехало.

Для синхронизации Obsidian я выбрал Self-hosted LiveSync. Это community-плагин, который хранит vault в CouchDB. Это не просто «ещё один бэкап». Все клиенты Obsidian подключаются к одной базе, а LiveSync синхронизирует изменения между ними.

Работает это так: плагин стоит на десктопе и телефоне, оба подключены к CouchDB. Когда заметка меняется, LiveSync разбивает данные на части, отправляет изменившиеся документы в базу, а остальные устройства получают обновление. Для пользователя это выглядит как обычная синхронизация, но под капотом Obsidian-файл превращается в набор документов CouchDB.

CouchDB здесь удобна тем, что у неё есть HTTP API и репликация из коробки. Своя база, полный контроль и никаких внешних сервисов.

CouchDB я поставил нативно, без Docker. На домашнем железе лишний слой контейнеров мне был не нужен. Просто запустил его через systemd на порту 5443.

Первая неожиданность — CORS и KeenDNS

LiveSync на десктопе подключился без проблем, а вот мобильные клиенты Obsidian с LiveSync в моей конфигурации не заработали без HTTPS. Я не буду притворяться, что докопался до единственной канонической причины. На практике мобильный клиент требовал HTTPS, а в моей конфигурации KeenDNS при проксировании молча срезал CORS-заголовки. Браузер видел ответ без нужных заголовков и блокировал запрос.

Решение вышло несимметричным, но рабочим: десктоп синхронизируется напрямую по HTTP, мобильные клиенты ходят через отдельный KeenDNS-поддомен, а MCP-сервер на домашнем сервере обращается к той же CouchDB напрямую.

Схематично получилось так:

Obsidian Desktop  -- HTTP ------------┐
                      │
Obsidian Mobile   -- HTTPS -- KeenDNS -- CouchDB
                      │
MCP-сервер        -- HTTP ------------┘

На этом этапе AI ещё ни при чём. Просто Obsidian уже синхронизируется через CouchDB, и у меня появляется база, к которой можно обратиться с сервера.

Шаг второй: MCP-сервер поверх CouchDB

Когда LiveSync заработал, мне пришла следующая мысль. Раз Obsidian уже хранит все заметки в CouchDB, почему бы не дать к ним прямой доступ Claude? Без Local REST API-плагина. Без запущенного Obsidian Desktop на сервере. Без копирования локального vault рядом с агентом. Просто HTTP-запросы к CouchDB и MCP-инструменты поверх них.

MCP-сервер в этой схеме — переводчик. Claude, Codex или другой клиент не знают, как устроен LiveSync, где лежат чанки и как из них собрать markdown. Они вызывают человеческие инструменты: search, fetch, update_note, get_links, find_hub_notes. А сервер внутри делает всю грязную работу: идёт в CouchDB, находит документ заметки, читает список чанков, собирает содержимое и возвращает нормальный markdown.

Например, запрос концептуально выглядит так:

fetch("Идеи/проект.md")
  -> найти manifest-документ заметки
  -> прочитать children
  -> загрузить каждый h:chunk
  -> склеить data в правильном порядке
  -> вернуть markdown клиенту

Второй сюрприз — формат хранения LiveSync

LiveSync не хранит заметку как один файл. В CouchDB лежит манифест с массивом children, а сами куски текста лежат отдельными документами с ID вида h:...:

идеи/проект.md -> children: ["h:a1b2c3", "h:d4e5f6"]
h:a1b2c3        -> первая часть текста
h:d4e5f6        -> вторая часть текста

Для синхронизации это разумно. Не нужно гонять большой файл целиком при каждом изменении, а можно обновить изменившийся фрагмент. Но для внешнего сервиса «заметка» перестаёт быть одной сущностью. Хочешь прочитать документ — обязан собрать все чанки. Хочешь обновить документ — сначала нужно убедиться, что он прочитан полностью.

Это важная деталь. Позже именно она стала одной из причин бага с потерей разделов.

Поиск в первом релизе я сделал просто: сервер получает список заметок, читает содержимое каждой и ищет текст или regex уже в памяти. Отдельного индекса на тот момент не было. Для небольшого vault этого хватает, но это честное ограничение первого релиза, а не магический full-text search уровня поискового движка.

Шаг третий: OAuth 2.1

Я написал сервер, запустил, пытаюсь подключить Claude.ai — не работает. Лезу в документацию MCP и Claude по custom connectors. Оказывается, remote MCP — это не то же самое, что локальный MCP.

Локальный MCP обычно запускается рядом с клиентом. Он может читать локальный конфиг, переменные окружения, файлы и в целом находится в зоне доверия пользователя. Remote MCP доступен по сети. Claude.ai подключается к нему из облачной инфраструктуры Anthropic, а не с моего компьютера. Значит, сервер должен уметь нормально проверять, кто к нему пришёл.

Для Claude.ai это означает OAuth 2.1: Authorization Code Flow с PKCE. Не API-ключ в заголовке, не Basic Auth, не пароль в конфиге, а полноценный flow с редиректом пользователя, выдачей access-токенов и refresh-токенов.

Пришлось реализовать всё, что сначала казалось избыточным для «просто дать Claude доступ к заметкам»:

  • endpoint авторизации;

  • endpoint выдачи токена;

  • refresh-токенов;

  • хранение кодов авторизации и сессий;

  • pre-registered OAuth client;

  • redirect URI для Claude;

  • проверку токена на MCP-запросах.

В текущей версии OAuth-клиент из коробки рассчитан на Claude.ai и Claude Code. Dynamic Client Registration выключен. Для других OAuth-клиентов нужно либо предрегистрировать отдельные redirect URI, либо включать DCR, понимая риск: любой, кто знает URL сервера, сможет попробовать зарегистрировать клиент.

Полезные ссылки, которые стоит держать рядом:

После настройки OAuth сервер стал подключаться через Claude Connectors. Добавляете URL MCP-сервера в настройках Claude, проходите авторизацию, и vault доступен не только в одном локальном окружении, а на клиентах этого пользователя.

Не только Claude: Bearer-only и Codex

Отдельный поворот случился позже, когда меня забанил Claude. Сразу стало ясно, что привязывать всю базу знаний к одному AI-клиенту — плохая идея. Если сервер действительно полезен, он должен работать не только с Claude.

Так появилась поддержка Codex и более простой режим авторизации — Bearer-only.

OAuth остаётся нужен там, где его требует клиент, например для Claude.ai. Но не каждому клиенту нужен полный Authorization Code Flow. Для локальных и агентских сценариев часто достаточно статического токена: клиент отправляет Authorization: Bearer ..., сервер сравнивает токен с MCP_API_KEY и либо пускает запрос, либо отклоняет.

В конфигурации это выглядит так:

MCP_API_KEY=your_api_key

Если MCP_API_KEY задан, сервер выбирает bearer-режим. Если bearer не задан, но есть OAUTH_PASSWORD, включается OAuth. Если не задано ничего, сервер падает при старте, а не запускается открытым. Это важное поведение: MCP-сервер имеет доступ к заметкам, и случайно поднять его без авторизации было бы плохой идеей.

Для Codex подключение документировано так:

[mcp_servers.obsidian]
url = "https://your-server/mcp"
bearer_token_env_var = "MCP_API_KEY"

То есть в окружении, где работает Codex, лежит тот же MCP_API_KEY, а в конфиге указан remote MCP endpoint. После этого Codex получает те же инструменты vault: может искать заметки, читать контекст, создавать планы, обновлять документы.

Для меня это оказался важный архитектурный вывод: Obsidian должен быть общей базой знаний для разных AI-инструментов, а не расширением одного конкретного клиента.

Что получилось в первом релизе

Первый релиз, 1.0.0, вышел 21 марта 2026 года. В нём было 20 инструментов для работы с vault.

Группа

Инструменты

Заметки

search, fetch, create, update, delete, move, duplicate, list

Метаданные

properties, tags, get_all_tags

Граф

links, link_graph, hub_notes, orphaned_notes

Canvas

node, edge

Прочее

vault_stats, list_templates, create_from_template

Группировка здесь по смыслу, а не по уровню риска. Это важно: search и fetch относительно безопасны, потому что только читают. А вот create, update, delete и move уже меняют базу. Когда AI получает write-инструменты к вашей базе знаний, нужно думать о бэкапах и failure modes заранее.

Вот простой пример работы:

> найди мои заметки,где упоминается CouchDB

Claude: Нашёл 3 заметки:

Инструменты/mcp/obsidian-mcp.md
Технические заметки/MCP Obsidian — проблема с секциями.md
Идеи/Хабр — статья про obsidian-livesync-mcp.md
Показать содержимое?

Но полезность не только в поиске. Например, агента можно попросить найти хабовые заметки, на которые больше всего ссылок и которые сами много куда ссылаются:

> покажи хабовые заметки в vault
MCP: find_hub_notes(min_links=5)
Claude: Вижу несколько центров:
Работа/Идеи/Проект Анализ требований/README.md
Идеи/Хабр — статья про obsidian-livesync-mcp.md
Инструменты/mcp/obsidian-mcp.md

Или найти осиротевшие заметки без входящих и исходящих связей. Для Obsidian это полезно: агент становится не просто редактором файлов, а навигатором по базе знаний.

Но первый релиз был не идеальным. Поиск проходил по заметкам без отдельного индекса. OAuth из коробки был рассчитан на Claude. А write-инструменты оказались рискованнее, чем я думал. И, как выяснилось, ошибка в чтении чанков могла превращаться в потерю данных.

Баг, который съедал заметки

Через неделю реального использования я поймал неприятный баг, когда

попросил Claude обновить один раздел в большом документе примерно на 300 строк через search-replace. Операция прошла, заметка сохранилась, но несколько других разделов исчезли. Никакой ошибки, никакого предупреждения. Данные просто тихо потерялись.

Первой мыслью было: Claude плохо сделал replace. Такое бывает — модель могла заменить не тот фрагмент, переписать больше текста, неаккуратно собрать ответ. Но улики не сходились. Исчезали разделы вне зоны замены: начало, середина и отдельные блоки, к которым запрос вообще не относился.

Потом проявился ещё один странный симптом. При попытке вернуть потерянное через повторный search-replace сервер отвечал «No matches found», хотя визуально строка совпадала с тем, что должно было лежать в файле. Это уже было похоже не на ошибку модели, а на то, что сам сервер видит не тот документ, который вижу я.

Временный обход нашёлся быстро. Я использовал mode=overwrite с полным содержимым документа. Это было медленно и неудобно, зато данные перестали пропадать. Значит, проблема была не в самой CouchDB как базе и не в LiveSync как синхронизации, а в цепочке «прочитал заметку → изменил кусок → записал обратно».

Диагностика показала три уровня проблемы.

Уровень 1 — чтение. read_note_content молча пропускала чанки, если те не находились в CouchDB. Вместо ошибки сервер возвращал частичный контент:

# Было: тихо пропустить битый чанк
for child_id in children:
    chunk = await self.get_doc(child_id)
    if chunk:
        parts.append(chunk["data"])
    # если нет — просто идём дальше, потеряв кусок заметки

Уровень 2 — запись. write_note сначала удаляла старые чанки, потом писала новые. Если операция падала посередине, документ мог остаться без содержимого.

Уровень 3 — обновление. obsidian_update_note читала заметку, делала search-replace в памяти и писала результат обратно. Если чтение возвращало неполный текст, update перезаписывал заметку этим неполным текстом и не понимал, что только что уничтожил часть документа.

Фикс вышел в версии 1.0.1 от 10 апреля 2026 года.

Чтение стало fail-fast:

for child_id in children:
    chunk = await self.get_doc(child_id)
    if chunk is None:
        raise ValueError(
            f"Chunk '{child_id}' not found for document '{doc_id}'. "
            "Document may be corrupted or still syncing."
        )
    data = chunk.get("data", "")
    if not isinstance(data, str):
        raise ValueError(
            f"Chunk '{child_id}' has unexpected data type."
        )
    parts.append(data)

Запись стала безопаснее по порядку операций. Теперь сначала создаётся новый чанк, и только потом удалялись старые.

# Создаём новый чанк первым
chunk_id = self._generate_chunk_id()
await self.put_doc(chunk_id, {
    "_id": chunk_id,
    "data": content,
    "type": "leaf",
})
# Старые чанки удаляем только после успешной записи нового
for child_id in doc["children"]:
    chunk = await self.get_doc(child_id)
    if chunk:
        await self.delete_doc(child_id, chunk["_rev"])

И главное: obsidian_update_note теперь ловит ошибку чтения и возвращает её пользователю, а не записывает неполный документ обратно.

После фикса правило стало простым: если заметку нельзя собрать полностью, её нельзя обновлять. Лучше явная ошибка, чем тихая потеря данных.

Итоговая схема

Сейчас схема выглядит так:

Obsidian Desktop / Mobile
        ↕ LiveSync
      CouchDB
        ↕ HTTP
   MCP-сервер
        ↕ OAuth 2.1 или Bearer token
 Claude.ai / Claude Code / Codex / другие MCP-клиенты

Obsidian продолжает синхронизироваться как раньше. MCP-сервер не требует запущенного Obsidian Desktop и работает напрямую с CouchDB. Claude подключается через OAuth-сценарий. Codex и другие клиенты могут использовать bearer-токен, если им подходит такой режим.

Заметки становятся общей базой знаний для AI-инструментов. Это уже не «папка файлов на одном компьютере», а удалённый vault, к которому можно подключать разных агентов.

Как поднять у себя

Минимально нужно:

  • CouchDB с данными Obsidian LiveSync;

  • Python 3.11+;

  • домен с HTTPS для remote MCP;

  • понимание, какой клиент будете подключать: Claude через OAuth или Codex/другой клиент через bearer-токен.

Общий порядок такой:

  1. Поднять CouchDB.

  2. Создать базу для LiveSync.

  3. Настроить CORS так, чтобы Obsidian LiveSync мог подключаться к CouchDB.

  4. Подключить Self-hosted LiveSync в Obsidian.

  5. Проверить синхронизацию хотя бы на одном-двух устройствах.

  6. Поднять MCP-сервер.

  7. Настроить авторизацию.

  8. Подключить AI-клиент.

Сам сервер:

git clone https://github.com/Selenion/obsidian-livesync-mcp
cd obsidian-livesync-mcp
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
python run.py

В .env сейчас используются такие переменные:

COUCHDB_URL=http://localhost:5984
COUCHDB_USER=admin
COUCHDB_PASSWORD=your_password
COUCHDB_DATABASE=obsidian
MCP_API_KEY=your_api_key
OAUTH_PASSWORD=your_oauth_password
OAUTH_CLIENT_ID=your_client_id
OAUTH_CLIENT_SECRET=your_client_secret
MCP_SERVER_URL=https://your-domain.com
MCP_HOST=0.0.0.0
MCP_PORT=8484

Для Claude.ai нужен OAuth-сценарий: URL сервера добавляется как custom connector, а client ID и client secret берутся из .env.

Для Codex — bearer-режим:

[mcp_servers.obsidian]
url = "https://your-server/mcp"
bearer_token_env_var = "MCP_API_KEY"

Отдельно про безопасность

CouchDB не стоит открывать наружу напрямую. Креды CouchDB — это доступ ко всем заметкам. Наружу лучше выставлять защищённый HTTPS/MCP-слой, а саму базу держать доступной только там, где она действительно нужна.

Перед включением write-инструментов сделайте бэкап vault или CouchDB. Read-инструменты полезны сами по себе, а запись лучше включать только после того, как вы понимаете, как восстановиться при ошибке.

Что дальше

Следующие очевидные направления развития:

  • нормальный индекс или векторный поиск, чтобы не проходить весь vault при каждом поиске;

  • webhooks при изменениях vault;

  • более удобная поддержка разных OAuth-клиентов;

  • отдельные политики для read/write-инструментов;

  • возможно, небольшая админка для диагностики подключения и состояния базы.

Код открыт: https://github.com/Selenion/obsidian-livesync-mcp

Если используете Obsidian LiveSync и хотите подключить к нему AI-агента — попробуйте и напишите в комментариях, как это работает на вашем vault.

P.S. Эту статью я писал вместе с AI-ассистентами. Сначала Claude помогал разрабатывать сервер и ловить баги. Потом, когда Claude меня забанил, Codex помог продолжить работу. В каком-то смысле инструмент действительно описывает сам себя и уже не через одного клиента.

Если тема AI-инструментов в разработке вам близка, 25 июня в 18:30 на площадке «Сфера X5» в Парке Горького пройдёт первый митап серии AI & ML Talks.

Поговорим о том, кто отвечает за качество сгенерированного кода, как его проверять, что делать с безопасностью и насколько большие компании готовы пускать AI-код в продакшен. В программе три доклада, Hot Battle со спорным тезисом и голосованием зала, а ещё нетворкинг под открытым небом.

Будет полезно разработчикам любого стека, тимлидам, AI-early adopters и всем, кто уже использует ИИ-инструменты или только думает, как встроить их в свой процесс.

🔗 Регистрация