obsidian-local-mcp-server
Provides tools for searching, reading, browsing, linking, and writing notes in an Obsidian vault, including access to backlinks, tags, and video sources.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@obsidian-local-mcp-serversearch my vault for notes about MCP"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
obsidian-local-mcp-server
Obsidian vault를 MCP 서버로 노출해 Claude Code와 Codex에서 언제든 검색·조회·편집할 수 있게 한다. 서버는 Docker 컨테이너로 돌고, vault는 호스트 폴더를 볼륨으로 마운트한다.
MCP 2026-07-28 명세(Stateless HTTP)를 구현했다. 세션도 initialize 핸드셰이크도 없이
요청 하나하나가 독립적으로 완결되므로, 컨테이너 한 대에 여러 클라이언트가 자유롭게 붙는다.
호스트 Docker
┌──────────────┐
│ Claude Code │──┐
├──────────────┤ │ 127.0.0.1:8787 ┌─────────────────────────┐
│ Codex │──┼──────────────────▶│ obsidian-mcp (non-root) │
├──────────────┤ │ Stateless HTTP │ Stateless HTTP :8787 │
│ 그 외 MCP │──┘ └───────────┬─────────────┘
│ 클라이언트 │ │ volume
└──────────────┘ ▼
┌───────────────────────────┐
│ 호스트의 Obsidian vault │
│ (VAULT_PATH → /vault) │
└───────────────────────────┘1. 빠른 시작
git clone <이 저장소>
cd obsidian-local-mcp-server
cp .env.example .env # vault 경로를 여기서 지정한다 (2절 참고)
npm run up # 이미지 빌드 + 컨테이너 기동
npm run health # {"ok":true,"notes":652,"vault":"/vault"}그다음 클라이언트를 붙인다.
# Claude Code (모든 프로젝트에서 사용)
claude mcp add --transport http --scope user obsidian-vault http://127.0.0.1:8787/mcp
# Codex
codex mcp add obsidian-vault --url http://127.0.0.1:8787/mcp두 클라이언트 모두 새 세션부터 도구가 보인다. MCP 서버 목록은 세션 시작 시 로드된다.
Related MCP server: Recalla
2. 최초 vault 폴더 등록
vault 경로는 .env의 VAULT_PATH 하나로 정해진다. 이미지에 노트를 굽지 않고
호스트 폴더를 그대로 마운트하므로, Obsidian에서 고친 내용이 즉시 서버에 보이고
MCP 쓰기 도구의 결과도 호스트 파일에 그대로 남는다.
cp .env.example .env.env를 열어 세 값을 채운다.
# 연결할 Obsidian vault의 절대경로 (필수)
VAULT_PATH=/Users/iron/Project/ai-docs/vault
# 호스트에 노출할 포트 (기본 8787)
MCP_PORT=8787
# 마운트된 vault를 읽고 쓰려면 호스트 사용자와 UID를 맞춰야 한다
UID=501
GID=20UID/GID는 아래로 확인한다. 이 값이 틀리면 읽기는 되는데 쓰기 도구만 권한 오류가 난다.
echo "UID=$(id -u)"
echo "GID=$(id -g)"경로를 바꿨으면 컨테이너를 다시 만든다. restart가 아니라 up이어야 마운트가 새로 잡힌다.
npm run down && npm run up
npm run health # notes 개수로 새 vault가 잡혔는지 확인vault를 여러 개 쓰려면
.env의MCP_PORT를 다르게 준 복사본으로 컨테이너를 하나 더 띄우고, 클라이언트에 다른 이름으로 등록하면 된다.
3. 서버 실행 방법
평소 운영 (Docker Compose)
npm run up # 빌드 + 기동 (docker compose up -d --build)
npm run down # 중지 및 컨테이너 제거
npm run restart # 재시작 (코드 변경은 반영되지 않는다 — up을 써야 한다)
npm run logs # 로그 추적
npm run health # 상태 확인
docker compose ps # 컨테이너 상태 (healthy 여부)restart: unless-stopped 정책이라 Docker Desktop이 켜지면 컨테이너도 함께 올라온다.
직접 npm run down으로 내리기 전까지는 계속 살아 있다.
코드를 고쳤다면 npm run up으로 다시 빌드해야 반영된다. restart는 이미지가 아니라
컨테이너만 다시 띄우므로 옛 코드가 그대로 돈다.
stdio로 붙이고 싶다면
HTTP 대신 클라이언트가 컨테이너를 직접 띄우는 방식도 지원한다. 상시 데몬이 필요 없는 대신 호출 때마다 컨테이너가 새로 뜬다.
claude mcp add --scope user obsidian-vault -- \
docker run -i --rm -v /Users/iron/Project/ai-docs/vault:/vault \
-e OBSIDIAN_VAULT=/vault obsidian-vault-mcp:latest node dist/stdio.jsDocker 없이 (개발용)
npm ci && npm run build
node dist/http.js # http://127.0.0.1:8787/mcp
node dist/stdio.js # stdio4. 아키텍처와 프로토콜
프로토콜: MCP 2026-07-28 Stateless
@modelcontextprotocol/server v2로 구현했다. 이 개정판의 핵심은 세션 제거다.
항목 | 2025 이전 | 2026-07-28 |
연결 개시 |
| 없음 — 요청이 스스로 완결 |
세션 |
| 제거 |
능력 확인 | 핸드셰이크에서 1회 |
|
서버 상태 | 세션에 암묵적으로 보관 | 명시적 핸들을 인자로 전달 |
요청은 이런 모양이 된다.
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: vault_searchMcp-Method와 Mcp-Name이 헤더로 올라와, 게이트웨이가 본문을 파싱하지 않고도
라우팅·인가·레이트리밋을 걸 수 있다.
이 설계가 컨테이너와 잘 맞는 이유는 서버가 요청 사이에 아무것도 기억하지 않기 때문이다. Claude Code와 Codex가 같은 컨테이너에 동시에 붙어도 서로 간섭하지 않고, 컨테이너를 재시작해도 클라이언트가 세션을 잃지 않는다.
한 factory가 두 전송을 덮는다
buildServer(index) ← 도구 정의는 여기 한 곳뿐
╱ ╲
serveStdio(factory) createMcpHandler(factory)
│ │
stdio Stateless HTTP
(docker run -i) (docker compose, :8787)src/server.ts의 factory 하나를 두 진입점이 공유하므로 전송별로 도구가 갈라질 수 없다.
2025 era 클라이언트가 붙으면 SDK가 stateless fallback으로 알아서 받아준다.
레이어
파일 | 역할 |
| vault 인덱스 · 파싱 · 검색 · 링크 그래프 · 경로 보안 |
| MCP 서버 factory (도구 8개). 인덱스를 주입받는다 |
| stdio 진입점 |
| Stateless HTTP 진입점 + Host/Origin 검증 + |
buildServer(index)가 인덱스를 주입받는 구조라서 테스트가 임시 vault를 꽂아 넣을 수 있다.
모듈 전역 인덱스였다면 도구 테스트가 실제 vault를 건드려야 했을 것이다.
인덱싱
652파일 0.8MB 전체 스캔이 ~150ms라 역색인을 유지할 이유가 없다. 통째로 메모리에 올리고,
TTL 5초로 외부 변경(Obsidian에서 직접 편집한 것)을 따라잡는다. 쓰기 도구는 즉시
invalidate()하므로 방금 쓴 노트가 다음 검색에 바로 잡힌다.
보안
명세는 두 가지를 요구한다: Origin 헤더 검증 후 403, 그리고 로컬 배포는 localhost에만 바인드.
createMcpHandler는 의도적으로 검증을 하지 않으므로src/http.ts가 앞단에서 Host/Origin을 확인하고 403을 낸다. 이게 없으면 사용자가 열어둔 아무 웹페이지나localhost:8787로 요청을 보내 vault를 읽고 쓸 수 있다(DNS rebinding).컨테이너 내부는
0.0.0.0에 바인드할 수밖에 없다(그래야 포트 매핑이 닿는다). 루프백 제한은 호스트 매핑127.0.0.1:8787:8787이 담당한다. compose에서 앞의127.0.0.1을 빼면 같은 네트워크의 누구나 vault를 편집할 수 있게 되므로 빼지 말 것.컨테이너는 non-root로 돈다. 쓰기 경로는 전부
safePath()를 통과해 vault 밖(../, 절대경로)과 숨김 경로를 막는다.
5. MCP 주요 기능 — 도구 8개
읽기
도구 | 하는 일 | 주요 인자 |
| 제목·별칭·태그·본문을 가중치로 채점해 검색 |
|
| 노트 전문 읽기 + 연결 관계 동봉 |
|
| 백링크(참조하는 노트) / 아웃링크(참조되는 노트) |
|
| 전체 개요, 태그별·타입별 목록, 주제 맵(MOC) 열기 |
|
| 개념 → 강의 유튜브 타임스탬프 링크 |
|
ref는 제목·별칭·경로 아무거나 받는다. "환경 변수", "env", ".env",
"10-Concepts/환경 변수.md"가 모두 같은 노트로 해석된다.
검색 점수는 제목 정확일치(100) > 별칭 정확일치(80) > 제목 부분일치(50) > 별칭 부분일치(30) > 태그(25) > 본문 빈도(최대 20) 순으로 쌓인다.
vault_sources는 개념 노트의 sources frontmatter를 읽어 강의 영상의 해당 지점으로
바로 가는 링크를 만든다.
**그래프 엔지니어링** 강의 출처 3건
- [13:39] **Loop와 Graph는 무엇이 다른가?**
https://youtu.be/I_c8R_PckJ8?t=819
영상 노트: `20-Videos/2026-08-31 암묵지 자산화를 위한 딥트윈 에이전트의 전체 원리와 설계 프로세스.md`쓰기
도구 | 하는 일 | 안전장치 |
| 노트 생성/덮어쓰기 | 기존 노트는 |
| 기존 노트에 섹션 추가 | 기존 내용을 지우지 않는다 |
| 노트 간 위키링크 | 이미 있으면 아무것도 바꾸지 않는다 |
도구마다 MCP 어노테이션을 붙여 클라이언트가 위험도를 구분할 수 있게 했다 —
읽기 5개는 readOnlyHint, vault_write는 destructiveHint, vault_link는 idempotentHint.
6. 개발
npm test # 전체 100개 (Docker 통합 포함, 이미지 빌드 수행)
npm run test:unit # Docker 제외 — 빠른 반복용
npm run typecheck
npm run buildTDD로 만들었다. 테스트는 네 층이다.
파일 | 검증 대상 |
| 인덱스 단위 + 실제 vault 통합(위키링크 100% 해석) |
|
|
| 실제 포트 · 실제 프로세스 spawn · Host/Origin 403 |
| 이미지 빌드 · 볼륨 양방향 · non-root · 루프백 · compose 설정 |
Docker 테스트는 데몬이 없으면 자동으로 skip된다. 쓰기 테스트는 전부 임시 vault에서만 돌므로 실제 vault는 건드리지 않는다.
설계 메모
NFC 정규화가 핵심이다. macOS는 한글 파일명을 NFD(자모 분리)로 저장하지만 본문의 위키링크는 NFC다. 정규화 없이는
[[환경 변수]]가 파일에 매칭되지 않는다. 실제 vault의 위키링크 3,990개가 100% 해석되는지를 테스트로 못박아 두었다.safePath()는 선행 슬래시를 벗기지 않는다. 벗기면/etc/hosts가<vault>/etc/hosts.md로 둔갑해 의도와 다른 곳에 쓰인다. 원문 그대로resolve()해서 절대경로가 절대경로로 판정되게 둔다. (TDD로 잡은 버그다.)fetch()로는 Host 헤더를 위조할 수 없다. Node가 금지 헤더로 보고 무시하므로, DNS rebinding 방어를 시험하려면node:httpraw 요청이어야 한다. 이걸 모르고 쓴 첫 테스트는 406을 403으로 착각해 통과하고 있었다.
환경변수
변수 | 기본값 | 설명 |
| — | (compose) 호스트 vault 절대경로. 필수 |
|
| (compose) 호스트에 노출할 포트 |
|
| (compose) 컨테이너 실행 사용자 |
|
| 서버가 읽을 vault 경로 |
|
| 서버 리슨 포트 |
|
| 바인드 주소. 컨테이너에서는 |
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 Connectors
Serve a folder of Markdown notes as an MCP server: hybrid search, reading, and sourced answers.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Markdown-based note-taking with a hosted MCP server. Your notes serve you and your AI.
Google Keep-style notes app with an MCP server for AI agents to read/write notes.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides an MCP server that allows AI assistants to interact with Obsidian vaults, enabling reading/writing notes, managing metadata, searching content, and working with daily notes.37MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to read and search your Obsidian vault through a local MCP server, keeping everything private and local.Apache 2.0
- AlicenseAqualityCmaintenanceEnables MCP-compatible AI hosts to read, search, link, and write notes in a local Obsidian vault with sandboxed file access.11MIT
- 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
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/sangwookp9591/obsidian-local-mcp-server-'
If you have feedback or need assistance with the MCP directory API, please join our Discord server