claude code + obsidian workflow

Table of content

by Ray Svitla


if you use obsidian, your vault is probably the richest source of context about how you think, what you’re building, and what you’ve learned. if you use claude code, your agent can’t see any of it.

these two tools live in separate worlds by default. connecting them creates something neither can do alone: an AI agent that knows your project’s code AND your thinking about it.

the connection problem

obsidian stores knowledge as markdown files in a local folder. claude code works in your project directory. they don’t overlap.

you could copy notes into your repo, but that’s manual and they’d go stale. you could paste vault content into claude code conversations, but that’s tedious and wastes context on content that might not be relevant.

the real solution: give claude code read access to your vault through MCP or direct file access.

approach 1: MCP server for obsidian

build a simple MCP server that lets claude code search and read your obsidian vault. this is the cleanest approach — the agent discovers relevant notes on demand instead of loading everything into context.

// obsidian-mcp/src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readdir, readFile } from "fs/promises";
import { join } from "path";

const VAULT_PATH = process.env.OBSIDIAN_VAULT || 
  join(process.env.HOME!, "obsidian-vault");

const server = new McpServer({
  name: "obsidian-vault",
  version: "1.0.0",
});

server.tool(
  "search_notes",
  "search obsidian vault for notes matching a query",
  { query: z.string().describe("search term") },
  async ({ query }) => {
    const results = await searchVault(VAULT_PATH, query);
    return {
      content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
    };
  }
);

server.tool(
  "read_note",
  "read the full content of an obsidian note",
  { path: z.string().describe("relative path within vault") },
  async ({ path }) => {
    const content = await readFile(join(VAULT_PATH, path), "utf-8");
    return {
      content: [{ type: "text", text: content }],
    };
  }
);

// simple recursive search — grep, basically
async function searchVault(dir: string, query: string): Promise<string[]> {
  const matches: string[] = [];
  const entries = await readdir(dir, { withFileTypes: true });
  for (const entry of entries) {
    if (entry.name.startsWith(".")) continue;
    const full = join(dir, entry.name);
    if (entry.isDirectory()) {
      matches.push(...await searchVault(full, query));
    } else if (entry.name.endsWith(".md")) {
      const content = await readFile(full, "utf-8");
      if (content.toLowerCase().includes(query.toLowerCase())) {
        matches.push(full.replace(VAULT_PATH + "/", ""));
      }
    }
  }
  return matches;
}

const transport = new StdioServerTransport();
await server.connect(transport);

register it in .mcp.json:

{
  "mcpServers": {
    "obsidian": {
      "command": "node",
      "args": ["/path/to/obsidian-mcp/dist/index.js"],
      "env": {
        "OBSIDIAN_VAULT": "/Users/you/obsidian-vault"
      }
    }
  }
}

now when you ask claude code a question, it can search your vault and read relevant notes.

simpler but less dynamic. create a context/ or docs/ directory in your project that symlinks to relevant obsidian folders:

mkdir -p docs/context
ln -s ~/obsidian-vault/projects/my-app docs/context/notes
ln -s ~/obsidian-vault/knowledge/architecture docs/context/architecture

claude code can now read these files directly. downside: you’re choosing what’s available upfront instead of letting the agent search dynamically.

mention the folder in your CLAUDE.md:

## context
project notes and architecture decisions in docs/context/
read these before making architectural changes.

the workflow in practice

daily development

you’re working on the auth system. your obsidian vault has a note called auth-design-decisions.md where you documented why you chose JWT over sessions, what the token rotation strategy is, and which edge cases you’ve handled.

without the vault connection, claude code guesses based on the code. with it:

"search my obsidian vault for notes about auth design, 
then refactor the token rotation based on what you find."

the agent reads your design notes, understands the intent behind the code, and makes changes that align with your documented decisions.

architecture planning

"search my vault for notes about 'scaling' and 'database', 
then plan the database sharding strategy based on my previous 
research."

your past thinking becomes input for current decisions. the agent doesn’t start from zero — it starts from where you left off.

documentation sync

"I just finished implementing the new payment flow. 
read docs/context/notes/payment-design.md and update it 
to reflect what we actually built."

obsidian notes stay current because the agent that built the feature also updates the documentation.

what to put in your vault for AI

not everything in your obsidian vault is useful to an AI agent. focus on:

architecture decision records. why you chose X over Y. agents make better changes when they understand intent. → project-specific conventions. patterns that aren’t in the code yet, or that apply across repos. → domain knowledge. business rules, edge cases, regulatory requirements. stuff that isn’t in the code but affects what the code should do. → debugging notes. “the payment webhook sometimes arrives before the order is created. we handle this with a retry queue.” — this saves the agent from re-discovering known issues.

don’t bother with: daily journal entries, personal reflections, reading lists, or anything that isn’t actionable context for code changes.

a caution about dependency

there’s a trap here. the more your AI agent relies on your notes, the more pressure you feel to maintain those notes. if “write obsidian notes” becomes a prerequisite for “write code,” you’ve added a step to every task.

the vault should be a bonus, not a requirement. claude code works fine without obsidian. it works better with it, the way a carpenter works better with a well-organized workshop — but a carpenter who won’t start until every tool is in its labeled drawer isn’t a good carpenter.

use the connection when it’s genuinely useful. don’t turn note-taking into a procrastination ritual disguised as productivity.


your first MCP server — build the server from scratch → context optimization — manage what the agent sees → agent-first design — structure repos for AI access


Ray Svitla stay evolving

Topics: claude-code obsidian pkm workflow mcp