AgentStack
MCP verified MIT Self-run

Obsidian Brain Vault

mcp-markfive-proto-obsidian-brain-vault · by markfive-proto

Brain Vault — the free, community-built Karpathy LLM-Wiki for Obsidian. CLI + MCP-ready. Claude Code skill pack included. obs + obs-mcp.

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add mcp-markfive-proto-obsidian-brain-vault

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Obsidian Brain Vault? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Brain Vault — a knowledge base that writes itself

obsidian-brain-vault · CLI: obs · MCP: obs-mcp

The free, community-built implementation of Andrej Karpathy's LLM Wiki pattern: drop raw sources in, an LLM compiles them into an interlinked wiki, answers you save compound over time. Built to give AI agents persistent context that goes beyond a single chat session.

AI-first. Headless. MCP-ready. Works with Claude Desktop, Cursor, Windsurf, Claude Code. Any markdown folder — Obsidian-compatible today, vendor-neutral by design.

[](LICENSE) [](LICENSE) [](./README.md#connect-it-to-claude-desktop--cursor--windsurf-mcp)


The problem

Every AI chat starts from zero. You re-explain who you are, what you're building, what you already know. The session ends and your best thinking disappears.

Meanwhile you have 20 browser tabs you meant to read, a folder of PDFs you never opened, and 500 notes that never link to each other. RAG retrieves the same chunks forever — nothing accumulates. Note apps are graveyards you have to maintain yourself.

Your AI agents need persistent, compounding context. That's what obs gives them.


The KB loop

RAW sources  →  obs kb ingest  →  raw/
raw/          →  obs kb compile →  compiled/ concept pages
compiled/     →  obs kb ask     →  outputs/ answers (filed back as new context)

Every ingest adds to the wiki. Every answer becomes part of the next answer. Source #50 links to ~10 existing pages and updates them — it doesn't sit alone.

obs kb ingest https://example.com/article   # fetch + file to raw/
obs kb compile                              # LLM compiles raw/ → concept pages
obs kb ask "what do I know about X?"        # query + save to outputs/

What obs gives you

  • A wiki that compounds. Drop a URL, PDF, repo, transcript, or image. The LLM extracts concepts, cross-references everything you already have, and files it.
  • Answers that stick. Ask a question. The answer is saved as a new note with wikilinks. Next question uses it as context.
  • A built-in MCP server. Plug into Claude Desktop, Cursor, Windsurf, Claude Code. Your agents query the wiki natively — no copy-pasting context.
  • Remote MCP hosting. Expose your vault over HTTPS so Claude.ai, mobile clients, or any AI tool can reach it from anywhere.
  • Headless by design. Runs on a server, in CI, in a cron job. Obsidian doesn't need to be open.
  • A Unix tool. Pipeable, scriptable, --json on every command. Compose it with anything.
  • Three ways to use it. CLI for scripts and automation. Claude Code slash commands (/clip, /compile, /ask, /lint) for conversational use. Claude Desktop MCP prompts for team workflows — all three speak the same underlying vault.
  • AutoDream. A nightly compile → lint → stats job that keeps your wiki fresh while you sleep. One script, works on macOS (launchd) and Linux (cron).
  • Ready-to-use scaffold. The [knowledgebase/](./knowledgebase/) folder in this repo is a drop-in template — pre-structured raw/, compiled/, outputs/, skills/ (all packs included), with AutoDream tools. See [knowledgebase/README-KB.md](./knowledgebase/README-KB.md) for the quickstart.

Why obs — and how it differs from Obsidian's official CLI

Obsidian shipped their own official CLI in early 2026 (now free). It's excellent at what it does: remote-controlling the Obsidian app, triggering plugins, deploying vaults, integrating Obsidian into team toolchains. It requires Obsidian to be running.

obs is a different category of tool:

| | Official Obsidian CLI | obs (this project) | |---|---|---| | Requires Obsidian running | Yes | No — fully headless | | LLM knowledge compilation | No | Yes — the core feature | | ingest → compile → ask loop | No | Yes | | Built-in MCP server | No | Yes (obs-mcp) | | Remote MCP (HTTPS, mobile) | No | Yes (supergateway + cloudflared) | | Claude Code skill pack | No | Yes | | Works on a server / in CI | No | Yes | | Vendor-neutral (no Obsidian dep) | No | Yes | | Vault ops (tags, links, search…) | Via Obsidian's API | Direct file I/O, no app needed |

If you want to script Obsidian's UI — use their CLI. If you want an AI agent knowledge base that runs anywhere and accumulates context over time — that's obs.


2-minute quickstart

Option A — Use the scaffold (recommended)

Clone this repo and copy the pre-built scaffold into your Obsidian vault:

git clone https://github.com/markfive-proto/obsidian-brain-vault.git
cp -r obsidian-brain-vault/knowledgebase /path/to/your/vault/

Then open [knowledgebase/README-KB.md](./knowledgebase/README-KB.md) — it's the complete quickstart from inside the vault.

Option B — Fresh install

1. Install

# Requires Node 18+
pnpm add -g obsidian-brain-vault          # or: npm i -g obsidian-brain-vault

# Verify
obs --version

2. Point obs at your vault

obs init                                 # Auto-detects Obsidian vaults
# or
obs vault config defaultVault /path/to/vault

3. Start the loop

obs kb init                              # Scaffold raw/ compiled/ outputs/

obs kb ingest https://karpathy.ai/...    # Add a source
obs kb compile                           # Fold it into the wiki
obs kb ask "what does my KB say about X?" # Query — answer saved to outputs/

obs kb stats                             # See the shape of your KB

You now have a vault structured like this:

your-vault/
├── raw/              sources you ingested (immutable)
│   ├── articles/
│   ├── papers/
│   ├── repos/
│   └── INGEST-LOG.md
├── compiled/         LLM-written wiki
│   ├── 00-INDEX.md
│   ├── concepts/     cross-referenced concept pages
│   ├── people/
│   └── orgs/
└── outputs/          answers, slides, charts, lint reports
    ├── answers/
    ├── slides/
    └── lint/

Open the vault in Obsidian — everything is plain markdown with [[wikilinks]].


Three ways to use the KB loop

There are three interfaces to the same underlying vault — pick the one that fits your workflow:

| Interface | Best for | How | |---|---|---| | CLI | Scripts, automation, headless runs | obs kb ingest / compile / ask / lint | | Claude Code skills | Conversational coding sessions | /clip, /compile, /ask, /lint slash commands | | Claude Desktop prompts | Team workflows, Claude.ai, mobile | MCP prompt picker — select prompt, fill args |

All three write to the same vault. The wiki you build with the CLI is queryable via Claude Desktop and vice versa.


Use it with Claude Code

obs ships with a Claude Code skill pack. Every obs kb CLI command has a slash-command twin you can invoke in Claude Code conversations.

Install the skill pack

# Clone and link if you haven't already
git clone https://github.com/markfive-proto/obsidian-brain-vault.git
cd obsidian-brain-vault && pnpm install && pnpm build && pnpm link --global
# npm works too: npm install && npm run build && npm link

# Install a pack globally (available in all Claude Code projects)
obs skills install knowledge-base          # The Karpathy pack (ingest/compile/qa/lint/render)
obs skills install capture                 # Brain-dump + quick-capture cognitive pack

# Or install to the current project only
obs skills install knowledge-base --local

Available slash commands

Once installed, in any Claude Code session:

| You type | Claude does | |---|---| | /clip | Fetches the page, cleans it to markdown, files it in raw/articles/ | | /paper | Extracts text + figures from a PDF into raw/papers/ | | /repo | Fetches README + key files into raw/repos/ | | /transcript | Pulls auto-captions into raw/transcripts/ | | /compile | Scans raw/ for new sources, generates/updates concept pages | | /ask | Queries the wiki, saves the answer to outputs/answers/ | | /deep | Multi-step research dive across the wiki | | /lint | Finds broken links, orphans, missing frontmatter, gaps | | /slides | Renders a Marp slide deck | | /brief | Renders a 1-page executive brief | | /chart | Renders a matplotlib chart |


Connect it to Claude Desktop / Cursor / Windsurf (MCP)

obs includes a built-in MCP server (obs-mcp) so any AI tool that speaks MCP can use your vault as a tool.

One-command setup (recommended)

obs setup --vault /absolute/path/to/your/vault

This auto-detects every AI editor you have installed (Claude Desktop, Claude Code, Cursor, Windsurf, Codex, OpenCode) and patches each config in one shot. Preview what it will do first:

obs setup --dry-run --vault /absolute/path/to/your/vault

Restart any editors that were patched. You'll see an 🔨 icon (Claude Desktop) or equivalent — click it to confirm obs_* tools are listed.

Manual setup (if you prefer)

Claude Desktop

# macOS
open ~/Library/Application\ Support/Claude/claude_desktop_config.json

# Windows
notepad %APPDATA%\Claude\claude_desktop_config.json

Add to mcpServers:

{
  "mcpServers": {
    "obs": {
      "command": "obs-mcp",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

Restart Claude Desktop.

Cursor

Add to ~/.cursor/mcp.json (or Settings → MCP → Add Server):

{
  "mcpServers": {
    "obs": {
      "command": "obs-mcp",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "obs": {
      "command": "obs-mcp",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

Claude Code (CLI)

claude mcp add obs obs-mcp --vault /absolute/path/to/your/vault

Remote MCP — expose your vault to Claude.ai, mobile, or any HTTP client

By default obs-mcp speaks stdio — it only works on the same machine. To use your vault from Claude.ai web chat, a second device, or any tool that only supports HTTP MCP, you need three layers:

| Layer | What it does | |---|---| | supergateway (streamableHttp mode) | Wraps obs-mcp stdio as an HTTP MCP endpoint | | OAuth proxy | Serves OAuth 2.1 + PKCE discovery so Claude mobile / web will accept the server | | Cloudflare Tunnel | Exposes localhost over HTTPS with zero port-forwarding |

> Why streamableHttp and not SSE? > SSE keeps a single long-lived connection per client. When a reverse proxy or the client reconnects, supergateway tries to call connect() on the same internal MCP instance and crashes. streamableHttp spawns a fresh stdio process for every POST — no persistent connection, no crash loop, no buffering issues.

> Why OAuth? > Claude mobile and Claude.ai web enforce RFC 8414 OAuth 2.1 discovery (/.well-known/oauth-authorization-server) before accepting any custom MCP server. Without it the server is silently rejected. The proxy auto-approves every authorization — actual security comes from keeping the endpoint URL private.

1. Install dependencies

npm i -g supergateway
# Node 18+ built-ins only needed for the OAuth proxy — no extra packages

2. Create the OAuth proxy

Save the following as ~/bin/obs-oauth-proxy.mjs (no npm dependencies — uses Node built-ins only):

#!/usr/bin/env node
// Minimal OAuth 2.1 + PKCE proxy in front of supergateway.
// Handles /.well-known/oauth-authorization-server + /oauth/* endpoints.
// Proxies everything else to supergateway on MCP_PORT.

import http from 'node:http'
import crypto from 'node:crypto'
import { URL } from 'node:url'

const PORT     = parseInt(process.env.OAUTH_PORT ?? '4321')
const MCP_PORT = parseInt(process.env.MCP_PORT   ?? '4322')
const BASE_URL = process.env.BASE_URL ?? 'https://obs-mcp.yourdomain.com'

const pendingCodes = new Map()
const validTokens  = new Set()

function sendJson(res, status, body) {
  const data = JSON.stringify(body)
  res.writeHead(status, { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) })
  res.end(data)
}

function parseBody(req) {
  return new Promise((resolve, reject) => {
    let buf = ''
    req.on('data', c => buf += c)
    req.on('end', () => {
      try {
        resolve(req.headers['content-type']?.includes('application/x-www-form-urlencoded')
          ? Object.fromEntries(new URLSearchParams(buf))
          : JSON.parse(buf || '{}'))
      } catch { resolve({}) }
    })
    req.on('error', reject)
  })
}

function proxyToMcp(req, res) {
  const opts = {
    hostname: '127.0.0.1', port: MCP_PORT, path: req.url,
    method: req.method, headers: { ...req.headers, host: `localhost:${MCP_PORT}` },
  }
  const proxy = http.request(opts, up => { res.writeHead(up.statusCode, up.headers); up.pipe(res) })
  proxy.on('error', err => {
    if (!res.headersSent) sendJson(res, 502, { error: 'mcp_unreachable', detail: err.message })
    else res.destroy()
  })
  req.pipe(proxy)
}

http.createServer(async (req, res) => {
  const url  = new URL(req.url, `http://localhost:${PORT}`)
  const path = url.pathname

  if (req.method === 'GET' && path === '/.well-known/oauth-authorization-server') {
    return sendJson(res, 200, {
      issuer: BASE_URL,
      authorization_endpoint: `${BASE_URL}/oauth/authorize`,
      token_endpoint: `${BASE_URL}/oauth/token`,
      response_types_supported: ['code'],
      grant_types_supported: ['authorization_code'],
      code_challenge_methods_supported: ['S256'],
      scopes_supported: ['mcp'],
    })
  }

  if (req.method === 'GET' && path === '/oauth/authorize') {
    const redirectUri   = url.searchParams.get('redirect_uri')
    const state         = url.searchParams.get('state')
    const codeChallenge = url.searchParams.get('code_challenge')
    if (!redirectUri) return sendJson(res, 400, { error: 'invalid_request' })
    const code = crypto.randomBytes(20).toString('hex')
    pendingCodes.set(code, { redirectUri, codeChallenge, expires: Date.now() + 600_000 })
    const redirect = new URL(redirectUri)
    redirect.searchParams.set('code', code)
    if (state) redirect.searchParams.set('state', state)
    res.writeHead(302, { Location: redirect.toString() })
    return res.end()
  }

  if (req.method === 'POST' && path === '/oauth/token') {
    const { grant_type, code, code_verifier } = await parseBody(req)
    if (grant_type !== 'authorization_code') return sendJson(res, 400, { error: 'unsupported_grant_type' })
    const stored = pendingCodes.get(code)
    if (!stored || Date.now() > stored.expires) return sendJson(res, 400, { error: 'invalid_grant' })
    if (stored.codeChallenge) {
      if (!code_verifier) return sendJson(res, 400, { error: 'invalid_grant' })
      const hash = crypto.createHash('sha256').update(code_verifier).digest('base64url')
      if (hash !== stored.codeChallenge) return sendJson(res, 400, { error: 'invalid_grant' })
    }
    pendingCodes.delete(code)
    const token = crypto.randomBytes(32).toString('hex')
    validTokens.add(token)
    return sendJson(res, 200, { access_token: token, token_type: 'bearer', expires_in: 31_536_000, scope: 'mcp' })
  }

  // GET on the MCP path → SSE keepalive stream (Claude mobile opens this for server-push)
  if (req.method === 'GET' && path.endsWith('/mcp')) {
    res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' })
    res.write(': connected\n\n')
    const ping = setInterval(() => { if (res.destroyed) return clearInterval(ping); res.write(': ping\n\n') }, 25_000)
    req.on('close', () => clearInterval(ping))
    return
  }

  proxyToMcp(req, res)
}).listen(PORT, '0.0.0.0', () => console.log(`[obs-oauth-proxy] :${PORT} → MCP :${MCP_PORT}`))

3. Create the gateway launch script

Save as ~/bin/run-obs-gateway.sh:

#!/bin/bas

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [markfive-proto](https://github.com/markfive-proto)
- **Source:** [markfive-proto/obsidian-brain-vault](https://github.com/markfive-proto/obsidian-brain-vault)
- **License:** MIT
- **Homepage:** https://supermarcus.ai/brain-os

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.