Map-of-Content (MOC) curation for Obsidian vaults. Use when creating a MOC for a tag, extending with orphans, fixing legacy MOC tags, or analyzing coverage.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add laurigates/claude-plugins --skill vault-mocs --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Vault Mocs?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/laurigates-vault-mocs)More formats (shields.io, HTML) on the badges page.
---
created: 2026-04-17
modified: 2026-06-28
reviewed: 2026-06-28
name: vault-mocs
description: "Map-of-Content (MOC) curation for Obsidian vaults. Use when creating a MOC for a tag, extending with orphans, fixing legacy MOC tags, or analyzing coverage."
user-invocable: false
allowed-tools: Read, Edit, Write, Grep, Glob
---
# MOC Curation
## When to Use This Skill
| Use this skill when... | Use the alternative instead when... |
|---|---|
| Creating or extending a Map of Content hub for a tag category | Reconnecting individual orphaned notes without building a hub — use `vault-orphans` |
| Migrating legacy `🗺️` MOC tags to canonical `📝/moc` | Renaming or consolidating non-MOC tags across the vault — use `vault-tags` |
| Auditing MOC coverage and linking orphans into existing hubs | Repairing broken `[[...]]` references inside an existing MOC — use `vault-wikilinks` |
A Map of Content (MOC) is a structured hub note that organizes related content via wikilinks. It's the primary navigation surface of a mature Obsidian vault — more useful than tags, more discoverable than search.
## Canonical MOC Shape
```markdown
---
tags: [📝/moc]
---
# Neovim MOC
Central hub for Neovim configuration, plugins, and workflows.
## Core
- [[Neovim]] — base configuration
- [[Lazy.nvim]] — plugin management
## Plugins
- [[nvim-treesitter]]
- [[Mason LSP]]
## Keybindings and Workflow
- [[Neovim Keybindings]]
- [[Neovim Session Management]]
```
Rules:
1. Tag is **exactly** `📝/moc` — not `🗺️` (legacy), not `MOC` (flat), not `📝/MOC` (wrong case).
2. File lives in `Zettelkasten/` (personal) or `work/MOC/` (work).
3. Filename is `{Subject} MOC.md` — suffix, not prefix.
4. Body has a one-paragraph description, then `##` section headings, then bullet-list wikilinks.
5. Never has `id:` or other legacy frontmatter.
## Legacy MOC Fixups
| Issue | Fix |
|-------|-----|
| `tags: 🗺️` | Rewrite to `tags: [📝/moc]` |
| `tags: [🗺, 📝/moc]` | Deduplicate to `tags: [📝/moc]` |
| MOC in `work/z/` instead of `work/MOC/` | Move file |
| Uses `[[Kanban/Foo]]` path-qualified links | Rewrite to `[[Foo]]` when basename unique |
## Coverage Analysis
For each tag category (`🛠️/`, `🔌/`, `💻/`, etc.), the vault-agent `mocs.analyze_mocs` analyzer reports how many tagged notes are NOT linked from any MOC. High uncovered counts indicate:
- **Missing MOC** — the category has 10+ notes but no MOC exists.
- **Stale MOC** — the MOC exists but hasn't been updated with recent additions.
- **Tag mismatch** — notes are tagged but don't belong in the relevant MOC.
## Offline Fallback (App Closed)
The detection methodology above is unchanged — only the **data source** changes when Obsidian (and its `obsidian` CLI / live link index) is closed. The `obsidian` CLI and `vault-agent` analyzers are the **live-index** path; parsing the `.md` corpus directly with Glob/Grep is the **deterministic headless default**, and for batch/scheduled audits it is often the better choice (reproducible, free of app/index state). `vault-frontmatter` already operates this way.
Parse the corpus directly:
- **Frontmatter** — read each note's YAML block between the leading `---` fences; extract `tags`, `aliases`, `context`. See `vault-frontmatter` for YAML-block mechanics.
- **Wikilinks** — match `[[Target]]`, `[[Target|Alias]]`, `[[Target#Heading]]`, `[[folder/Target]]`, and `![[embed]]`. Resolve each target to a note by **basename**, then **relative path**, then **alias** (from frontmatter), all **case-insensitive**. Resolve `![[embed]]` against attachments as well as notes — the attachment folder is per-vault configurable, so read it from `.obsidian/app.json` (`attachmentFolderPath`) and fall back to the vault root / `Files/` only when that key is unset.
Coverage analysis offline: for each tag category, count notes whose parsed frontmatter `tags` place them in the category but which no `📝/moc`-tagged note links to (via the resolution cascade). That is the same uncovered count `mocs.analyze_mocs` produces from the live index.
## Creating a New MOC
Thresholds (heuristic):
- ≥ 10 tagged notes in the category AND
- No existing MOC covers them AND
- Notes share enough subject to belong in one hub
If all three hold, create `Zettelkasten/{Category} MOC.md`:
```markdown
---
tags: [📝/moc]
---
# {Category} MOC
{One-paragraph framing of the category.}
## {Section}
- [[Note1]]
- [[Note2]]
```
Pick 2–4 `##` sections that reflect natural groupings within the notes — don't force a deep hierarchy.
## Extending an Existing MOC
When the analyzer reports orphaned notes that belong in an existing MOC:
1. Read the MOC and find the most appropriate `##` section (or create a new one if 3+ notes fit a new grouping).
2. Add wikilinks one per bullet, alphabetical within the section.
3. Keep descriptions brief — one short phrase per link at most.
Don't add a "See also" or "Random" section as a dumping ground. If a note doesn't fit any section, reconsider whether it belongs in this MOC at all.
## Never Do
- **Don't create nested MOCs** (MOC of MOCs) unless the vault has 20+ MOCs that justify a top-level index.
- **Don't dataview-generate MOC content** in place of hand-curated links. Dataview is fine for supplementary sections ("Recent notes in this category"), but the primary content should be hand-picked.
- **Don't add the `📝/moc` tag to a note that isn't actually a MOC** — it pollutes MOC inventories.
- **Don't rename existing MOCs** without updating every link (use `vault-wikilinks` rewrite patterns).
## Commit Messages
| Action | Commit |
|--------|--------|
| New MOC | `feat(mocs): add {Category} MOC covering N notes` |
| Fixup tag | `fix(mocs): 🗺️ → 📝/moc on work MOCs` |
| Add orphans | `feat(mocs): link 12 notes into Neovim MOC` |
| Rewrite path-qualified link | `fix(mocs): unqualify [[Kanban/X]] → [[X]] across 6 MOCs` |
## Safety
- Never modify a MOC's section structure without the user's input — they reflect the user's mental model.
- When adding links, preserve the user's existing sort order (alphabetical, chronological, by-importance — look at the first section to infer).
- Don't link notes that are tagged but clearly off-topic for the MOC.
## Related Skills
- **vault-orphans** — identifies candidate notes to add to MOCs
- **vault-tags** — tag taxonomy that drives coverage analysis
- **vault-wikilinks** — link syntax and safe-rewrite rules
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!