← All Posts

Building a Knowledge Management System with Obsidian and Claude Code

5 min readMarch 14, 2026
claude-codeobsidianworkflowknowledge-managementproductivity

Every time I finish a Claude Code session, useful stuff disappears. Blog drafts scroll past. Security audit results vanish into terminal history. Generated images sit in /tmp/ until the next reboot wipes them. I'd built 29 blog posts, 8 projects, and 59 skills — but my actual knowledge about all of it was scattered across hidden folders, terminal scrollback, and my own memory.

I needed a system where everything Claude Code produces is browsable, searchable, and backed up. Not a new tool — just a better way to see what I already had.

The answer was embarrassingly simple: point Obsidian at Claude Code's memory folder.

The Problem: Terminal-Shaped Knowledge

Claude Code has a built-in memory system. It writes markdown files to ~/.claude/projects/ — notes about your projects, preferences, lessons learned. It's genuinely useful. But there are two problems.

First, the memory folder is hidden. You never browse it. You never read it unless Claude Code reads it for you. It's knowledge locked behind a CLI.

Second, everything else Claude Code produces — blog drafts, generated images, security reports, architecture decisions, debugging write-ups — has no home at all. It renders in your terminal, you nod, and it's gone.

Before: Where Outputs Go to Die
Blog draft markdown
→ terminal scrollback (lost on close)
Generated images
→ /tmp/ (lost on reboot)
Security audit results
→ terminal scrollback (lost on close)
Architecture decisions
→ your brain (lost over time)
Debugging root causes
→ your brain (lost over time)
Content plans
→ terminal scrollback (lost on close)

I was losing knowledge faster than I was creating it.

The Fix: One Folder, Two Interfaces

An Obsidian vault is just a folder of markdown files with a .obsidian config directory. Claude Code's memory is just a folder of markdown files. The realization: they're the same thing.

# Install Obsidian
brew install --cask obsidian

# The memory folder IS the vault — just register it
# Obsidian stores vault configs in ~/Library/Application Support/obsidian/obsidian.json

No migration. No export/import. No sync tool. Obsidian opens the folder directly. Now the same files are accessible two ways:

InterfaceWhen to useStrengths
Claude CodeDuring sessions — reading/writing memory, generating outputsInstant filesystem access, bulk operations, automation
ObsidianBetween sessions — browsing, reviewing, editingVisual UI, graph view, search, image previews

Edits flow both ways. Update a note in Obsidian, Claude Code sees it next session. Claude Code writes a blog draft, it appears in Obsidian immediately.

The Vault Structure

I reorganized the flat memory folder into a structure that makes sense in Obsidian's sidebar:

memory/
├── MEMORY.md                  ← index (38 lines, was 304)
├── personal/                  ← accounts, Google, Notion
├── projects/                  ← 8 project knowledge files
├── project-docs/              ← symlinked READMEs + CLAUDE.md
├── skills/                    ← 59 symlinked SKILL.md files
├── tools/                     ← n8n, status line, GIF recording
├── workflows/                 ← feedback, processes, reminders
├── review/                    ← approval inbox
│   ├── blog-drafts/
│   ├── content-plans/
│   ├── images/                ← 41 images + Gallery.md
│   ├── reports/
│   └── screenshots/
└── logs/                      ← session history
    ├── sessions/
    ├── debugging/
    └── architecture-decisions/

A few design decisions worth explaining.

Symlinks for Live Docs

Skills and project docs already live in their own locations (~/.claude/skills/ and each project's repo). Instead of copying, I symlinked them into the vault:

# Symlink all 59 skills
for skill_dir in ~/.claude/skills/*/; do
  skill_name=$(basename "$skill_dir")
  ln -sf "$skill_dir/SKILL.md" memory/skills/${skill_name}.md
done

# Symlink project docs
ln -sf ~/ai-journey/CLAUDE.md memory/project-docs/ai-journey-CLAUDE.md
ln -sf ~/pantry-app/README.md memory/project-docs/pantry-app-README.md

One source of truth. Edit a skill in Obsidian, it updates in ~/.claude/skills/. Push a README change from your repo, it shows up in Obsidian.

The Review Inbox

This is the folder that changes everything. Instead of outputs vanishing into the terminal, Claude Code now drops them here:

Output typeGoes toReviewed in
Blog draftsreview/blog-drafts/{slug}.mdObsidian — read, edit, approve
Generated imagesreview/images/Obsidian — inline image preview
Security auditsreview/reports/{type}-{date}.mdObsidian — browse findings
Content plansreview/content-plans/Obsidian — review schedule
QA screenshotsreview/screenshots/Obsidian — visual comparison

The key insight: review/ is an approval queue. Nothing goes live until I've seen it in Obsidian and said "ship it." This turned Claude Code from a tool that does things for me into one that does things with me.

The Image Gallery

Obsidian renders images inline. I created a Gallery.md that embeds every generated image using Obsidian's wiki-link syntax:

### ai-journey-tech-stack
![[blog/ai-journey-tech-stack.png]]

### building-pantry-app
![[blog/building-pantry-app.png]]

Scrolling through 41 images in one view beats hunting through Finder. This alone made the whole setup worth it.

Session Logs

The logs/ folder captures knowledge that would otherwise exist only in my memory:

  • Session summaries — what was built, what tools were used, gotchas found
  • Debugging write-ups — root cause analysis for tricky bugs
  • Architecture decisions — what was chosen, what was rejected, and why

These accumulate over time into a searchable history. Three months from now, when I hit a similar bug, I can search my vault instead of re-debugging from scratch.

Context Window Benefits

The reorganization had an unexpected technical benefit. Before, Claude Code loaded a 304-line MEMORY.md into every conversation — project details for 8 projects, API keys, gotchas, everything. Even when I was only working on one project.

After splitting into individual files, the index dropped to 38 lines. Claude Code loads only the relevant project file on demand. That's roughly 270 fewer lines of context consumed by default, leaving more room for actual work.

Backing It Up

The vault lives in a hidden folder (~/.claude/projects/). If my machine dies, everything dies with it. Same problem with skills — 59 skill definitions, local only.

I created two private GitHub repos with simple backup scripts:

# Skills backup
~/.claude/skills-backup/backup.sh
# → pushes to github.com/carlfung1003/claude-skills (private)

# Memory/vault backup
~/.claude/memory-backup/backup.sh
# → pushes to github.com/carlfung1003/claude-memory (private)

Each script rsyncs the current state, commits with a timestamp, and pushes. Run them weekly or after significant changes. The memory backup excludes .obsidian/ config (machine-specific), skills/ (symlinks, backed up separately), and project-docs/ (symlinks to repos already in git).

The Full Storage Picture

After setting this up, I mapped where all my data actually lives. Five layers, each with a distinct purpose:

LayerWhat lives thereBackup strategy
GitHub (8 repos)Source code, deployed contentGit itself — push = backed up
Obsidian vaultProject knowledge, review inbox, session logsclaude-memory private repo
Claude Code skills59 skill definitionsclaude-skills private repo
Notion (5 hubs)Rich notes, databases, mobile-accessible planningCloud (Notion's infrastructure)
Google DriveWork exports, shared spreadsheetsCloud (Google's infrastructure)

The rule of thumb: if Claude Code needs to read/write it fast, it goes in Obsidian. If it needs rich editing or mobile access, it goes in Notion. If it's code, it goes in Git. No overlap, no orphans.

What I'd Do Differently

Honestly, not much. The whole setup took about 30 minutes because the foundational insight is so simple: Obsidian vaults are folders, Claude Code memory is a folder, make them the same folder.

If I were starting over, I'd set this up on day one. Every session summary, every debugging write-up, every generated image from the past month is gone — lost to terminal history and /tmp/ cleanups. The vault only captures what happens after you set it up.

The one thing I'd add is a daily note template that auto-creates a session log file. Right now it depends on Claude Code remembering to write one at session end. Automating that with Obsidian's Daily Notes plugin would close the last gap.

If you're using Claude Code for anything more than one-off questions, give this a try. The setup is trivial. The payoff compounds with every session.