NOUZ MCP Server
Manages notes in an Obsidian vault, providing tools to read, write, and navigate markdown files with YAML frontmatter, including bidirectional link tracking (parents/children), semantic indexing, and hierarchical organization across five knowledge levels.
Integrates with Ollama for local embedding generation, enabling semantic search, similarity matching, and automated metadata suggestions using locally-hosted language models.
Integrates with OpenAI's API for cloud-based embedding generation, supporting semantic analysis, core sign calibration, and vector similarity operations for knowledge graph navigation.
NOUZ — Semantic Knowledge Graph for Obsidian
One server. Three approaches. Your notes find their own place in the graph.
Why NOUZ?
You write in Obsidian. A lot. Over time your vault turns into a mess — hundreds of notes connected somehow, with no system or logic.
NOUZ fixes this. It reads your notes, analyzes the content, and builds the knowledge graph itself — what belongs where, what "sign" each note has, where the semantic connections between different branches are.
No API keys needed. NOUZ works with your own embedding model.
Related MCP server: Semantic Mesh Memory (SEM) MCP Server
What NOUZ Does
Builds the Graph
Add parents: to a note — and NOUZ automatically places it in the hierarchy. No manual folder sorting.
Classifies by Content
Using embeddings (local model), NOUZ understands what the note is about and assigns it a "sign" — T (technology), S (science), H (humanities) or any other you define.
Finds Hidden Connections
Notes from different branches can be semantically close. NOUZ finds these bridges and suggests linking them.
Tracks Knowledge Drift
Over time the content of a branch changes. NOUZ shows when the actual composition of notes diverges from the declared topic — this is core_drift, a signal that the branch has grown beyond its domain.
Three Modes for Different Tasks
Mode | What It Does | Embeddings? |
LUCA | Pure graph — only links and hierarchy | ❌ |
PRIZMA | Full semantics — classification, bridges, drift | ✅ |
SLOI | Strict 5-level hierarchy with control | ✅ |
Start with LUCA — just connect and add links. Move to PRIZMA or SLOI when you want semantics.
Quick Start
# Install via PyPI (recommended)
pip install nouz-mcp
# Run
OBSIDIAN_ROOT=/path/to/vault nouz-mcpOr from source:
git clone https://github.com/KVANTRA-dev/NOUZ-MCP
cd NOUZ-MCP
pip install -r requirements.txt
OBSIDIAN_ROOT=./vault python server.pyConnect to Claude Desktop, Cursor, Opencode, or any other MCP client:
{
"mcpServers": {
"nouz": {
"command": "nouz-mcp",
"env": {
"OBSIDIAN_ROOT": "/path/to/vault",
"MODE": "prizma",
"EMBED_API_URL": "http://127.0.0.1:1234/v1"
}
}
}
}How It Works
1. You Write a Note
---
type: module
level: 3
sign: T
parents:
- Machine Learning
---
Your note here.2. NOUZ Builds the Graph
Reads YAML → builds DAG (directed acyclic graph)
Vectorizes text → calculates proximity to your cores
Proposes sign, level, parents
Finds bridges to other branches
3. Structure Emerges from Content
T (core)
├── TH (pattern: AI)
│ ├── TH (module: ML)
│ │ ├── TH (quant: neural-networks.md) — T
│ │ └── TS (quant: transformers.md) — T
│ └── TH (module: Ethics)
│ └── TH (quant: ai-safety.md) — T
└── TS (pattern: Physics)
└── ...The more you write — the smarter your knowledge base becomes, and the agent working with NOUZ.
How Classification Works
Cores — Coordinate Axes
In config.yaml you define 2–5 domains as text descriptions. The server converts them into reference vectors — coordinate axes in the multidimensional embedding space.
mode: prizma
etalons:
- sign: T
name: Technology
text: "programming software architecture machine learning neural networks"
- sign: S
name: Science
text: "physics chemistry biology mathematics formal logic theorems"
- sign: H
name: Humanities
text: "philosophy psychology sociology history literature ethics"On core quality: separation between cores matters more than description accuracy. After writing — run calibrate_cores and check pairwise_cosine. Values above 0.55 between any two cores means they're too similar and the classifier will confuse domains. This is analogous to orthogonal basis vectors: the more orthogonal — the more accurate the projection.
Sign Assignment
For each note, its content vector is compared against all reference vectors:
scores = {S: cosine(note, core_S), T: cosine(note, core_T), H: cosine(note, core_H)}
spread = max(scores) - min(scores)If spread < 0.05 — the note is equidistant from all cores, sign is undefined. This is not an error: the note genuinely belongs to multiple domains or its content is insufficient for classification.
adjusted = {k: scores[k] - min(scores) for k in scores}
percent = {k: adjusted[k] / sum(adjusted) * 100 for k in adjusted}
sign = all domains where percent[k] >= 30%If two domains score ≥ 30% — the sign is composite: TS, SH. This is not a contradiction, but a spectrum: the note lives on the border between domains.
Sign Inheritance
The sign flows top-down through hierarchical links:
L1 core ← defined manually, never changes
L2 pattern ← defined manually + embedding adds second sign (if ≥ 30%)
L3 module ← inherits sign from parent pattern
L4 quant ← hybrid: sign from L3 parent + embedding content
L5 artifact ← inherits sign from parent quantPriority: sign_manual (YAML) > sign_auto (embedding) > inherited
Manual sign in YAML is never overwritten automatically.
Sign Confidence: auto vs weak_auto
Spread-normalization answers "which core is relatively closer". But it doesn't answer "how close is the note to this core in absolute terms".
For this there's confident_cosine — a threshold on max(cosine):
max_cosine >= confident_cosine → sign_source = "auto" (confident sign)
max_cosine < confident_cosine → sign_source = "weak_auto" (relative sign)What this means in practice:
weak_auto occurs when the note has a relative winner among cores (spread is normal), but in absolute terms all cosines are low. This happens when:
The note is short or not written in the language of the cores
The cores don't cover the note's topic well
The embedding model isn't strong in this domain
Impact on semantic bridges:
This is where it matters. Semantic bridges are only proposed between notes with different signs — if signs match, they're assumed to be "the same area". But if the sign is weak_auto — this assumption is unreliable.
sign_source = "auto" → sign is considered closed. Bridges to the same core are not proposed.
sign_source = "weak_auto" → sign is open. Bridges to notes with the same core are still proposed.This gives you a choice: either set the sign manually (close the domain), or let the system keep proposing connections from all directions.
Threshold tuning:
thresholds:
confident_cosine: 0.6 # for most models (e5, BGE, multilingual)
# confident_cosine: 0.75 # for nomic-embed (high baseline 0.74–0.83)The higher the threshold — the stricter the confidence requirement, the more notes get weak_auto. Calibrate for your model.
core_mix — Reality Bottom-Up
The sign flows top-down (intent). core_mix flows bottom-up (reality):
quant (L4) → updates core_mix of parent module (L3)
module (L3) → aggregates into core_mix of parent pattern (L2)Each module accumulates the averaged domain distribution of all its quants. When the declared sign (intent) diverges from core_mix (reality) — the system reports core_drift.
This is not an error. It's information about how the knowledge base has evolved. A branch with sign=T can gradually accumulate 60% of notes about mathematics — and core_drift will show this.
This bidirectional flow — top-down constraints and bottom-up evidence — mirrors the architecture of hierarchical predictive coding systems: upper levels set expectations, lower levels return discrepancies.
Semantic Bridges
suggest_metadata returns candidates for cross-domain links. All bridges are marked with proposed: true and require explicit confirmation.
Algorithm:
For note A (sign=S) and note B (sign=T):
if cosine(embed(A), embed(B)) >= 0.55 → propose linkFinds notes that are semantically similar overall but belong to different domains. A note about thermodynamic entropy and a note about data compression can have high embedding similarity — both are about efficient information encoding. The bridge detects that they're talking about the same thing from different angles.
The 0.55 threshold is configurable in config.yaml via semantic_bridge_threshold.
Customize It
mode: prizma
etalons:
- sign: T
name: Technology & Engineering
text: "programming software architecture infrastructure machine learning neural networks
algorithms frameworks database cloud computing"
- sign: S
name: Science & Mathematics
text: "physics chemistry biology mathematics formal logic theorems cosmology quantum
mechanics research methodology"
- sign: H
name: Humanities & Arts
text: "philosophy psychology sociology history literature art culture ethics
cognitive science epistemology linguistics"
thresholds:
sign_spread: 0.05 # minimum spread for classification
pattern_second_sign_threshold: 30.0 # second sign threshold (%)
semantic_bridge_threshold: 0.55 # semantic bridge thresholdTools
All Modes
Tool | Description |
| Read a note with YAML metadata |
| Create or update a note |
| List with filters by level, sign, subfolder |
| Traverse DAG downwards (all children) |
| Traverse DAG upwards (parents) |
| Reindex the entire vault |
| Entity formula: |
PRIZMA / SLOI
Tool | Description |
| Vectorize core texts → reference vectors |
| Reclassify all notes by embeddings |
| Recalculate bottom-up aggregation |
| Propose sign, level, semantic bridges |
| Find parents by semantic similarity |
| Get embedding vector for any text |
Configuration
Variable | Default | Description |
|
| Path to the vault |
|
| Mode: |
|
| Enable embeddings |
|
| Provider: |
|
| Endpoint for embeddings |
| `` | API key if required |
Privacy: What Stays Local
Component | Local? |
Embeddings (LM Studio / Ollama) | ✅ Yes |
Your notes (raw files) | ✅ Yes |
NOUZ server | ✅ Yes |
AI agent context (what the cloud model sees) | ❌ No — goes to the cloud |
NOUZ runs locally. But when you connect a cloud AI agent (Claude, ChatGPT, etc.), the content it sees — including your notes — goes to that provider's cloud. This is outside NOUZ control.
Your choice: use local agents or accept the trade-off.
Who Is It For?
Order lovers | Want structure without spending time on manual organization |
Researchers | Gather lots of information and want to see connections |
AI enthusiasts | Building knowledge graphs for RAG or agent systems |
Everyone with >100 notes | When folders stop coping |
Development
pip install -e .Links
Structure emerges from content — you just write.
MIT License © 2026 KVANTRA
Cosines are calculated, syntax changes, semantics remains.
Appeared in Searches
Latest Blog Posts
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/KVANTRA-dev/NOUZ-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server