Advanced MCP server that creates an intelligent, atomic knowledge graph with automatic structuring, semantic understanding, and bidirectional relations - stored as Obsidian-compatible Markdown files.
- Automatic YAML Structuring: Converts text observations into queryable structured properties
- Fractal Decomposition: Complex entities automatically split into atomic components
- Peripheral Concept Extraction: Wikilinks in observations become separate atomic entities
- Zettelkasten Principles: Core entity with essential properties, peripheral concepts as linked atomic notes
- Bidirectional Auto-Generation: Create
A influences.increases Bβ automatically generatesB influenced_by.increased_by A - Semantic Normalization: Uses embeddings to find similar relations (e.g., "blocks.completely" matches "inhibits.competitive" at 92%)
- Property Standardization: Synonym mapping and similarity matching prevent proliferation
- Dendron Link Ontology: Relations stored as
relationType.qualification: ['[[target]]']in YAML frontmatter
- ArticleRank Centrality: Identify influential entities in knowledge graph
- Path Finding: Discover connection chains between entities
- Link Prediction: Suggest missing relations based on graph structure
- Metadata Extraction: Automatic extraction of wikilinks, tags, and structured properties
- Dual Index System: MCP memory + external Obsidian vault
- Vault Integration: Auto-detects and indexes existing Obsidian vaults
- Cross-Vault Search: Query across both MCP-created and vault entities
- Unified Navigation: Seamless access to knowledge across sources
git clone https://github.com/Zpankz/obsidian-memory-mcp.git
cd obsidian-memory-mcp
npm install
npm run buildAdd to Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"obsidian-memory": {
"command": "node",
"args": ["/full/path/to/obsidian-memory-mcp/dist/index.js"],
"env": {
"MEMORY_DIR": "/path/to/your/obsidian/vault/memory"
}
}
}
}Note: The server will auto-detect external Obsidian vaults in common locations (~/Documents/Obsidian, iCloud, etc.)
After configuration, restart Claude Desktop to load the MCP server.
// Simple text observations...
create_entities({
entities: [{
name: "NMDAR",
entityType: "protein",
observations: [
"Tetrameric structure composed of GluN1 and GluN2 subunits",
"Requires glutamate and glycine for activation",
"Conductance: 50 pS",
"Critical for long-term potentiation"
]
}]
})
// ...automatically become structured YAML and atomic entities!What happens automatically:
- YAML Structuring: Observations parsed into structured properties
- Atomic Extraction: Peripheral concepts (GluN1, GluN2, glutamate, glycine, LTP) become separate entities
- File Creation: 6 markdown files created (1 core + 5 atomic)
- Type Inference: Each atomic entity assigned appropriate type (protein_component, molecule, process)
Result - NMDAR.md:
---
entityType: protein
structure:
components:
- GluN1
- GluN2 subunits
activation:
required_ligands:
- glutamate
- glycine
biophysics:
conductance:
value: 50
unit: pS
---
# NMDAR
*Essential structured properties in YAML above. Peripheral concepts as wikilink atomic entities.*Atomic entities created:
GluN1.md,GluN2 subunits.md(protein components)glutamate.md,glycine.md(ligands)long-term potentiation.md(process)
// Create one direction...
create_relations({
relations: [{
from: "dopamine",
to: "reward_processing",
relationType: "influences",
qualification: "increases"
}]
})
// ...get both directions automatically!Result:
# dopamine.md
---
influences.increases:
- '[[reward_processing]]'
---
# reward_processing.md
---
influenced_by.increased_by:
- '[[dopamine]]'
---18 bidirectional rules covering influences, modulates, inhibits, binds, regulates, is_a, part_of, requires, and more.
// Analyze network structure
analyze_graph({
analysis_type: "centrality"
})
// Returns: Top entities by ArticleRank, average degree, clustering metrics
// Find connection paths
analyze_graph({
analysis_type: "paths",
entityName: "dopamine",
targetEntity: "learning"
})
// Returns: Shortest path with intermediate entities and relation types
// Predict missing links
analyze_graph({
analysis_type: "predictions",
entityName: "NMDAR",
options: { topK: 10 }
})
// Returns: Top 10 predicted connections based on graph structure// Search your existing Obsidian vault
query_vault({
query: "neuroscience",
linkToMCP: true
})
// Returns: Vault entities matching query + suggestions for linking to MCP entities---
entityType: protein
structure:
quaternary: tetrameric
subunits:
- name: '[[GluN1]]'
count: 2
- name: '[[GluN2]]'
count: 2
activation:
required_ligands:
- '[[glutamate]]'
- '[[glycine]]'
biophysics:
conductance:
value: 50
unit: pS
block:
agent: '[[magnesium]]'
voltage: -70
unit: mV
modulates.agonism:
- '[[long-term potentiation]]'
conducts.permeates:
- '[[calcium]]'
---
# NMDAR
Essential structured properties in YAML above.---
entityType: protein_component
atomic: true
parent_references:
- NMDAR
structure:
domains:
c_terminal:
length: long
binding_partners:
- '[[PSD95]]'
- '[[CaMKII]]'
---
# GluN2B subunit
Specific subunit properties. Part of [[NMDAR]].create_entities: Create entities with automatic YAML structuring and atomic decompositiondelete_entities: Remove entities and their filesadd_observations: Add observations to existing entitiesdelete_observations: Remove specific observations
create_relations: Create relations with automatic bidirectional pair generation and normalizationdelete_relations: Remove relationsget_relation_properties: Get all relation types and qualifications with usage statistics
read_graph: Retrieve entire knowledge graphsearch_nodes: Search entities by query across MCP and vaultopen_nodes: Get specific entities by namequery_vault: Search external Obsidian vault with MCP link suggestions
analyze_graph: Run graph analyticscentrality: ArticleRank centrality analysispaths: Find shortest path between entitiespredictions: Predict missing links based on graph structure
User creates entity with observations
β
YAML Parser: text β structured properties
β
Atomic Extractor: wikilinks β atomic entities
β
EntityEnhancer: orchestrates decomposition
β
create_entities: creates core + atomic files
β
generateMarkdown: YAML frontmatter + Dendron relations
β
Result: Fractal Zettelkasten structure
βββββββββββββββββββββββββββββββββββββββββββ
β Unified Query Engine β
β (merges results, resolves cross-links) β
ββββββββββββββ¬βββββββββββββββββββββββββββββ
β
ββββββββ΄βββββββ
β β
ββββββββββββ βββββββββββββββ
β MCP β β External β
β Memory β β Obsidian β
β Index β β Vault β
ββββββββββββ βββββββββββββββ
src/structuring/: YAML parsing and atomic entity extractionsrc/inference/: Bidirectional relation generationsrc/semantic/: Semantic embeddings for intelligent matchingsrc/analytics/: ArticleRank, path finding, link predictionsrc/index/: Dual indexing (MCP memory + vault scanner)src/integration/: Entity and relation enhancementsrc/extraction/: Metadata extraction (wikilinks, tags)src/utils/: Normalization, markdown generation, path utilities
Uses sentence transformers (@xenova/transformers) to find semantically similar relations:
User creates: "blocks.completely"
System suggests: "Use existing 'inhibits.competitive' (92% semantically similar)"
Prevents property proliferation by understanding meaning, not just strings.
- Synonym mapping: "affects" β "influences", "controls" β "regulates"
- Similarity matching: Levenshtein distance with 85% threshold
- Semantic embeddings: Meaning-based matching for intelligent deduplication
- ArticleRank: Improved PageRank variant for knowledge graphs
- Degree Centrality: Incoming/outgoing connection counts
- Common Neighbor: Link prediction algorithm
- Path Finding: BFS shortest path algorithm
MEMORY_DIR: Directory for storing memory markdown files (default:./memory)
Atomic decomposition can be disabled per request:
create_entities({
entities: [...],
atomicDecomposition: false // Disable if you want monolithic entities
})Bidirectional relations can be disabled:
create_relations({
relations: [...],
bidirectional: false // Create only forward relations
})npm run build # Compile TypeScript
npm run watch # Watch mode for developmentnpm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage reportCurrent test status: 51 passing tests across 16 test suites
obsidian-memory-mcp/
βββ src/
β βββ analytics/ # Graph analytics engine
β βββ config/ # Vault discovery
β βββ extraction/ # Metadata extraction
β βββ index/ # Dual indexing system
β βββ inference/ # Bidirectional relations
β βββ integration/ # Entity/relation enhancement
β βββ semantic/ # Semantic embeddings
β βββ storage/ # Markdown storage manager
β βββ structuring/ # YAML parsing, atomic extraction
β βββ utils/ # Utilities
β βββ index.ts # Main MCP server
βββ docs/
β βββ plans/ # Design documents and implementation plans
βββ test-fixtures/ # Test data
βββ dist/ # Compiled JavaScript
- Dendron link ontology format (relationType.qualification)
- YAML observation structuring
- Atomic entity decomposition
- Bidirectional relation generation
- Semantic relation embeddings (infrastructure)
- Graph analytics (ArticleRank, paths, predictions)
- Dual indexing (MCP + external vault)
- Property normalization and standardization
- Semantic weight calculation for relation pruning
- Small-world network optimization
- Entity resolution (duplicate detection across vaults)
- Temporal knowledge versioning
- Self-organizing property taxonomy
- Tool consolidation (MCP optimization)
- Session-based state management
- Dynamic resource templates
- Workflow prompts
See docs/plans/ for detailed implementation plans.
You create:
"NMDAR is a tetrameric protein requiring glutamate"
System creates:
NMDAR.md- Core entity with structured YAMLglutamate.md- Atomic ligand entity- Relation:
NMDAR requires.co_agonist β glutamate - Inverse:
glutamate required_by.co_agonist_for β NMDAR
Result: Fractal knowledge structure with bidirectional navigation!
Old approach (string matching):
"affects" β "influences" (hardcoded synonym)
"blocks" β miss "inhibits" (not in dictionary)
New approach (semantic understanding):
"blocks.completely" β finds "inhibits.competitive" (92% semantic similarity)
"enhances.strongly" β finds "potentiates.allosteric" (88% semantic similarity)
Learns from your vault's existing knowledge to guide consistency.
Optimizes graph topology for:
- High clustering (0.4-0.6): Dense local neighborhoods
- Low path length (3-5 hops): Everything reachable
- Moderate degree (5-15): No bloated hub entities
- Small-worldness > 3: Significantly better than random graphs
This project is based on Anthropic's memory server from the Model Context Protocol servers collection.
- Storage: JSON β Individual Markdown files
- Format: Dendron link ontology in YAML frontmatter
- Architecture: Atomic Zettelkasten structure
- Intelligence: Semantic embeddings, bidirectional relations, graph analytics
- Indexing: Dual index (MCP + external vault)
- Structuring: Automatic YAML parsing and atomic decomposition
- @modelcontextprotocol/sdk: MCP protocol implementation
- gray-matter: YAML frontmatter parsing
- @xenova/transformers: Semantic embeddings (local, no API calls)
- luxon: Temporal analysis and date handling
- Original memory server: Anthropic, PBC
- Obsidian integration: YuNaga224
- Atomic architecture & intelligence: Enhanced by community contributions
MIT License - see LICENSE file for details.
Original memory server: Copyright (c) 2024 Anthropic, PBC Obsidian integration modifications: Copyright (c) 2025 YuNaga224
- Datacore - Reactive data engine for Obsidian
- Dendron - Note-taking tool with link ontology
- Model Context Protocol - Protocol for LLM-application integration
For issues, questions, or contributions:
- GitHub Issues: https://github.com/YuNaga224/obsidian-memory-mcp/issues
- Fork and contribute: https://github.com/Zpankz/obsidian-memory-mcp
Transform your knowledge into an intelligent, self-organizing graph! π