Claude Code x Obsidian: Vault-Struktur, Rechte, Templates und Link-Audit
Praktischer Workflow für Claude Code und Obsidian: Daily Logs, Handoff-Notizen, Snippets, Content Ops und Link-Audit.
Ein Obsidian-Vault wird mit der Zeit wertvoller, aber auch schwerer zu pflegen. Tagesnotizen sammeln offene Aufgaben, Projektseiten verlieren den aktuellen Stand, Code-Snippets enthalten irgendwann nicht mehr die Version oder den Fehlerkontext, und Artikelideen verlinken nicht mehr sauber auf Produkte, Training oder interne Quellen. Claude Code kann dabei helfen, weil ein Vault im Kern ein Ordner mit Markdown-Dateien ist.
Der gute Einsatz besteht nicht darin, Claude Code den ganzen Vault “aufräumen” zu lassen. Der bessere workflow ist begrenzt: klare Ordnerstruktur, enge Dateirechte, wiederverwendbare Templates und ein Link-Audit nach jeder Änderung. Für Einsteiger: Der Vault ist der Notizordner; das harness ist das Arbeitsgerüst, das dem Agenten sagt, wo er lesen, schreiben und prüfen darf.
Dieser Leitfaden behandelt vier konkrete use cases: tägliche Logs, project handoff, Code-Snippets und content operations. Gleichzeitig nennt er die wichtigsten pitfall- und risk-Stellen, denn der gefährlichste Fehler ist nicht ein schlecht formulierter Absatz, sondern ein still kaputter Link, falsche Properties oder ein versehentlich gelesener Privatordner.
Integrationsmodell
Die offizielle Obsidian-Hilfe beschreibt interne Links als Wikilinks wie [[Notizname]] oder als Markdown-Links. Daily notes sind ein Core Plugin für datumsbasierte Notizen. Templates können Werte wie {{date}} einfügen, und Properties liegen als YAML am Anfang der Datei. Nützlich sind die offiziellen Seiten zu Internal links, Daily notes, Templates, Properties und Web Clipper templates.
Auf der Claude-Code-Seite sind settings und permissions die Sicherheitsgrenze. CLAUDE.md erklärt die Regeln des Vaults. .claude/settings.json begrenzt die Dateioperationen.
flowchart LR
A["Inbox"] --> B["Claude Code review"]
B --> C["Daily logs"]
B --> D["Projects"]
B --> E["Content ops"]
C --> F["Obsidian links"]
D --> F
E --> F
F --> G["Link audit"]
Markdown bleibt die Wahrheit. Claude Code sortiert, schreibt Entwürfe, fasst zusammen und prüft Links, aber es ersetzt nicht die Obsidian-Struktur.
Vault-Struktur klein halten
Beginnen Sie mit wenigen Ordnern, die realer Arbeit entsprechen.
mkdir -p inbox daily projects content-ops snippets templates scripts archive private
| Ordner | Zweck | Sichere Claude-Code-Arbeit |
|---|---|---|
inbox/ | Rohnotizen und Web-Clips | anlegen und triagieren |
daily/ | Daily Logs und Arbeitsgedächtnis | erstellen, ergänzen, Vortag zusammenfassen |
projects/ | Projektstatus und Entscheidungen | Handoff-Notizen aktualisieren |
content-ops/ | Artikelideen, CTA, Publishing | Entwürfe und Links ordnen |
snippets/ | Befehle und Codebeispiele | Kontext, Tags und Fehlerfälle ergänzen |
templates/ | Obsidian-Templates | lesen, aber nur nach Freigabe ändern |
archive/ | abgeschlossene Notizen | nicht ändern |
private/ | private oder geheime Daten | nicht lesen |
So entstehen praktische Workflows: Tagesnotizen übernehmen offene Aufgaben, Handoff-Notizen halten Status und nächste Aktion fest, Snippet-Notizen speichern lauffähige Befehle mit Fehlermodus, und Content-ops-Notizen prüfen offizielle Links, interne Links, /products/ und /training/.
CLAUDE.md in den Vault legen
Diese Datei gehört in das Wurzelverzeichnis. Schreiben Sie konkrete Regeln statt allgemeiner Wünsche.
# Obsidian Vault Rules
## Purpose
- This vault stores daily logs, project handoffs, code snippets, and content operations notes.
- Keep notes useful in Obsidian without requiring Claude Code to read private files.
## Directory policy
- `daily/`: create or update daily notes in `YYYY-MM-DD.md`.
- `projects/`: maintain one handoff note per active project.
- `content-ops/`: maintain article plans, CTA checks, and publishing notes.
- `snippets/`: store runnable commands and code examples with context.
- `templates/`: read freely, but ask before editing.
- `archive/` and `private/`: do not edit. Do not summarize private files.
## Note rules
- Use Wikilinks like `[[Project name]]` for internal links.
- Use YAML properties at the top of notes.
- Keep one paragraph under five lines.
- Add a `source:` property when a note comes from a URL.
- Add `status: draft`, `status: active`, or `status: done`.
## Safety rules
- Never rename existing notes without asking first.
- Never rewrite `.obsidian/` settings.
- Before bulk edits, list the target files and wait for approval.
- After changes, run `node scripts/audit-wikilinks.cjs .`.
Der häufige pitfall: “Bitte räume meinen Vault auf.” Claude Code muss dann Ordner, Überschriften und Tags erraten. Diese Vermutungen können gut klingen und trotzdem Suche, Graph View und Übergaben verschlechtern.
Rechte eng konfigurieren
Erstellen Sie .claude/settings.json. Dieses Beispiel erlaubt normale Notizarbeit, fragt bei Template-Änderungen, Git und Webzugriff nach und sperrt private oder empfindliche Bereiche.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Read(./CLAUDE.md)",
"Read(./daily/**)",
"Read(./projects/**)",
"Read(./content-ops/**)",
"Read(./snippets/**)",
"Read(./templates/**)",
"Read(./scripts/**)",
"Edit(./daily/**)",
"Edit(./projects/**)",
"Edit(./content-ops/**)",
"Edit(./snippets/**)",
"Write(./inbox/**)",
"Write(./daily/**)",
"Write(./projects/**)",
"Write(./content-ops/**)",
"Write(./snippets/**)",
"Bash(node scripts/audit-wikilinks.cjs .)"
],
"ask": [
"Edit(./templates/**)",
"Bash(git *)",
"WebFetch"
],
"deny": [
"Read(./private/**)",
"Read(./**/.env)",
"Read(./**/.env.*)",
"Edit(./.obsidian/**)",
"Edit(./archive/**)",
"Write(./archive/**)",
"Bash(rm *)",
"Bash(del *)"
]
}
}
Das ist bewusst vorsichtig. WebFetch, Git oder Template-Änderungen sind nicht verboten, aber sie brauchen eine bewusste Zustimmung. Ein breiter Bypass-Modus passt nur zu isolierten Test-Vaults.
Drei Templates vorbereiten
Das Daily-Template muss klein bleiben.
---
date: "{{date:YYYY-MM-DD}}"
status: active
tags:
- daily
---
# {{date:YYYY-MM-DD}}
## Today
- [ ]
## Learned
-
## Questions
-
## Links
- [[Weekly review]]
Für project handoff zählt die nächste Aktion mehr als eine lange Zusammenfassung.
---
status: active
owner: Masa
tags:
- project
- handoff
updated: "{{date:YYYY-MM-DD}}"
---
# Project handoff: {{title}}
## Goal
## Current state
## Next action
- [ ]
## Decisions
-
## Risks and pitfall
-
## Links
- [[Daily note]]
- [[Related snippet]]
Bei content operations wird die Monetarisierung schon im Template sichtbar, damit die CTA zur Suchintention passt.
---
status: draft
channel: blog
source:
target_cta:
- /products/
- /training/
tags:
- content-ops
---
# Content ops note: {{title}}
## Search intent
## Reader problem
## Outline
## Internal links
- [[Claude Code approval sandbox guide]]
- [[Claude Code documentation generation]]
## Monetization CTA
- Product CTA:
- Training CTA:
## Publish checklist
- [ ] Official links checked
- [ ] Code examples tested
- [ ] Broken internal links audited
Passende interne Vertiefungen sind Approval und Sandbox, Dokumentation generieren und Content Funnel Audit. Wiederverwendbare Materialien gehören nach products, Team-Rollout und Beratung nach training.
Interne Links mit Node prüfen
Speichern Sie das folgende Skript als scripts/audit-wikilinks.cjs. Es prüft Wikilinks und interne Markdown-Links gegen Dateien im Vault.
#!/usr/bin/env node
const fs = require("node:fs");
const path = require("node:path");
const vaultRoot = path.resolve(process.argv[2] || ".");
const ignoredDirs = new Set([".git", ".obsidian", ".trash", "node_modules"]);
const allFiles = [];
const markdownFiles = [];
function walk(dir) {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
if (ignoredDirs.has(entry.name)) continue;
const full = path.join(dir, entry.name);
if (entry.isDirectory()) {
walk(full);
} else if (entry.isFile()) {
allFiles.push(full);
if (entry.name.toLowerCase().endsWith(".md")) markdownFiles.push(full);
}
}
}
function toPosix(filePath) {
return filePath.split(path.sep).join("/");
}
function withoutMd(value) {
return value.replace(/\.md$/i, "");
}
function stripTarget(raw) {
return raw.split("|")[0].split("#")[0].split("^")[0].trim();
}
function safeDecode(value) {
try {
return decodeURIComponent(value);
} catch {
return value;
}
}
function isExternal(target) {
return /^(https?:|mailto:|obsidian:|#|\/)/i.test(target);
}
function candidateKeys(target, fromFile) {
const clean = safeDecode(stripTarget(target));
if (!clean) return [];
const keys = new Set();
const normalized = toPosix(path.normalize(clean));
keys.add(normalized);
keys.add(withoutMd(normalized));
if (clean.includes("/") || clean.includes("\\")) {
const fromDir = path.dirname(toPosix(path.relative(vaultRoot, fromFile)));
const relative = toPosix(path.normalize(path.join(fromDir, clean)));
keys.add(relative);
keys.add(withoutMd(relative));
} else {
keys.add(withoutMd(path.posix.basename(normalized)));
keys.add(path.posix.basename(normalized));
}
return [...keys].filter(Boolean);
}
walk(vaultRoot);
const byPath = new Map();
const byBase = new Map();
for (const file of allFiles) {
const rel = toPosix(path.relative(vaultRoot, file));
const lowerRel = rel.toLowerCase();
byPath.set(lowerRel, file);
if (rel.toLowerCase().endsWith(".md")) byPath.set(withoutMd(lowerRel), file);
const base = rel.toLowerCase().endsWith(".md")
? withoutMd(path.posix.basename(rel)).toLowerCase()
: path.posix.basename(rel).toLowerCase();
const list = byBase.get(base) || [];
list.push(file);
byBase.set(base, list);
}
const problems = [];
const wikilink = /!?\[\[([^\]]+)\]\]/g;
const markdownLink = /!?\[[^\]]*\]\(([^)]+)\)/g;
for (const file of markdownFiles) {
const text = fs.readFileSync(file, "utf8");
const rel = toPosix(path.relative(vaultRoot, file));
const targets = [];
let match;
while ((match = wikilink.exec(text))) targets.push(match[1]);
while ((match = markdownLink.exec(text))) {
const target = match[1].replace(/^<|>$/g, "").trim();
if (!isExternal(target)) targets.push(target);
}
for (const target of targets) {
const clean = stripTarget(target);
if (!clean || isExternal(clean)) continue;
const keys = candidateKeys(clean, file);
const pathHit = keys.some((key) => byPath.has(key.toLowerCase()));
const baseHits = keys.flatMap((key) => byBase.get(path.posix.basename(key).toLowerCase()) || []);
if (!pathHit && baseHits.length === 0) {
problems.push(`${rel} -> missing [[${clean}]]`);
} else if (!pathHit && baseHits.length > 1) {
problems.push(`${rel} -> ambiguous [[${clean}]] (${baseHits.length} matches)`);
}
}
}
if (problems.length) {
console.error("Broken or ambiguous internal links:");
for (const problem of problems) console.error(`- ${problem}`);
process.exit(1);
}
console.log(`OK: checked ${markdownFiles.length} Markdown files in ${vaultRoot}`);
Ausführen:
node scripts/audit-wikilinks.cjs .
Ein guter Prompt an Claude Code ist konkret:
Read `daily/2026-06-02.md` and `projects/site-refresh.md`.
Create `daily/2026-06-03.md` from `templates/daily.md`.
Carry over unfinished tasks only when they still have an owner.
Do not edit `.obsidian/`, `archive/`, or `private/`.
After editing, run `node scripts/audit-wikilinks.cjs .` and report the result.
Typische Fehler
Erstens: .obsidian/ bearbeiten lassen. Plugin- und Theme-Zustand ist kein normaler Inhalt.
Zweitens: Notizen außerhalb von Obsidian umbenennen. Das kann Backlinks brechen, besonders bei Bulk-Renames.
Drittens: YAML-Properties ohne Anführungszeichen. Interne Links in Properties sollten wie related: "[[Project name]]" geschrieben werden.
Viertens: Tagesnotizen überladen. Wenn zehn Felder leer bleiben, wird das Template selbst zum Rauschen.
Fünftens: content operations nur als Schreiben verstehen. Ein veröffentlichter Beitrag braucht offizielle Quellen, interne Links, CTA und einen Prüfbeleg.
Was Masa getestet hat
In Masas Test-Vault funktionierten zwei Workflows am besten: offene Aufgaben aus dem Vortag in die neue Tagesnotiz übernehmen und Links vor Veröffentlichung prüfen. Der schwächste Versuch war “räume den ganzen Vault auf”; dabei entstanden zu viele Tags und Überschriften. Enge Rechte, dünne Templates und das Node-Audit ergaben einen stabileren Obsidian-Workflow.
Kostenloses PDF: Claude-Code-Cheatsheet
E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.
Wir schützen Ihre Daten und senden keinen Spam.
Über den Autor
Masa
Engineer für praktische Claude-Code-Workflows und Team-Einführung.
Ähnliche Artikel
Claude Code Permission Safety Ladder: Zugriff kontrolliert erweitern
Von read-only zu begrenzten Änderungen, Prüfbefehlen und Deploy-Checks mit klarer Kontrolle.
Claude Code Small PR Proof Pack: kleine Änderungen reviewbar machen
Ein Proof Pack für Claude-Code-PRs: Diff, Checks, öffentliche URL, CTA-Pfad und Rollback.
Claude-Code-Review-Gate vor dem Commit
Vor dem Commit mit Claude Code prüfen: Diff, Build, öffentliche URL, Gumroad-Links, Beratung-CTA, fehlende Tests und fremde Dateien.