obsidian-second-brain turns an Obsidian vault into persistent, searchable memory for Claude Code and other command-line coding agents, storing knowledge as linked Markdown notes. It is for developers, founders, writers, and researchers who want agents to retain project context across sessions. Its catalogue entries provide commands, hooks, a plugin, a skill, and instructions for capturing, finding, and maintaining that memory.
Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
git clone --depth 1 https://github.com/eugeniughelbur/obsidian-second-brainWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/commands/eugeniughelbur/obsidian-second-brain/obsidian-health)<a href="https://agentmods.dev/commands/eugeniughelbur/obsidian-second-brain/obsidian-health"><img src="https://agentmods.dev/badge/commands/eugeniughelbur/obsidian-second-brain/obsidian-health/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/commands/eugeniughelbur/obsidian-second-brain/obsidian-health"><img src="https://agentmods.dev/badge/commands/eugeniughelbur/obsidian-second-brain/obsidian-health.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00022 | $0.02517 |
| Opus 5.5 | $0.00009 | $0.01007 |
| Sonnet 5.5 | $0.00004 | $0.00503 |
| Haiku 4.5 | $0.00002 | $0.00252 |
Grade A, and why
obsidian-health scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 17d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 46 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Use the obsidian-second-brain skill. Execute /obsidian-health:
- Read
_CLAUDE.mdfirst to find the vault path - Run the health scan from the skill root (its absolute path was given at session start as Skill root; substitute it for
SKILL_ROOT):uv run --directory "SKILL_ROOT" scripts/vault_health.py --path ~/path/to/vault --json(replace vault path with the one from_CLAUDE.md)- Large or noisy vault? If the scan surfaces thousands of findings from directories the user does not maintain by hand (atomic-card pools, backup snapshots, imported dumps), do NOT hardcode fixes. Offer to write a
<vault>/.vault-config.jsonthat extends the exclude list:{"exclude-dirs": ["_card-pool"], "exclude-paths": ["Archive/Backup"]}.exclude-dirsmatches directory names anywhere in the tree;exclude-pathsmatches vault-relative path prefixes. Both are additive - the built-in excludes always apply - and a missing or malformed file is ignored silently. Re-run the scan afterward. source_payloadfindings? (#194) Three different problems under one type. Anerrornaming one source means the note declarescapture_scope: full-localorbounded-localand has essentially no body - it claims evidence it does not hold, so re-capture it or setcapture_scope: url-onlyand say so plainly. Awarningnaming a source plus the notes that link it means active knowledge rests on aurl-onlyrecord: the vault kept the locator, not the evidence. Offer to re-capture the source, or to mark the dependent claims as URL-backed; never resolve it by copying a complete copyrighted work. The singleinfoline counting sources with nocapture_scopeis every source written before the field existed - fill them in as you touch them, do not sweep the vault."source_policy": "strict-local"in.vault-config.jsonraises the last two by one severity.source_qualityfindings? (#258) Awarningnames a concept, synthesis or other note that cites only sources gradedspeculation: provenance unknown, derived or conflicting. It is not a claim that the note is wrong. Offer to corroborate its claims with a better source (the bounded lateral read inreferences/source-quality-check.md, only on an explicit yes), or to say in the note that they are unverified. A source with nosource_qualityis unjudged and never reported."source_quality_policy": "silent"in.vault-config.jsonmutes the check.rewrite_policy: unattendedinfo line? The vault has opted out of the confirm-before-rewrite gate in/obsidian-ingest(#250) and reviews rewrites through its own layer. Nothing to fix; the line is there so a reader of the report knows the vault runs without the gate. Remove the key from.vault-config.jsonto restore the default.
- Large or noisy vault? If the scan surfaces thousands of findings from directories the user does not maintain by hand (atomic-card pools, backup snapshots, imported dumps), do NOT hardcode fixes. Offer to write a
- Parse the JSON output and split findings into categories
- Spawn parallel subagents to handle each category simultaneously:
- Wanted-notes agent: the script reports
wanted_noteitems - links to a note that does not exist yet. These are NOT errors: in a wiki-style vault you link a thing the moment you mention it, so wanted notes are a demand-ranked wishlist of pages worth writing, not breakage. Triage them withuv run --directory "SKILL_ROOT" scripts/triage_links.py --path <vault> --limit N, which sorts each into keep (a deliberate seed, leave it), create (referenced enough to deserve a real note now), or delete (junk or a typo - fix the link). Report-only by default; needsANTHROPIC_API_KEY. Headless on purpose: it can run unattended or on a schedule. The goal is to triage the backlog, never to drive the count to zero. - Duplicates agent: confirm duplicates are truly the same concept, not just similar names
- Taxonomy agent: only fires when
<vault>/_meta/taxonomy.mdexists (format inreferences/taxonomy-format.md) - the script'stag_synonymandtag_not_in_taxonomyfindings are empty otherwise, so a vault without the file sees nothing.tag_synonymmeans a note's tag is a known synonym of a canonical tag: the fix is unambiguous, so offer to rewrite that note'stags:frontmatter to the canonical form, per note, with explicit confirmation before editing - never batch-rewrite across the vault unattended.tag_not_in_taxonomymeans the tag matches neither a canonical tag nor a synonym: report it as informational only - it may be a legitimate new tag - and never auto-fix it; the taxonomy file is a human-curated vocabulary, not something this command edits on its own. - Frontmatter agent: identify notes missing required fields by type. If the script reports a
code_fence_wrappednote (frontmatter trapped inside a leading```markdownfence), the fix is to unwrap it - strip the opening fence line and the matching closing```so the inner---frontmatter and body become real markdown. Never add a new frontmatter block to a wrapped note - that produces duplicate frontmatter and leaves the body trapped. If the note already has both a prepended frontmatter block and an inner wrapped one, merge them (keep the richer fields) and unwrap. - Staleness agent: check overdue tasks and unfilled template syntax
- Orphans agent: check orphaned notes and empty folders
- Contradictions agent: scan Key Decisions sections and reference/concept notes (the concept or knowledge folder per
references/folder-map.md- wiki-stylewiki/concepts/, Obsidian-styleKnowledge/) for claims that conflict with each other or have been superseded by newer sources - Typed-edge lint agent: run
uv run --directory "SKILL_ROOT" scripts/link_graph.py --path <vault> --lint, which validates therelations:typed-edge layer (seereferences/ai-first-rules.mdRule 6 § Typed edges). It returnsfindings(each withseverity,kind,note,target,type,detail) and asummary. Map them into the severity groups below:contradiction(A and B claim the same asymmetric type about each other) is 🔴 Critical;unknown_type,dangling_target, andself_edgeare 🟡 Warning (fix the type name, the target link, or drop the self-edge);missing_inverseis ⚪ Info (offer to add the reciprocal edge on the target note, never required). If the vault uses norelations:blocks yet, this returns zero findings - not an error. - Concept gaps agent: find terms mentioned 3+ times across different notes that lack a dedicated page - these are missing concepts the vault should have
- Stale claims agent: compare reference/concept notes (the concept or knowledge folder per
references/folder-map.md- wiki-stylewiki/concepts/, Obsidian-styleKnowledge/) against their source dates - flag any note older than 6 months that references fast-moving topics (tools, APIs, pricing, team structure) - Freshness agent: run the freshness lint -
uv run --directory "SKILL_ROOT" scripts/freshness_lint.py --path <vault> --json- which enforcesreferences/freshness-policy.md: every stored fact must be timeless, dated, or a pointer. FRESH-1 errors are present-tense claims about fast facts (counts, statuses, balances) with noas ofstamp - the sentences that silently become lies. Report the top offenders grouped by folder; offer to fix by adding a stamp, converting to a pointer (where truth lives + last observed value), or moving the claim into a dated note. For aged stamps (FRESH-2 warnings) run the refresh loop from the policy: re-observe (check the source, update value + stamp), convert (keep only the pointer), or retire (move into a dated note as history). Never delete - restamp, convert, or mark superseded
- Wanted-notes agent: the script reports
- Merge results and group by severity:
- 🔴 Critical: unfilled template syntax, contradictions between notes, typed-edge contradiction cycles, code-fence-wrapped notes (frontmatter trapped in a fence)
- 🟡 Warning: duplicates, stale tasks, missing frontmatter, stale claims, concept gaps, freshness violations (undated fast facts, aged stamps), typed-edge problems (unknown type, dangling target, self-edge), tag-synonym findings (a tag that should fold to its canonical form per
_meta/taxonomy.md), invalid tags (digits-only, dots, spaces - Obsidian renders these broken with no error; fix by prefixing a word or replacing the separator with-) - ⚪ Info: wanted notes (linked but unwritten - a wishlist, not errors), orphaned notes, empty folders, missing inverse edges, tags not in the taxonomy (informational, not necessarily wrong)
- For safe fixes (missing frontmatter, unwrapping code-fence-wrapped notes, obvious duplicates, creating pages for concept gaps), offer to fix automatically. For a
code_fence_wrappednote, unwrap the fence rather than adding frontmatter (see the Frontmatter agent note above). - For destructive fixes (archiving, merging, resolving contradictions), list them and ask for explicit confirmation first
- Append to the operation log: if
Logs/exists write**HH:MM** - health | X critical, Y warnings, Z infotoLogs/YYYY-MM-DD.md; otherwise append## [YYYY-MM-DD] health | X critical, Y warnings, Z infotolog.md
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 17d ago Changed · +1 lines ff38e0250095
- 1mo ago Changed · +1 lines 268b961687ad
- 1mo ago Changed · +2 lines 21822d482aad
- 1mo ago First seen · 42 lines · 22 tokens per session scan A b69f3e572a32
obsidian-health is a command published in the GitHub repository eugeniughelbur/obsidian-second-brain (4,996 stars, last pushed today), licensed MIT. It adds 22 tokens to every session and 2,517 once invoked, about $0.0001 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other commands, from other repositories
patterns
Scan recent sessions for recurring patterns and turn them into captures (rules, concept notes, writing seeds).
curate
A command for maintaining a file-based knowledge wiki. It can review pages, shorten overlong material, manage page lifecycles, find possible contradictions, and rebuild weak connections between notes.
ingest
A command for adding information to a file-based knowledge wiki from web pages, files, or text notes. It classifies the material, updates or creates wiki pages, and adds links between related pages.
onboard
An interview-based setup command for an LLM Wiki, a notes system designed for use with language models. It asks about your wiki, files, working mode, and personal context, then fills in the setup details.
refresh-context
Re-snapshot Core Context.md from (optional) mothership system files + key personal essays. Run when mothership files change, when new essays signal philosophy shift, or when snapshot is older than 30 days.
wiki-req
Capture and decompose a concept into atomic, traceable wiki requirements. Clarifies ambiguous requirements, splits them into atomic pieces, and persists them as wiki/requirements/ pages with status tracking.