Skip to main content
Glama
sipho102
by sipho102

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() 会实时读取你仓库中 90-meta/CONVENTIONS.md 里的 type/status/domain 枚举,而不是硬编码它们(参见 src/brain_mcp/vault.py 中的 _extract_enum_values)。它已直接对照一个真实仓库的文件做过校验:该文件在单个 ## Enums 标题下将这三个枚举写成粗体内联标签(**type:** \note`, `project`, ...),而不是让每个枚举各自拥有一个子标题,因此 _extract_enum_values 会先尝试这种形态(限定在标签自身的段落内,这样就不会把下方正文中无关的、被反引号引用的词收进来——例如 “domainis the primary query axis...”),对于以其他方式记录枚举的仓库,则回退到基于标题的启发式方法。如果你以后重构CONVENTIONS.md`'s Enums 部分,请重新检查这个解析器——如果它无法为全部三个字段解析出非空的值列表,服务器会在启动时明确报错,而不是回退到错误的默认值。

uid 格式: 用于校验该解析器的仓库目前在其自身的 CONVENTIONS.md 中存在自相矛盾——frontmatter 示例显示的是 UUIDv4,其下方两行正文说真实格式是 YYYYMMDD-HHmm(同一分钟冲突时附加一个字母),而磁盘上的实际笔记之间又使用了三种不同的方案(一条 inbox 笔记中是 UUIDv4,meta 文档中是 00000000-000N 哨兵值,_index.md 文件中是 YYYYMMDD-000N 顺序计数器)。capture() 生成 UUIDv4——这正是原始规范的要求,与当前代码一致,并且能让 read_note 的短前缀查找(≥8 个字符)保持有意义;而如果针对低熵的、基于日期的 id,同一天的所有内容都共享同一个前缀,短前缀查找就不会有意义了。如果你自己的 CONVENTIONS.md 记录了不同的 uid 方案,那值得在仓库侧进行协调统一——这不是本服务器会自动处理的事情。

Related MCP server: Obsidian MCP Server

环境要求

  • 仓库的 PARA 结构和 frontmatter 模式,如仓库自身的 90-meta/CONVENTIONS.md 所述。

  • Unraid 机器上的 Docker(或 Docker Compose),或本地用于开发的 Python 3.12 + uv

  • PATH 中的 ripgrep(已捆绑在容器镜像中;本地开发需单独安装)。

配置

所有配置都通过环境变量进行——没有任何关于特定仓库的信息(路径、名称、令牌)被硬编码,因此同一个镜像可以以独立容器的方式服务任意数量的同级仓库。

变量

必填

默认值

含义

BRAIN_ROOT

容器内仓库根的绝对路径

BRAIN_NAME

实例名称,例如 personalfamily

BRAIN_TOKEN

每个 MCP 请求所需的 Bearer 令牌

PORT

3100

监听端口

BIND_ADDRESS

0.0.0.0

监听地址

LOG_LEVEL

INFO

DEBUG/INFO/WARNING/ERROR/CRITICAL

运行 Compose 前,请把 .env.example 复制为 .env,并填写 BRAIN_NAMEBRAIN_VAULT_PATH(你的仓库在宿主机上的路径)和 BRAIN_TOKEN(一个随机密钥——openssl rand -hex 32 就很不错)。

本地开发

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

这是有意为之且至关重要的设计——即使写入路径存在 bug,也无法触碰 inbox 之外的任何内容,无论 Python 代码自以为在做什么。请不要把它简化成单一的读写挂载。

改为作为 Unraid 应用安装

如果你更愿意像管理其他应用一样,从 Unraid 的 Docker 选项卡管理这个容器——用一个表单代替编辑 .env,之后还能用“启动/停止/更新”按钮——unraid/brain-mcp.xml 中就有现成的模板。.github/workflows/publish.yml 会在每次推送到 main 时构建本仓库的镜像并发布到 GHCR(ghcr.io/sipho102/brain-mcp:latest),模板会直接拉取该镜像——完全不需要在 Unraid 机器上进行克隆或构建。

让 Unraid 可以使用这个模板:

  • 推荐——在 Docker 选项卡中点击添加容器(Add Container),然后将本仓库模板的原始 URL 直接粘贴到模板字段中: https://raw.githubusercontent.com/sipho102/brain-mcp/main/unraid/brain-mcp.xml 这种方式不会向 Unraid 的本地模板文件夹写入任何内容,因此不会留下多余文件,日后也不会与之冲突——关于另一种方法,请参阅下面的注意事项。

  • 或者先通过 SSH 把它复制到 Unraid 的本地模板文件夹中:

    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)”之后的说明:容器创建后要删除这个文件。

无论采用哪种方式,你都会得到一个表单,用来填写仓库路径、inbox 路径(必须是 <vault path>/00-inbox——模板无法替你推导出来)、实例名称和 Bearer 令牌;其余所有内容都已在“高级视图(advanced view)”下预填了合理的默认值。

如果你使用了上面的本地复制方法,请在容器创建后删除那个种子文件:

rm /boot/config/plugins/dockerMan/templates-user/brain-mcp.xml

当你在“添加容器(Add Container)”上点击“应用(Apply)”时,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_NAMEBRAIN_VAULT_PATHBRAIN_TOKENPORT,然后也在那里运行 docker compose up -d --build。同一个镜像(brain-mcp:latest),相互独立的容器。

容器用户/权限

容器以非 root 用户身份运行,默认 UID:GID 为 99:100(即 Unraid 的 nobody:users)——如果你的共享目录需要不同的属主,可以在构建时用 .env 中的 BRAIN_UID/BRAIN_GID 覆盖。该用户必须对宿主机共享目录上的 00-inbox/ 具有写权限。

连接客户端

Claude Code

claude mcp add --transport http --scope user brain \
  http://<unraid-host>:3100/mcp \
  --header "Authorization: Bearer <token>"

然后在会话中运行 /mcp,应该会列出全部六个工具。

已知怪癖: Claude Code 反复出现过这样的 bug:通过 --header 设置的请求头在建立会话期间不会被发送,从而产生 401,即便使用相同令牌的 curl 一切正常。如果你遇到了这种情况,请直接把 headers 对象写进 JSON 配置(~/.claude/mcp_servers.json 或相应作用域文件)中:

{
  "mcpServers": {
    "brain": {
      "type": "http",
      "url": "http://<unraid-host>:3100/mcp",
      "headers": {
        "Authorization": "Bearer <token>"
      }
    }
  }
}

(在 JSON 配置中,type 也接受 streamable-http 作为 http 的别名。)

opencode

opencode 默认会对远程 MCP 服务器尝试 OAuth 发现,并且除非你显式禁用这一点,否则它会忽略静态 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 曾被直接打开过则是浏览器历史、如果你曾把它粘贴进终端则是 shell 历史。访问日志在这里不用担心(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/ 中创建一条新笔记。绝不覆盖已有内容,绝不触碰 inbox 之外的任何内容。

本服务器刻意不做的事

不做语义搜索/嵌入,不提供 00-inbox/ 之外的写访问,不依赖 Obsidian Local REST API(直接读取文件系统),不抓取 paperless-ngx 文档(从 frontmatter 返回文档 ID,供客户端链接到独立的 paperless MCP 服务器),不做任何 git 操作。理由请参阅 brain-mcp-spec.md §2。

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    A
    quality
    A
    maintenance
    A 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.
    38
    31
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Exposes an Obsidian notes vault as MCP services, enabling AI assistants to search, read, create, update, and delete notes and folders.
    24
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Exposes a personal markdown-based second brain (Obsidian-style) as an MCP server, enabling agents to search, read, and write notes with privacy controls.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP 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.
    235
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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