Second
Brain
An Obsidian vault that Claude can read, query, and write to. 140+ atomic notes, one idea each.
No database — just Markdown files with structured frontmatter, one idea per file. Nine MCP tools give Claude read and write access to the whole thing.
140+atomic notes, linked by topic, queried semantically. Here's how it works ↓
What an atomic note looks like
YAML frontmatter on top, free-form Markdown below, one concept per file. Four note types — decision, learning, skill, reference — plus an index page per project, each carrying a trigger rule that tells the agent when to write one itself.
Knowledge Map
Every note is a node, every line a semantic link. Hover to see how decisions, learnings, and skills relate.
decisionslearningsskillsreferences
Vault Explorer
Folders mirror how I organize knowledge: projects, patterns, resources. Every note carries typed frontmatter — type, tags, project, creation date.
Click any note to inspect its metadata.
Zod Validation
Content preview...
Vault MCP — the nine tools
Nine tools ship with the server. Three carry retrieval — vault_search, vault_query, vault_recall; the other six handle reading, writing, context-packing, and linking.
Select a tool on the left to see its schema, request, and response.
vault_recall
Hybrid recall — semantic + keyword + project filter (default)
z.object({task: z.string().describe("Natural language task or query"),project: z.string().optional(),types: z.array(z.string()).optional(),})
{"task": "decisions about automation","types": ["decision", "learning"]}
{"results": [{ "path": "01-projects/hipm/decisions/n8n-statt-make.md","title": "n8n statt Make", "type": "decision", "score": 0.94 },{ "path": "02-knowledge/skills/webhook-patterns.md","title": "Webhook Patterns", "type": "skill", "score": 0.81 }]}
Live Query
A semantic search, live. The agent asks a plain-language question; the vault finds and ranks the closest notes.
Try it: type "mcp", "automation", or "portfolio".
How It Works
The frontmatter schema — type, tags, project, status, date — is what lets the agent run typed queries instead of full-text search. Nine MCP tools expose the vault; three carry retrieval, and seven slash commands ( /brain-context, /daily-brief, /weekly-checkin and more) wire it into day-to-day flow.
// vault_search — semantic search via local Ollama embeddings.
// Falls back to keyword search if Ollama is unreachable.
server.tool(
"vault_search",
"Semantische Suche ueber den Vault.",
{
query: z.string().describe("Search term or question"),
limit: z.number().optional(),
project: z.string().optional(),
type: z.string().optional(),
},
async ({ query, limit = 10, project, type }) => {
let results;
if (ollamaAvailable) {
const queryEmbedding = await ollama.embed(query);
results = findTopK(queryEmbedding, embeddingsCache, limit, { project, type });
} else {
// Graceful degradation: keyword over title + tags + content
const notes = listNotes(VAULT_PATH).map(p => {
const n = readNote(VAULT_PATH, p);
return { path: p, title: n.title, tags: n.frontmatter.tags ?? [], content: n.content };
});
results = keywordSearch(query, notes).slice(0, limit);
}
for (const r of results) {
const note = readNote(VAULT_PATH, r.path);
r.excerpt = note.content.slice(0, 200);
}
return { content: [{ type: "text", text: JSON.stringify({ results }, null, 2) }] };
}
);The Search Stack
No cloud service. Every note is embedded locally by Ollama running nomic-embed-text; at query time the same model embeds the question and cosine similarity returns a ranked top-K, dropping to keyword search if Ollama is down. Nothing leaves the machine — no API cost, single-digit-ms latency, works offline.
// Local embedding via Ollama — no cloud round-trip
async embed(text: string): Promise<Float32Array> {
const prepared = this.prepareText(text); // truncate to ~6k tokens
const res = await fetch(`${this.host}/api/embeddings`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ model: this.model, prompt: prepared }),
});
const { embedding } = await res.json() as { embedding: number[] };
return new Float32Array(embedding);
}
// Cosine similarity — the ranking function that makes "semantic" mean something
export function cosineSimilarity(a: Float32Array, b: Float32Array): number {
let dot = 0, normA = 0, normB = 0;
for (let i = 0; i < a.length; i++) {
dot += a[i] * b[i];
normA += a[i] * a[i];
normB += b[i] * b[i];
}
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
}Why the vault is built this way
- 01Obsidian, not a custom DB
Plain Markdown with frontmatter: human-readable, git-trackable, editable without tooling. The MCP layer sits on top, so the vault itself stays portable.
- 02One note, one idea
One decision per file, no mega-docs or nested structures. That way each note can be queried, linked, and surfaced on its own.
- 03Frontmatter as schema
Typed fields (type, tags, project, created) let the agent filter by note type and project context over MCP, instead of scanning full text.
- 04Local embeddings over a cloud API
Ollama running
nomic-embed-textonlocalhost. Quality is a notch below OpenAI'stext-embedding-3— but the data never leaves the machine. - 05Model-versioned index
Each cached vector records the model that produced it. Swap the embedding model and only the stale vectors get re-embedded, so old and new never mix in one ranking.
- 06Keyword fallback
If Ollama isn't reachable, the server falls back to keyword search over title, tags, and content instead of throwing. Ranking suffers, but the vault keeps working.