brain-mcp
brain-mcp
Автор иконки: wenmeiZhou на iStock.
MCP-сервер, который предоставляет markdown-хранилище второго мозга, организованное по методу PARA (совместимое с Obsidian), в виде набора инструментов для чтения и одного ограниченного инструмента для записи (capture, который только создаёт новые заметки в 00-inbox/). Работает как Docker-контейнер, используется через streamable-HTTP клиентами Claude Code, opencode и другими MCP-клиентами.
Полная спецификация поведения: см. brain-mcp-spec.md в этом репозитории (или там, где вы его храните), если вам нужно «почему» за тем или иным проектным решением.
Примечания о парсере CONVENTIONS.md
brain_structure() читает перечисления type/status/domain напрямую из вашего файла 90-meta/CONVENTIONS.md, а не захардкоживает их (см. _extract_enum_values в src/brain_mcp/vault.py). Он был проверен на реальном файле хранилища: в этом файле три перечисления указаны как жирные встроенные метки под одним заголовком ## Enums (**type:** \note`, `project`, ...), а не каждое в отдельном подзаголовке, поэтому _extract_enum_values сначала пробует такую форму (ограничиваясь абзацем самой метки, чтобы не захватывать посторонние слова в кавычках-бэктиках в тексте ниже — например, «domain— основная ось запросов...»), а затем переходит к эвристике на основе заголовков для хранилищ, где перечисления описаны иначе. Если вы позже измените структуру раздела Enums вCONVENTIONS.md`, перепроверьте этот парсер — сервер громко падает при запуске, а не переходит к плохим значениям по умолчанию, если не может разобрать непустой список значений для всех трёх полей.
Формат uid: хранилище, на котором это проверялось, в настоящее время содержит противоречие в собственном CONVENTIONS.md — пример во frontmatter показывает UUIDv4, в тексте двумя строками ниже сказано, что реальный формат — YYYYMMDD-HHmm (+ буква при коллизиях в одну минуту), а реальные заметки на диске используют три разные схемы (UUIDv4 в одной заметке во входящих, 00000000-000N-заглушки в мета-документах, последовательные счётчики YYYYMMDD-000N в файлах _index.md). capture() генерирует UUIDv4 — это то, что просила исходная спецификация, соответствует текущему коду и сохраняет осмысленность поиска по короткому префиксу в read_note (≥8 символов), чего не было бы с низкоэнтропийным датированным id, где всё за один день имеет общий префикс. Если в вашем собственном CONVENTIONS.md описан другой формат uid, это стоит согласовать на стороне хранилища — сервер это автоматически не делает.
Related MCP server: Obsidian MCP Server
Требования
Структура PARA и схема frontmatter хранилища, как описано в собственном
90-meta/CONVENTIONS.mdхранилища.Docker (или Docker Compose) на Unraid-машине, или Python 3.12 +
uvлокально для разработки.ripgrepв PATH (встроен в образ контейнера; установите отдельно для локальной разработки).
Конфигурация
Вся конфигурация через переменные окружения — ничего о конкретном хранилище (путь, имя, токен) не захардкожено, поэтому один и тот же образ обслуживает любое количество соседних хранилищ как отдельные контейнеры.
Переменная | Обязательная | По умолчанию | Значение |
| да | — | Абсолютный путь к корню хранилища в контейнере |
| да | — | Имя экземпляра, например |
| да | — | Bearer-токен, обязательный для каждого MCP-запроса |
| нет |
| Порт прослушивания |
| нет |
| Адрес прослушивания |
| нет |
|
|
Скопируйте .env.example в .env и заполните BRAIN_NAME, BRAIN_VAULT_PATH (путь на хосте к вашему хранилищу) и BRAIN_TOKEN (случайный секрет — openssl rand -hex 32 подойдёт) перед запуском Compose.
Локальная разработка
uv sync --dev # or: python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"
uv run pytest # or: .venv/bin/python -m pytestТесты полностью выполняются на синтетическом фикстурном хранилище, созданном в tests/conftest.py — никогда на реальных данных.
Чтобы запустить сервер локально на реальном (или тестовом) каталоге хранилища:
export BRAIN_ROOT=/path/to/vault
export BRAIN_NAME=personal
export BRAIN_TOKEN=dev-token
uv run brain-mcpЗапуск на Unraid
cp .env.example .env # fill in BRAIN_NAME, BRAIN_VAULT_PATH, BRAIN_TOKEN
docker compose up -d --build # or: docker compose pull && docker compose up -d
curl http://<unraid-host>:3100/health--build собирает из этого репозитория; pull вместо этого загружает тот же образ, предварительно собранный из GHCR (см. «Установка как приложение Unraid» ниже) — оба варианта дают локальный тег ghcr.io/sipho102/brain-mcp:latest.
Файл compose монтирует BRAIN_VAULT_PATH в режиме только для чтения и поверх него монтирует только 00-inbox/ в режиме чтения-записи:
volumes:
- ${BRAIN_VAULT_PATH}:/vault:ro
- ${BRAIN_VAULT_PATH}/00-inbox:/vault/00-inbox:rwЭто намеренно и критически важно — даже ошибка в пути записи не может затронуть ничего за пределами входящих, независимо от того, что думает код Python. Не упрощайте это до единого монтирования чтения-записи.
Установка как приложение Unraid вместо этого
Если вы предпочитаете управлять этим через вкладку Docker в Unraid, как любым другим приложением — форма вместо редактирования .env, кнопки Start/Stop/Update после — для этого есть шаблон в unraid/brain-mcp.xml. .github/workflows/publish.yml собирает образ этого репозитория и публикует его в GHCR (ghcr.io/sipho102/brain-mcp:latest) при каждом push в main, и шаблон тянет его напрямую — без клонирования или сборки на Unraid-машине вообще.
Сделайте шаблон доступным для Unraid:
Рекомендуется — на вкладке Docker нажмите Add Container и вставьте URL сырого шаблона этого репозитория прямо в поле шаблона:
https://raw.githubusercontent.com/sipho102/brain-mcp/main/unraid/brain-mcp.xmlТак ничего не записывается в локальную папку шаблонов Unraid, поэтому не остаётся лишнего файла, который мог бы конфликтовать позже — см. предупреждение ниже об альтернативном методе.Или скопируйте его в локальную папку шаблонов Unraid через SSH:
curl -o /boot/config/plugins/dockerMan/templates-user/brain-mcp.xml \ https://raw.githubusercontent.com/sipho102/brain-mcp/main/unraid/brain-mcp.xmlЗатем он появится в Docker → Add Container → выпадающем списке шаблонов — но см. примечание сразу после Add Container об удалении этого файла после создания контейнера.
В любом случае вы получите форму для пути к хранилищу, пути к входящим (должен быть <путь к хранилищу>/00-inbox — шаблон не может вывести его за вас), имени экземпляра и bearer-токена; всё остальное предзаполнено разумными значениями по умолчанию в «расширенном виде».
Если вы использовали метод локального копирования выше, удалите этот файл-затравку после добавления контейнера:
rm /boot/config/plugins/dockerMan/templates-user/brain-mcp.xmlКогда вы нажимаете Apply в Add Container, Unraid сохраняет второй файл с вашими реальными значениями — my-brain-mcp.xml, рядом с пустым, который вы скачали — и оба объявляют одно и то же имя контейнера. С двумя шаблонами, претендующими на это имя, Update может в итоге пересоздать контейнер из пустого оригинала вместо вашего сохранённого, стирая BRAIN_NAME/BRAIN_TOKEN/пути и оставляя его неработоспособным. Как только my-brain-mcp.xml существует (проверьте ls /boot/config/plugins/dockerMan/templates-user/), файл-затравка выполнил свою задачу и больше не нужен — удалите его, чтобы не было двусмысленности. После этого нажатие Update потянет самое свежее из ghcr.io/sipho102/brain-mcp:latest, используя вашу сохранённую конфигурацию, как и ожидается.
Обслуживание второго хранилища
Один контейнер обслуживает одно хранилище — намеренно нет списка мульти-хранилищных сервисов в docker-compose.yml, и нет мульти-хранилищной формы в шаблоне Unraid. На пути приложения Unraid это просто означает повторное Add Container из того же шаблона с другим именем/путями/токеном/портом. На пути Compose скопируйте этот каталог развёртывания (или просто docker-compose.yml + .env) в другое место, заполните в копии .env другие BRAIN_NAME, BRAIN_VAULT_PATH, BRAIN_TOKEN и PORT, и запустите docker compose up -d --build оттуда. Тот же образ (brain-mcp:latest), независимые контейнеры.
Пользователь контейнера / права доступа
Контейнер работает от непривилегированного пользователя, UID:GID 99:100 по умолчанию (Unraid nobody:users) — переопределите при сборке через BRAIN_UID/BRAIN_GID в .env, если вашему ресурсу нужны другие права владельца. Этот пользователь должен иметь доступ на запись к 00-inbox/ на хостовом ресурсе.
Подключение клиента
Claude Code
claude mcp add --transport http --scope user brain \
http://<unraid-host>:3100/mcp \
--header "Authorization: Bearer <token>"Затем /mcp в сессии должен показать все шесть инструментов.
Известная особенность: у Claude Code были повторяющиеся ошибки, когда заголовки, заданные через --header, не отправлялись при установлении сессии, что приводило к 401, хотя curl с тем же токеном работал. Если вы столкнулись с этим, запишите объект headers напрямую в JSON-конфиг (~/.claude/mcp_servers.json или соответствующий файл области):
{
"mcpServers": {
"brain": {
"type": "http",
"url": "http://<unraid-host>:3100/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}(type также принимает streamable-http как псевдоним для http в JSON-конфигах.)
opencode
opencode по умолчанию пытается выполнить OAuth-обнаружение на удалённых MCP-серверах и игнорирует статический bearer-токен, если вы явно не отключите это:
{
"mcp": {
"brain": {
"type": "remote",
"url": "http://<unraid-host>:3100/mcp",
"oauth": false,
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}Без oauth: false opencode попытается выполнить (и провалит) OAuth-рукопожатие вместо использования заголовка.
Клиенты без поля заголовка вообще
Некоторые интерфейсы MCP-клиентов принимают только имя, транспорт и URL — нет способа задать пользовательский заголовок Authorization. Для таких поместите токен в URL:
http://<unraid-host>:3100/mcp?token=<token>Сервер сначала проверяет заголовок Authorization, а затем переходит к параметру запроса ?token=, так что это работает везде, где работает и конфигурация с заголовком выше. Стоит знать, прежде чем полагаться на это: токен в URL может оказаться в большем количестве мест, чем заголовок — в сохранённой конфигурации клиента, в истории браузера, если URL когда-либо открыт напрямую, в истории оболочки, если вы вставили его в терминал. Журналы доступа здесь не проблема (журнал доступа uvicorn выключен), но относитесь к самому URL как к носителю секрета, так же, как и к самому токену.
Инструменты
Шесть инструментов, намеренно небольших (схемы инструментов стоят контекста клиента):
brain_structure()— ориентация: папки PARA + счётчики, живые перечисления изCONVENTIONS.md, схема frontmatter, полный текст соглашений, количество заметок. Вызывайте это первым в сессии.search_notes(query, domain, type, status, para, tag, limit)— полнотекстовый поиск (ripgrep) с фильтрацией по frontmatter. Возвращает метаданные + фрагмент ~200 символов, никогда полные тела.read_note(identifier)— полная заметка по пути относительно хранилища, полномуuidили однозначному префиксуuid(≥8 символов).list_notes(para, domain, status, type, limit)— просмотр только метаданных, без поиска по содержимому.get_backlinks(identifier)— заметки, ссылающиеся на эту, с контекстной строкой.capture(title, body, domain, tags, source, links)— единственная запись: создаёт новую заметку в00-inbox/. Никогда не перезаписывает, никогда не касается ничего за пределами входящих.
Что это намеренно не делает
Нет семантического поиска/эмбеддингов, нет доступа на запись за пределами 00-inbox/, нет зависимости от Obsidian Local REST API (читает файловую систему напрямую), нет получения документов paperless-ngx (возвращает ID документов из frontmatter, чтобы клиент мог связать их с отдельным MCP-сервером paperless), нет операций с git. См. brain-mcp-spec.md §2 для обоснования.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceA generic Markdown vault MCP server with FTS5 full-text search, semantic vector search, frontmatter-aware indexing, incremental reindexing, and non-markdown attachment support that exposes search, read, write, and edit tools.3831MIT
- AlicenseNot gradedqualityCmaintenanceExposes an Obsidian notes vault as MCP services, enabling AI assistants to search, read, create, update, and delete notes and folders.241MIT
- AlicenseNot gradedqualityBmaintenanceExposes a personal markdown-based second brain (Obsidian-style) as an MCP server, enabling agents to search, read, and write notes with privacy controls.MIT
- AlicenseNot gradedqualityAmaintenanceMCP server that turns a Markdown folder (e.g. Obsidian vault) into a second brain, capturing readings and ideas, connecting them as concepts, and resurfacing related notes on demand.235MIT
Related MCP Connectors
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/sipho102/brain-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server