Obsidian β Atomic Notes β Knowledge Graph β MCP Server
κ°μΈ μ§μμ Knowledge Graphλ‘ λ³ννκ³ AI λꡬμμ νμ©
- β Obsidian λ ΈνΈ μλ λΆν΄ - λ¨μΌ κ°λ λ¨μλ‘ Atomic Notes μμ± (Gemini AI)
- β Entity & Relationship μΆμΆ - AI + Regex κΈ°λ° μ§μ κ·Έλν ꡬμ±
- β Neo4j Knowledge Graph - κ°λ ₯ν κ·Έλν 쿼리 λ° μκ°ν
- β MCP Server - Claude Desktop, Cursor λ± AI λꡬμ μ°λ
- β Raw Data μ 곡 - Reasoningμ Claude/Cursorκ° μ§μ μν
# 1. uv μ€μΉ
curl -LsSf https://astral.sh/uv/install.sh | sh
# 2. μμ‘΄μ± μ€μΉ
cd PKM
uv sync
# 3. Neo4j μμ
docker-compose up -d
# 4. νκ²½ λ³μ μ€μ
cp .env.example .env
# .env νμΌμ GEMINI_API_KEY μ
λ ₯
# 5. Knowledge Graph κ΅¬μΆ (Stage 1-3)
./quick_start.sh
# β μ΅μ
4 μ ν (μ 체 νμ΄νλΌμΈ)
# 6. MCP Server μ€μ
# Claude Desktopμμ μ¬μ© (docs/MCP_SERVER_SETUP.md μ°Έκ³ )π uv λΉ λ₯Έ μμ κ°μ΄λ - 5λΆ λ§μ μλ£!
# 1. κ°μνκ²½ λ° μμ‘΄μ± μ€μΉ
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# 2. Neo4j μμ
docker-compose up -d
# 3. νκ²½ λ³μ μ€μ
cp .env.example .env
# 4. Knowledge Graph ꡬμΆ
./quick_start.shπ Obsidian Vault (Your Notes)
β
ββ Markdown files with frontmatter, links, tags
β
βΌ
βββββββββββββββββββββββ
β Stage 1: Atomic β β Gemini 2.5-flash
β Note Agent β
βββββββββββββββββββββββ
β
ββ atomic_notes/*.json
β
βΌ
βββββββββββββββββββββββ
β Stage 2: Entity & β β Regex + Gemini
β Relationship β Enhancement
βββββββββββββββββββββββ
β
ββ *_enhanced.json
β
βΌ
βββββββββββββββββββββββ
β Stage 3: Neo4j β β Neo4j 5.14.0
β Graph DB Import β (Docker)
βββββββββββββββββββββββ
β
β Cypher Queries (Raw Data)
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Neo4j Knowledge Graph β
β β
β Nodes: AtomicNote, Entity β
β Relationships: MENTIONS, SUPPORTS β
β USES, CAUSES, etc. β
ββββββββββββββββββββββββββββββββββββββββ
β
β Raw Data (JSON)
βΌ
βββββββββββββββββββββββββββββββββββββββ
β MCP Server (FastMCP) β
β β
β 6 Tools: β
β β’ search_entities β
β β’ get_entity_graph β
β β’ find_related_notes β
β β’ find_entity_path β
β β’ get_graph_stats β
β β’ run_cypher_query β
βββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββ¬βββββββββββββββ
β β β
βΌ βΌ βΌ
Claude Cursor VS Code
Desktop + Continue
β β β
βββββββββββββββ΄βββββββββββββββ
Reasoningμ LLMμ΄ μ§μ !
| Stage | κΈ°λ₯ | μν | μ€λͺ |
|---|---|---|---|
| 1 | Atomic Notes μμ± | β μλ£ | Obsidian λ ΈνΈλ₯Ό λ¨μΌ κ°λ μΌλ‘ λΆν΄ |
| 2 | Entity & Relationship μΆμΆ | β μλ£ | AI κΈ°λ° μν°ν° λ° κ΄κ³ μΆμΆ |
| 3 | Neo4j Graph DB κ΅¬μΆ | β μλ£ | Knowledge Graphλ‘ λ³ν |
| MCP | MCP Server | β μλ£ | Raw Data μ 곡, Reasoningμ LLM |
κΈ°μ‘΄ (μλͺ»λ μ κ·Ό):
User β Claude β MCP β Gemini API (Reasoning) β Raw Data β Claude
β μ΄μ€ LLM λΉμ©, ν¬λͺ
μ± λΆμ‘±
νμ¬ (μ¬λ°λ₯Έ μ κ·Ό):
User β Claude β MCP β Raw Data from Neo4j β Claude (Reasoning)
β
λΉμ© μ κ°, ν¬λͺ
μ±, Claude λ₯λ ₯ μ΅λ νμ©
μ₯μ :
- π° λΉμ© μ κ°: Gemini API λΆνμ, Claudeλ§ μ¬μ©
- π ν¬λͺ μ±: Claudeκ° μ΄λ€ λ°μ΄ν°λ₯Ό μ¬μ©νλμ§ λͺ ν
- π§ λ λμ Reasoning: Claudeκ° raw dataλ‘ λ κΉμ λΆμ
- π μ μ°μ±: μ¬μ©μκ° μνλ λꡬ μ‘°ν© κ°λ₯
| κ³μΈ΅ | κΈ°μ | μ©λ |
|---|---|---|
| Input | Obsidian, Markdown | λ ΈνΈ μμ± λ° κ΄λ¦¬ |
| LLM | Google Gemini 2.5-flash | Atomic λΆν΄, Entity μΆμΆλ§ |
| Database | Neo4j 5.14.0 (Docker) | Knowledge Graph μ μ₯ |
| Backend | Python 3.10+ | λ°μ΄ν° μ²λ¦¬ |
| Graph Query | Cypher | Graph νμ λ° μΏΌλ¦¬ |
| MCP Framework | FastMCP | MCP μλ² κ΅¬ν |
| Reasoning | Claude / Cursor / etc. | LLMμ΄ μ§μ Reasoning |
| Container | Docker Compose | Neo4j 격리 λ° λ°°ν¬ |
| Package Manager | uv (κΆμ₯) / pip | Python μμ‘΄μ± κ΄λ¦¬ |
PKM μμ€ν μ Zettelkasten λ°©λ²λ‘ μ λ°λ¦ λλ€:
- λ¨μΌ μ± μ (Single Responsibility) - νλμ κ°λ /μμ΄λμ΄λ§ ν¬ν¨
- λ λ¦½μ± (Independence) - λ 립μ μΌλ‘ μ΄ν΄ κ°λ₯
- μ°κ²°μ± (Connectivity) - λ€λ₯Έ λ ΈνΈμ λ§ν¬ κ°λ₯
- ꡬ쑰ν (Structure) - λͺ νν λ©νλ°μ΄ν° ν¬ν¨
PKM/
βββ src/ # ν΅μ¬ μμ€ μ½λ
β βββ obsidian_loader.py # Obsidian Vault λ‘λ
β βββ atomic_note_agent.py # Stage 1: Atomic Notes
β βββ entity_extraction_simple.py # Stage 2: Entity Extraction
β βββ graph_db.py # Stage 3: Neo4j Manager
β
βββ tests/ # ν
μ€νΈ μ€ν¬λ¦½νΈ
β βββ test_atomic_agent.py # Stage 1 ν
μ€νΈ
β βββ test_entity_extraction.py # Stage 2 ν
μ€νΈ
β βββ test_graph_import.py # Stage 3 ν
μ€νΈ
β βββ regenerate_markdown.py # Markdown μ¬μμ±
β
βββ docs/ # λ¬Έμ
β βββ INSTALLATION.md # μ€μΉ κ°μ΄λ
β βββ USAGE_GUIDE.md # μ¬μ© κ°μ΄λ
β βββ QUICKSTART_UV.md # uv λΉ λ₯Έ μμ
β βββ QUICKSTART_DOCKER.md # Docker λΉ λ₯Έ μμ
β βββ MCP_SERVER_SETUP.md # MCP μλ² μ€μ
β βββ DOCKER_SETUP.md # Docker μμΈ κ°μ΄λ
β βββ UV_SETUP.md # uv μμΈ κ°μ΄λ
β βββ Obsidian-to-GraphDB-Implementation.md # ꡬν κ°μ΄λ
β
βββ scripts/ # μ νΈλ¦¬ν° μ€ν¬λ¦½νΈ
β βββ start_neo4j.sh # Neo4j μμ
β βββ stop_neo4j.sh # Neo4j μ€μ§
β
βββ mcp_server.py # MCP Server (FastMCP)
βββ quick_start.sh # Quick Start μ€ν¬λ¦½νΈ
βββ docker-compose.yml # Neo4j Docker μ€μ
βββ pyproject.toml # uv νλ‘μ νΈ μ€μ
βββ requirements.txt # pip μμ‘΄μ±
βββ .env.example # νκ²½ λ³μ μμ
βββ README.md # μ΄ νμΌ
- π μ€μΉ κ°μ΄λ - μ²μλΆν° μ€μΉνκΈ°
- π μ¬μ© κ°μ΄λ - Stage 1-3 μμΈ μ¬μ©λ²
- β‘ uv λΉ λ₯Έ μμ - 5λΆ λ§μ μμνκΈ°
- π³ Docker λΉ λ₯Έ μμ - Dockerλ‘ 3λΆ λ§μ μμνκΈ°
- π MCP Server μ€μ - Claude Desktop / Cursor μ°λ
- π³ Docker κ°μ΄λ - Neo4j Docker κ΄λ¦¬
- β‘ uv κ°μ΄λ - uv κ³ κΈ μ¬μ©λ²
- π μ 체 ꡬν κ°μ΄λ - νλ‘μ νΈ μ€κ³ λ° κ΅¬ν μΈλΆμ¬ν
λ¬΄λ£ ν°μ΄:
- 15 RPM (λΆλΉ μμ²)
- 1,500 RPD (μΌμΌ μμ²)
- 1 Million TPM (λΆλΉ ν ν°)
μμ λΉμ© (λ¬΄λ£ ν°μ΄ μ΄κ³Ό μ):
- μ§§μ λ ΈνΈ (1000μ): ~$0.001-0.002
- κΈ΄ λ ΈνΈ (5000μ): ~$0.005-0.01
- μ 체 Vault (10κ° λ ΈνΈ): ~$0.05-0.10
λ¬΄λ£ ν°μ΄:
- μΆ©λΆν μ¬μ©λ μ 곡
μ₯μ :
- β MCP μλ²λ Gemini API λΆνμ (Graph DBμμ raw dataλ§ μ 곡)
- β Reasoningμ Claudeκ° λ¬΄λ£λ‘ μ²λ¦¬
- β μ 체 λΉμ© = Stage 1-2 μ²λ¦¬ λΉμ©λ§
- πΎ 무λ£: Community Edition μ¬μ©
- π¦ λ‘컬 μ€ν: ν΄λΌμ°λ λΉμ© μμ
- π λ°μ΄ν° μμ κΆ: λͺ¨λ λ°μ΄ν°κ° λ‘컬μ μ μ₯
PKM μμ€ν μ Claude Desktop, Cursor λ±μμ μ¬μ©ν μ μμ΅λλ€!
search_entities- κ°λ (Entity) κ²μget_entity_graph- νΉμ κ°λ μ£Όλ³ κ·Έλνfind_related_notes- κ΄λ ¨ Atomic Notes μ°ΎκΈ°find_entity_path- λ κ°λ κ° μ°κ²° κ²½λ‘get_graph_stats- Knowledge Graph ν΅κ³run_cypher_query- μ¬μ©μ μ μ Cypher 쿼리
# 1. Knowledge Graph κ΅¬μΆ (Stage 1-3)
./quick_start.sh
# 2. MCP Server ν
μ€νΈ
uv run python mcp_server.py
# 3. Gemini CLI μ μ μ€μ νμΈ
# μ μ μ€μ νμΌμ PKM MCP μλ²κ° μ΄λ―Έ μΆκ°λμ΄ μμ΅λλ€
cat ~/.gemini/settings.jsonμ μ μ€μ νμΌ μμΉ:
~/.gemini/settings.json(ν λλ ν 리)
μ€μ μμ:
{
"mcpServers": {
"pkm-knowledge-graph": {
"command": "/opt/homebrew/bin/uv",
"args": ["run", "python", "mcp_server.py"],
"cwd": "/Users/inyoungpark/Desktop/Projects/personal/PKM",
"env": {
"GEMINI_API_KEY": "your-key",
"GEMINI_MODEL": "gemini-2.5-flash",
"NEO4J_URI": "neo4j://127.0.0.1:7687",
"NEO4J_USER": "neo4j",
"NEO4J_PASSWORD": "password"
}
}
}
}π MCP Server μ€μ κ°μ΄λ - μμΈν μ€μ λ°©λ²
π€ User: AIμ λ¨Έμ λ¬λμ΄ μ΄λ»κ² μ°κ²°λμ΄ μλμ§ μλ €μ€
π€ Gemini:
[search_entities λꡬ μ¬μ©]
[find_entity_path λꡬ μ¬μ©]
[find_related_notes λꡬ μ¬μ©]
AIμ λ¨Έμ λ¬λμ λ€μκ³Ό κ°μ΄ μ°κ²°λμ΄ μμ΅λλ€:
κ²½λ‘ 1: AI β is_parent_of β λ¨Έμ λ¬λ
κ²½λ‘ 2: AI β includes β λ₯λ¬λ β is_part_of β λ¨Έμ λ¬λ
λΉμ μ λ
ΈνΈμ λ°λ₯΄λ©΄...
[raw dataλ₯Ό κΈ°λ°μΌλ‘ Claudeκ° μ§μ reasoning]
Q: Neo4j μ°κ²° μ€ν¨
# Docker μν νμΈ
docker-compose ps
# Neo4j μ¬μμ
docker-compose restart neo4j
# λ‘κ·Έ νμΈ
docker-compose logs neo4jQ: uv: command not found
# PATH μΆκ°
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc
source ~/.zshrcQ: MCP Serverκ° Claudeμμ 보μ΄μ§ μμ
# 1. Neo4j μ€ν νμΈ
docker-compose ps
# 2. MCP μλ² μλ ν
μ€νΈ
uv run python mcp_server.py
# 3. Claude Desktop λ‘κ·Έ νμΈ (Cmd+Option+I)λ λ§μ λ¬Έμ ν΄κ²° λ°©λ²μ **μ€μΉ κ°μ΄λ**λ₯Ό μ°Έκ³ νμΈμ.
.gitignoreμ λ€μμ΄ μλμΌλ‘ μ μΈλ©λλ€:
.env- API ν€atomic_notes/- μμ±λ Atomic Notesatomic_notes_md/- μμ±λ Markdown.venv/,venv/- Python κ°μνκ²½neo4j/data/- Neo4j λ°μ΄ν°λ² μ΄μ€mcp_config.json- λ‘컬 MCP μ€μ
νμ¬ μλ£:
- β Stage 1-3: Knowledge Graph ꡬμΆ
- β MCP Server: Raw Data μ 곡
- β Claude/Cursor μ°λ
ν₯ν κ³ν:
- π Vector Search ν΅ν© - Semantic Search κ°ν
- π Web Interface - μκ°μ Graph νμ
- π Real-time Sync - Obsidian β Neo4j μλ°©ν₯ λκΈ°ν
- π Multi-Vault μ§μ - μ¬λ¬ Obsidian Vault ν΅ν©
MIT License
- Obsidian - κ°λ ₯ν λ ΈνΈ μμ± λꡬ
- Neo4j - λ°μ΄λ Graph Database
- Google Gemini - κ³ νμ§ LLM API
- FastMCP - κ°νΈν MCP μλ² νλ μμν¬
- uv - μ΄κ³ μ Python ν¨ν€μ§ κ΄λ¦¬μ
- Anthropic Claude - MCPμ ν¨κ»νλ μ΅κ³ μ AI Assistant
Made with β€οΈ for Personal Knowledge Management
MCP μ² ν: Raw Data Provider, Reasoningμ LLMμκ²