MCP 서버 심화
MCP(Model Context Protocol)의 개념을 이해하고 고급 설정과 트러블슈팅 방법을 배웁니다.
개요
MCP는 AI 모델이 외부 도구와 상호작용할 수 있게 해주는 프로토콜입니다. 이 가이드에서는 MCP의 작동 원리와 Obsidian MCP 서버의 고급 기능을 다룹니다.
학습 목표
- MCP의 작동 원리 이해
- MCP 서버의 고급 설정
- 여러 MCP 서버 함께 사용
- 성능 최적화
MCP란 무엇인가?
기본 개념
MCP (Model Context Protocol)는 AI 모델이 외부 리소스에 접근하고 작업을 수행할 수 있게 해주는 표준 프로토콜입니다.
sequenceDiagram
participant User as 사용자
participant Claude as Claude Code
participant MCP as MCP Server
participant Obsidian as Obsidian
User->>Claude: "노트 목록 보여줘"
Claude->>MCP: list_notes 요청
MCP->>Obsidian: REST API 호출
Obsidian-->>MCP: 노트 목록 반환
MCP-->>Claude: 파싱된 데이터
Claude-->>User: "현재 23개의 노트가 있어요"
MCP의 핵심 구성 요소
| 구성 요소 | 설명 | 예시 |
|---|---|---|
| Server | 외부 리소스와 AI를 연결 | Obsidian MCP Server |
| Tools | AI가 호출할 수 있는 기능 | read_note, search, create_note |
| Resources | AI가 읽을 수 있는 데이터 | 노트 내용, 메타데이터 |
| Prompts | 재사용 가능한 프롬프트 템플릿 | “트러블슈팅 문서화” |
MCP 아키텍처
1단계: 클라이언트-서버 통신
graph TB
subgraph "Claude Code"
A[MCP Client]
end
subgraph "MCP Servers"
B[Obsidian MCP]
C[GitHub MCP]
D[Web Search MCP]
end
subgraph "External Resources"
E[Obsidian Vault]
F[GitHub Repos]
G[Search Engines]
end
A -->|stdio| B
A -->|stdio| C
A -->|stdio| D
B --> E
C --> F
D --> G
style A fill:#e1f5ff
style B fill:#90EE90
style C fill:#FFB6C1
style D fill:#DDA0DD
2단계: 메시지 교환
MCP는 stdin/stdout을 통해 JSON-RPC 형식의 메시지를 교환합니다.
// 요청 예시
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "obsidian_read_note",
"arguments": {
"path": "Projects/study/redis.md"
}
}
}
// 응답 예시
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": "# Redis 공부\n\n...",
"metadata": {
"created": "2025-01-10",
"tags": ["study", "redis"]
}
}
}
Obsidian MCP 서버 상세
사용 가능한 도구(Tools)
| 도구 이름 | 설명 | 사용 예시 |
|---|---|---|
obsidian_read_note | 노트 내용 읽기 | “Redis 노트 읽어줘” |
obsidian_create_note | 새 노트 생성 | “트러블슈팅 문서 만들어줘” |
obsidian_update_note | 기존 노트 수정 | “이 노트에 내용 추가해줘” |
obsidian_delete_note | 노트 삭제 | “이 테스트 노트 삭제해줘” |
obsidian_search | 노트 검색 | “Kafka 관련 노트 찾아줘” |
obsidian_list_notes | 노트 목록 | “최근 노트들 보여줘” |
obsidian_get_graph | 백링크 그래프 | “이 노트와 연결된 것들 보여줘” |
실제 사용 예시
1. 노트 읽기
사용자: "Projects/study/redis.md 노트를 읽어줘"
Claude의 내부 동작:
1. obsidian_read_note 도구 호출
2. 경로: Projects/study/redis.md
3. 내용 반환 및 요약
2. 노트 검색
사용자: "Redis 관련된 모든 노트를 찾아줘"
Claude의 내부 동작:
1. obsidian_search 도구 호출
2. 검색어: "redis"
3. 결과:
- Projects/study/redis.md
- Troubleshooting/redis-timeout.md
- Clippings/redis-best-practices.md
3. 노트 생성
사용자: "오늘 발생한 에러를 문서화해줘"
Claude의 내부 동작:
1. obsidian_create_note 도구 호출
2. 템플릿 적용
3. 사용자 입력 내용 정리
4. Troubleshooting/ 폴더에 저장
여러 MCP 서버 함께 사용
설정 예시
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["-y", "obsidian-mcp-server"],
"env": {
"OBSIDIAN_VAULT_PATH": "/Users/jonginkim/Documents/mynote",
"OBSIDIAN_REST_API_PORT": "27123",
"OBSIDIAN_API_KEY": "your-api-key"
}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "your-github-token"
}
},
"web-search": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-brave-search"],
"env": {
"BRAVE_API_KEY": "your-brave-api-key"
}
}
}
}
함께 사용하는 예시
사용자: "최근 GitHub 이슈를 검색해서 Obsidian에 정리해줘"
Claude의 동작:
1. web-search 서버로 GitHub 이슈 검색
2. obsidian 서버로 결과 정리 및 노트 생성
3. 두 서버의 데이터 결합
sequenceDiagram
participant User as 사용자
participant Claude as Claude Code
participant Web as Web Search MCP
participant Obs as Obsidian MCP
User->>Claude: "GitHub 이슈 검색해서 정리해줘"
Claude->>Web: search("GitHub Redis timeout")
Web-->>Claude: 검색 결과
Claude->>Obs: create_note(검색 결과)
Obs-->>Claude: 노트 생성 완료
Claude-->>User: "3개의 이슈를 정리했습니다"
성능 최적화
1. Vault 크기 관리
대용량 Vault의 경우 검색 속도가 느려질 수 있습니다.
graph LR
A[Vault 크기] --> B{1000노트 미만?}
B -- 예 --> C[기본 설정]
B -- 아니요 --> D[최적화 필요]
D --> E[폴더별 MCP 서버]
D --> F[인덱싱 최적화]
D --> G[불필요한 노트 정리]
최적화 팁
| 문제 | 해결 방법 |
|---|---|
| 검색이 느림 | Dataview 인덱스 재구성 |
| 메모리 사용량 높음 | Vault 분리 또는 MCP 서버 재시작 |
| 파일 동기화 지연 | Git LFS 고려 |
2. 캐싱 전략
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["-y", "obsidian-mcp-server"],
"env": {
"OBSIDIAN_VAULT_PATH": "/path/to/vault",
"CACHE_ENABLED": "true",
"CACHE_TTL": "300"
}
}
}
}
3. 동시 요청 처리
여러 MCP 서버를 병렬로 호출할 수 있습니다.
사용자: "GitHub 이슈와 내 노트를 함께 검색해줘"
Claude는 병렬로:
1. GitHub MCP → 이슈 검색
2. Obsidian MCP → 관련 노트 검색
→ 두 결과를 결합하여 응답
고급 기능
1. 커스텀 프롬프트
재사용 가능한 프롬프트를 정의할 수 있습니다.
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["-y", "obsidian-mcp-server"],
"prompts": {
"troubleshooting": {
"description": "트러블슈팅 문서를 생성합니다",
"arguments": [
{
"name": "error_log",
"description": "에러 로그",
"required": true
},
{
"name": "solution",
"description": "해결책",
"required": true
}
]
}
}
}
}
}
2. 워크플로우 자동화
사용자: "/troubleshoot 에러로그와 해결책"
Claude가 자동으로:
1. Troubleshooting 폴더 확인
2. 템플릿 적용
3. 관련 노트 검색
4. 백링크 생성
5. 일일 노트에 링크 추가
3. 이벤트 기반 트리거
// Obsidian 스크립트 예시
// 노트가 수정될 때 자동으로 Claude에게 전송
const { obsidian } = app.plugins.plugins['obsidian-local-rest-api'];
app.vault.on('modify', (file) => {
if (file.extension === 'md') {
// Claude에게 알림
notifyClaude({
type: 'note_modified',
path: file.path,
content: await app.vault.read(file)
});
}
});
트러블슈팅
문제 1: MCP 서버가 응답하지 않음
증상
Claude가 계속 "thinking..." 상태
진단
# MCP 서버 로그 확인
DEBUG=* claude
# 또는
claude --verbose
해결 방법
- MCP 서버 재시작
- Obsidian 재시작
- 포트 충돌 확인
# 포트 확인
lsof -i :27123
# 프로세스 종료
kill -9 <PID>
문제 2: 한글 깨짐
증상
노트 내용의 한글이 깨져서 보임
해결 방법
{
"mcpServers": {
"obsidian": {
"env": {
"ENCODING": "UTF-8"
}
}
}
}
문제 3: 대용량 파일 처리 실패
증상
큰 노트를 읽을 때 타임아웃
해결 방법
{
"mcpServers": {
"obsidian": {
"env": {
"MAX_FILE_SIZE": "10485760",
"TIMEOUT": "30000"
}
}
}
}
실습 과제
- MCP 로그를 확인하여 Claude와 Obsidian 간의 통신 이해하기
- 여러 MCP 서버 설정하고 함께 사용해보기
- 커스텀 프롬프트 정의해보기
- 성능 모니터링하고 최적화하기
참고 자료
다음 단계
MCP를 이해했으니, 실제로 노트를 작성해봅시다.
| → [[04-first-steps | 첫 노트 작성하기]]로 계속하세요 |