Agentic
Agentic · Second Brain

Second
Brain

An Obsidian vault that Claude can read, query, and write to. 140+ atomic notes, one idea each.

0+Atomic Notes
0Note Types
0MCP Tools
Scroll
The vault, live

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 ↓

illustrative — generated to mirror vault topology
Anatomy

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.

01-projects/luccafaust-dev/decisions/portfolio-bilingual-toggle.mdtype: decision
---
type: decision
project: luccafaust-dev
tags: [i18n, next-intl, toggle]
created: 2026-04-20
---
# Portfolio bilingual — EN + DE with toggle
Portfolio ships bilingual (EN + DE), switchable via a top-nav toggle. The i18n pass happens once content is solid, not in parallel, so the two languages don't drift.
**Why:** …   **How to apply:** …
01

Knowledge Map

Every note is a node, every line a semantic link. Hover to see how decisions, learnings, and skills relate.

decisionslearningsskillsreferences

n8n statt Make
decision
Zod Validation
learning
Webhook Patterns
skill
MCP Protocol Spec
reference
Agent Orchestration
skill
MCP Server Design
skill
Atomic Notes
learning
Tool Schema Design
decision
decision
learning
skill
reference
02

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.

Vault Explorer~/second-brain

Zod Validation

#mcp#validation#zod
---
type:learning
tags:[mcp, validation, zod]
created:2026-03-15
project:second-brain-bridge
---
Content

Content preview...

dedecision
lrlearning
skskill
rfreference
03

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 MCP — 5 tools

vault_recall

Hybrid recall — semantic + keyword + project filter (default)

Schema
z.object({
task: z.string().describe("Natural language task or query"),
project: z.string().optional(),
types: z.array(z.string()).optional(),
})
Request
{
"task": "decisions about automation",
"types": ["decision", "learning"]
}
Response
{
"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 }
]
}
04

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".

vault_query
Obsidian
MCP SDK
TypeScript
Markdown
Frontmatter
YAML

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.

second-brain/.mcp-server/src/index.ts
// 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.

embeddings/ollama-client.ts
// 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

  • 01
    Obsidian, 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.

  • 02
    One 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.

  • 03
    Frontmatter 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.

  • 04
    Local embeddings over a cloud API

    Ollama running nomic-embed-text on localhost. Quality is a notch below OpenAI's text-embedding-3 — but the data never leaves the machine.

  • 05
    Model-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.

  • 06
    Keyword 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.