brain-mcp
brain-mcp
아이콘 디자인 출처: iStock의 wenmeiZhou.
마크다운 기반 PARA 구조의 세컨드 브레인 볼트(Obsidian 호환)를 읽기 도구 모음과 단일한 제약적 쓰기 도구(capture, 00-inbox/에 새 노트만 생성함)로 노출하는 MCP 서버입니다. Docker 컨테이너로 실행되며, streamable-HTTP를 통해 Claude Code, opencode 및 기타 MCP 클라이언트가 사용합니다.
전체 동작 사양: 설계 선택의 "이유"가 필요하면 이 저장소(또는 보관 중인 곳)의 brain-mcp-spec.md를 참조하세요.
CONVENTIONS.md 파서에 관한 참고 사항
brain_structure()는 type/status/domain 열거형을 하드코딩하는 대신 볼트의 90-meta/CONVENTIONS.md에서 실시간으로 읽어옵니다(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(같은 분에 충돌하면 문자 하나를 덧붙임)이라고 말하며, 디스크의 실제 노트들은 서로 다른 세 가지 방식을 사용합니다(인박스 노트 하나의 UUIDv4, 메타 문서의 00000000-000N 센티널, _index.md 파일들의 YYYYMMDD-000N 순차 카운터). capture()는 UUIDv4를 생성합니다. 원래 사양이 요구한 것이고, 현재 코드와 일치하며, read_note의 짧은 접두사 조회(≥8자)가 의미를 유지하게 해줍니다. 저엔트로피 날짜 기반 id에서는 같은 날의 모든 id가 같은 접두사를 공유하므로 그렇지 않을 것입니다. 자신의 CONVENTIONS.md가 다른 uid 방식을 문서화하고 있다면 볼트 쪽에서 조정할 가치가 있습니다. 이 서버가 자동으로 해주는 일이 아닙니다.
Related MCP server: Obsidian MCP Server
요구 사항
볼트 자체의
90-meta/CONVENTIONS.md에 설명된 볼트의 PARA 구조와 frontmatter 스키마.Unraid 머신의 Docker(또는 Docker Compose), 또는 로컬 개발용 Python 3.12 +
uv.PATH에 있는
ripgrep(컨테이너 이미지에는 포함되어 있으며, 로컬 개발용으로는 별도 설치).
구성
모든 구성은 환경 변수를 통해 이루어집니다. 특정 볼트에 관한 어떤 것(경로, 이름, 토큰)도 하드코딩되어 있지 않으므로, 같은 이미지로 여러 개의 형제 볼트를 각각 별도 컨테이너로 서빙할 수 있습니다.
변수 | 필수 | 기본값 | 의미 |
| 예 | — | 컨테이너 내 볼트 루트의 절대 경로 |
| 예 | — | 인스턴스 이름(예: |
| 예 | — | 모든 MCP 요청에 필요한 Bearer 토큰 |
| 아니요 |
| 수신 포트 |
| 아니요 |
| 수신 주소 |
| 아니요 |
|
|
.env.example을 .env로 복사하고 Compose를 실행하기 전에 BRAIN_NAME, BRAIN_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-mcpUnraid에서 실행
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 앱으로 설치
다른 앱과 마찬가지로 Unraid의 Docker 탭에서 관리하고 싶다면 — .env를 편집하는 대신 양식을 쓰고, 이후 Start/Stop/Update 버튼을 쓰는 방식 — unraid/brain-mcp.xml에 해당 템플릿이 있습니다. .github/workflows/publish.yml은 main에 푸시할 때마다 이 저장소의 이미지를 빌드해 GHCR(ghcr.io/sipho102/brain-mcp:latest)에 게시하며, 템플릿은 그 이미지를 직접 가져옵니다. Unraid 머신에서 클론이나 빌드가 전혀 필요하지 않습니다.
템플릿을 Unraid에서 사용할 수 있게 만드는 방법:
권장 — Docker 탭에서 Add Container를 클릭하고 이 저장소의 raw 템플릿 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 → template 드롭다운에 표시됩니다. 다만 Add Container 바로 다음에 있는, 컨테이너가 생성되면 이 파일을 삭제하라는 참고 사항을 확인하세요.
어느 쪽이든 볼트 경로, 인박스 경로(<vault path>/00-inbox여야 함 — 템플릿이 자동으로 유도해 주지 못함), 인스턴스 이름, Bearer 토큰을 위한 양식이 제공됩니다. 나머지는 "advanced view"에서 합리적인 기본값으로 미리 채워져 있습니다.
위의 로컬 복사 방식을 사용했다면, 컨테이너가 추가된 후 해당 시드 파일을 삭제하세요:
rm /boot/config/plugins/dockerMan/templates-user/brain-mcp.xmlAdd 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_NAME, BRAIN_VAULT_PATH, BRAIN_TOKEN, PORT를 채운 다음 그곳에서도 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에는 --header로 설정한 헤더가 세션 수립 중에 전송되지 않는 버그가 반복적으로 있었습니다. 같은 토큰을 사용하는 curl은 정상 작동하는데도 401이 발생했습니다. 이 문제가 발생하면 headers 객체를 JSON 구성에 직접 작성하세요(~/.claude/mcp_servers.json 또는 해당 스코프 파일):
{
"mcpServers": {
"brain": {
"type": "http",
"url": "http://<unraid-host>:3100/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}(type은 JSON 구성에서 http의 별칭으로 streamable-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 클라이언트 UI는 이름, transport, 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)— frontmatter 필터링이 포함된 전체 텍스트 검색(ripgrep). 메타데이터와 ~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 문서 가져오기 없음(클라이언트가 별도의 paperless MCP 서버로 연결할 수 있도록 frontmatter에서 문서 ID를 반환할 뿐), 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