Skip to main content
skill CX Codex

wiki-setup — Claude Code skill: Obsidian vault setup

Builds the structure and config for an Obsidian wiki vault, and repairs a broken one. Useful on first run or after moving things around.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add Ar9av/obsidian-wiki --skill wiki-setup -a claude-code
Open on GitHub

What wiki-setup does

The skill walks through the initial setup of an Obsidian vault used as a wiki. It asks where the vault should live (OBSIDIAN_VAULT_PATH), where source documents sit (OBSIDIAN_SOURCES_DIR), whether to pull in Claude history, and whether QMD is available for semantic search. Answers go into .env, created from .env.example.

Then it lays out the directories: concepts, entities, skills, references, synthesis, journal, projects, _archives, _raw, _staging and .obsidian. The .obsidian folder is what makes Obsidian recognise the vault, and _raw holds rough drafts that wiki-ingest later promotes. Special files such as index.md come from obsidian-wiki setup --vault <path>, which also takes a timezone via --timezone.

Watch the QMD part. If QMD_WIKI_COLLECTION is set, verify the collection excludes _raw/. The vault contains _raw/, so a plain qmd collection add <vault> quietly merges the wiki collection with the papers collection, and wiki-query cites them as separate layers. There is no --ignore flag, so you edit the ignore block in ~/.config/qmd/index.yml by hand and run qmd update. One more thing: with WIKI_STAGED_WRITES=true, new pages land in _staging/ and stay out of the Obsidian graph until /wiki-stage-commit promotes them.

What it helps with

  • stand up an Obsidian vault structure from scratch
  • create .env from .env.example and fill in the paths
  • repair a vault after a broken setup
  • keep _raw/ out of the QMD collection so layers stay separate
  • route new pages through _staging/ for a team wiki

Example prompts for the agent

  • set up a new Obsidian vault for the wiki
  • check that the QMD collection does not index _raw/
  • turn on WIKI_STAGED_WRITES and show me how to promote pages

How to install wiki-setup

1Skills CLI (Vercel)

npx skills add Ar9av/obsidian-wiki --skill wiki-setup -a claude-code

2Manually: put the files in place

~/.claude/skills/wiki-setup/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/wiki-setup/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about wiki-setup

How do I install wiki-setup in Claude?

Run npx skills add Ar9av/obsidian-wiki --skill wiki-setup -a claude-code. The skill lands at ~/.claude/skills/wiki-setup/SKILL.md.

What does wiki-setup do?

It creates .env and the Obsidian vault directory tree, and repairs an existing setup. It also checks the QMD configuration and the writing profile.

What do I need to provide during setup?

The vault path, the directories holding source documents, optionally the Claude history path and QMD settings. Timezone goes into index.md via obsidian-wiki setup --timezone <IANA name>.

Source text

SKILL.md · MIT
---
name: wiki-setup
description: >
  Initialize or repair an Obsidian wiki vault's required structure and configuration. Use for new-vault setup, .env/config creation, reconfiguration, or broken setup recovery.
---

# Obsidian Setup — Vault Initialization

You are setting up a new Obsidian wiki vault (or repairing an existing one).

## Step 1: Create .env

If `.env` doesn't exist, create it from `.env.example`. Ask the user for:

1. **Where should the vault live?** → `OBSIDIAN_VAULT_PATH`
   - Default: `~/Documents/obsidian-wiki-vault`
   - Must be an absolute path (after expansion)

2. **Where are your source documents?** → `OBSIDIAN_SOURCES_DIR`
   - Can be multiple paths, comma-separated
   - Default: `~/Documents`
   - Local git repo clones (public or private, any host) can be listed here too — clone
     the repo locally first, then add its path. See "Ingesting Git Repositories" in
     `wiki-ingest/SKILL.md` for how repo sources are handled.

3. **Want to import Claude history?** → `CLAUDE_HISTORY_PATH`
   - Default: auto-discovers from `~/.claude`
   - Set explicitly if Claude data is elsewhere

4. **Have QMD installed?** → `QMD_WIKI_COLLECTION` / `QMD_PAPERS_COLLECTION` / `QMD_TRANSPORT`
   - Optional. Enables semantic search in `wiki-query` and source discovery in `wiki-ingest`.
   - Default to `QMD_TRANSPORT=mcp` unless the user wants the agent to call the local `qmd` CLI directly.

5. **Which timezone should the wiki's timestamps use?** → `timezone:` in `index.md` (not `.env`)
   - Optional. An IANA name such as `America/Detroit`; blank means UTC in the `Z` spelling.
   - Lives in the vault so it applies to every writer (CLI, server, Python API) and travels with it.
   - Written by `obsidian-wiki setup --timezone <name>` (step 3 below) or by hand; `obsidian-wiki memory now` prints stamps in it.
   - If using CLI mode, set `QMD_CLI_SEARCH_MODE=quality` by default; suggest `balanced` if reranking is too slow.
   - If unsure, skip for now — both skills fall back to `Grep` automatically.
   - Install instructions: see `.env.example` (QMD section).
   - **If `QMD_WIKI_COLLECTION` is set, verify the collection excludes `_raw/`.** The wiki
     collection and papers collection must stay disjoint — `wiki-query` cites them as
     separate layers (compiled knowledge vs. raw staging), and `OBSIDIAN_VAULT_PATH` contains
     `_raw/`, so a plain `qmd collection add <vault>` silently merges the two.
     Read `~/.config/qmd/index.yml`, find the entry for `$QMD_WIKI_COLLECTION`, and check its
     `ignore` list includes `_raw/**` (and ideally `log.md`, which has no semantic value). If
     the collection doesn't exist yet, create it (`qmd collection add "$OBSIDIAN_VAULT_PATH"
     --name <collection-name>`), then add the `ignore` block to `index.yml` by hand — `qmd`
     has no `--ignore` flag and refuses a second `collection add` on a path that already has
     one, so editing the YAML is the only way to scope it. Run `qmd update` after editing.
     If the collection already exists without the `ignore` block, tell the user their
     wiki collection is indexing `_raw/` (including `_raw/_archived/` drafts left behind by
     `wiki-ingest`) and offer to add the `ignore` block and re-run `qmd update`.

5. **Token budget warning threshold?** → `WIKI_TOKEN_WARN_THRESHOLD`
   - Default: `100000` (warn when full-wiki read would cost > 100K tokens)
   - Set to `0` to disable the warning entirely
   - `wiki-status` shows a token footprint table and emits this warning automatically

6. **Enable staged writes?** → `WIKI_STAGED_WRITES`
   - Default: unset / `false` (pages written directly to their final location)
   - Set to `true` for team wikis, high-stakes domains, or any vault where the human wants final say on every LLM-written page
   - When enabled: all new/updated pages land in `_staging/` first; run `/wiki-stage-commit` to review and promote them
   - `wiki-status` shows a "Staged writes pending" count when files are waiting

After resolving config, assign the global config directory with the exact
`obsidian_wiki_config_dir` algorithm from the Config Resolution Protocol in
`.skills/llm-wiki/SKILL.md`. Create the shared writing profile only when it does not
already exist. Preserve an existing `$GLOBAL_CONFIG_DIR/WRITING.md`; never overwrite it
and do not ask additional writing-style questions.

Use `OBSIDIAN_WIKI_REPO` when it was loaded from config. When it is absent, derive the
absolute repository/data root from this loaded skill's absolute path, distinguishing the
packaged `<root>/skills/wiki-setup/SKILL.md` layout from the source
`<root>/.skills/wiki-setup/SKILL.md` layout. Then check both canonical template layouts:

- Packaged install: `<root>/skills/llm-wiki/references/WRITING.md`
- Source checkout: `<root>/.skills/llm-wiki/references/WRITING.md`

```bash
GLOBAL_CONFIG_DIR="$(obsidian_wiki_config_dir)"
mkdir -p "$GLOBAL_CONFIG_DIR"

SKILL_FILE="<absolute path of this loaded wiki-setup/SKILL.md>"
SKILL_DIR="$(cd "$(dirname "$SKILL_FILE")" && pwd)"
if [ -n "${OBSIDIAN_WIKI_REPO:-}" ]; then
  WIKI_ROOT="${OBSIDIAN_WIKI_REPO%/}"
else
  case "$SKILL_DIR" in
    */.skills/wiki-setup) WIKI_ROOT="${SKILL_DIR%/.skills/wiki-setup}" ;;
    */skills/wiki-setup) WIKI_ROOT="${SKILL_DIR%/skills/wiki-setup}" ;;
    *) echo "Cannot derive writing-profile template root from $SKILL_DIR" >&2; exit 1 ;;
  esac
fi

WRITING_TEMPLATE=""
for candidate in \
  "$WIKI_ROOT/skills/llm-wiki/references/WRITING.md" \
  "$WIKI_ROOT/.skills/llm-wiki/references/WRITING.md"
do
  if [ -f "$candidate" ]; then
    WRITING_TEMPLATE="$candidate"
    break
  fi
done
[ -n "$WRITING_TEMPLATE" ] || { echo "Writing profile template not found under $WIKI_ROOT" >&2; exit 1; }

WRITING_PROFILE="$GLOBAL_CONFIG_DIR/WRITING.md"
if [ ! -e "$WRITING_PROFILE" ]; then
  cp "$WRITING_TEMPLATE" "$WRITING_PROFILE"
fi
```

## Step 2: Create Vault Directory Structure

```bash
mkdir -p "$OBSIDIAN_VAULT_PATH"/{concepts,entities,skills,references,synthesis,journal,projects,_archives,_raw,_staging,.obsidian}
```

- `.obsidian/` — Obsidian's own config. Creates vault recognition.
- `projects/` — Per-project knowledge (populated during ingest).
- `_archives/` — Stores wiki snapshots for rebuild/restore operations.
- `_raw/` — Staging area for unprocessed drafts. Drop rough notes here; `wiki-ingest` will promote them to proper wiki pages and move the originals into `_raw/_archived/` (created on first use).
- `_staging/` — Review queue for LLM-written pages when `WIKI_STAGED_WRITES=true`. Pages here are not visible in Obsidian's graph until promoted via `/wiki-stage-commit`.

## Step 3: Create Special Files

`obsidian-wiki setup --vault <path> [--timezone <IANA name>]` creates all of these in one go. The templates below are what it writes, for setups done by hand.

### index.md

```markdown
---
title: Wiki Index
---

# Wiki Index

*This index is automatically maintained. Last updated: TIMESTAMP*

## Concepts

*No pages yet. Use `wiki-ingest` to add your first source.*

## Entities

## Skills

## References

## Synthesis

## Journal
```

### log.md

```markdown
---
title: Wiki Log
---

# Wiki Log

- [TIMESTAMP] INIT vault_path="OBSIDIAN_VAULT_PATH" categories=concepts,entities,skills,references,synthesis,journal
```

### hot.md

```markdown
---
title: Hot Cache
updated: TIMESTAMP
---

# Hot Cache

*A ~500-word semantic snapshot of recent activity. Updated after every major write operation.*

## Recent Activity

- [TIMESTAMP] INIT — vault created at OBSIDIAN_VAULT_PATH

## Active Threads

*None yet — start ingesting sources to populate.*

## Key Takeaways

*None yet.*

## Flagged Contradictions

*None yet.*
```

### .manifest.json

Create an empty manifest so ingest skills have a tracking file to append to and
`obsidian-wiki doctor` reports the vault as complete (it treats `.manifest.json`
as a required core file):

```bash
printf '{}\n' > "$OBSIDIAN_VAULT_PATH/.manifest.json"
```

## Step 4: Create .obsidian Configuration

Create minimal Obsidian config for a good out-of-box experience:

### .obsidian/app.json
```json
{
  "strictLineBreaks": false,
  "showFrontmatter": false,
  "defaultViewMode": "preview",
  "livePreview": true
}
```

### .obsidian/appearance.json
```json
{
  "baseFontSize": 16,
  "enabledCssSnippets": ["obsidian-wiki-folders"]
}
```

### Folder colors and graph defaults

`obsidian-wiki setup` also writes `.obsidian/snippets/obsidian-wiki-folders.css` (one color per category folder in the file explorer, `_` folders dimmed) and `.obsidian/graph.json` (the same colors in graph view, with `_raw/`, `_archives/`, `_staging/`, `_meta/`, `index`, `log`, and `hot` filtered out). If the CLI is available, run `obsidian-wiki setup --vault "$OBSIDIAN_VAULT_PATH"` rather than writing them by hand. Never overwrite an existing `.obsidian` file; to recolor later, use `graph-colorize`.

## Step 5: Recommend Obsidian Plugins

Tell the user about these recommended community plugins (they install manually):

1. **Dataview** — Query page metadata, create dynamic tables. Essential for a wiki.
2. **Graph Analysis** — Enhanced graph view for exploring connections.
3. **Templater** — If they want to create pages manually using templates.
4. **Obsidian Git** — Auto-backup the vault to a git repo.

## Step 6: Verify Setup

Run a quick sanity check:
- [ ] Vault directory exists with: `concepts/`, `entities/`, `skills/`, `references/`, `synthesis/`, `journal/`, `projects/`, `_archives/`, `_raw/`
- [ ] `index.md` exists at vault root
- [ ] `index.md` frontmatter carries `timezone:` if the user chose one (`obsidian-wiki memory status` shows the zone in use)
- [ ] `log.md` exists at vault root
- [ ] `hot.md` exists at vault root
- [ ] `.manifest.json` exists at vault root (empty `{}` is fine)
- [ ] `.env` has `OBSIDIAN_VAULT_PATH` set
- [ ] `.obsidian/` directory exists
- [ ] `_staging/` directory exists (required even when `WIKI_STAGED_WRITES` is not set — created on setup for future use)
- [ ] `WRITING_PROFILE` exists at the resolved global config directory
- [ ] Source directories (if configured) exist and are readable

Report the results, including the resolved absolute `WRITING_PROFILE` path, and tell the user they can now:
1. Open the vault in Obsidian (File → Open Vault → select the directory)
2. Run `wiki-status` to see what's available to ingest
3. Run `wiki-ingest` to add their first sources
4. Run `claude-history-ingest` to mine their Claude conversations
5. Run `codex-history-ingest` to mine their Codex sessions (if they use Codex)
6. Run `wiki-status` again anytime to check the delta

## Optional: Install the Stop Hook (Auto-Capture)

Ask the user: **"Want to auto-capture findings at session end?"**

If yes, install the Stop hook into their global Claude Code settings so that every session
with meaningful work automatically prompts `/wiki-capture --quick` before closing.

**What the hook does:** reads the session transcript on Stop, counts file edits and shell
calls, and if significant work happened, asks Claude to run `/wiki-capture --quick` once.
The `wiki-capture` quick-mode KEEP/SKIP gate prevents noise — routine or
inconclusive sessions are skipped automatically.

**Installation steps:**

1. Find the obsidian-wiki repo path. If `OBSIDIAN_WIKI_REPO` is set in config, use that.
   Otherwise, check common locations: `~/Documents/projects/obsidian-wiki`, `~/obsidian-wiki`,
   or ask the user.

2. Locate the `wiki-stop-capture.sh` script. Its path differs between a pip/uv install and a
   source checkout, so check both layouts under `<REPO_PATH>` and use the first that exists:

   - `<REPO_PATH>/hooks/wiki-stop-capture.sh` — packaged install (`OBSIDIAN_WIKI_REPO`
     points at the bundled `_data/` dir, which ships the hook under `hooks/`).
   - `<REPO_PATH>/.claude/hooks/wiki-stop-capture.sh` — source checkout.

   If neither exists (e.g. an older wheel that predates bundling the hook), fetch the canonical
   copy to a stable location and point at that instead. Use the global config dir from the
   Config Resolution Protocol in `llm-wiki/SKILL.md` (XDG-style `~/.config/obsidian-wiki` by
   default, or the legacy `~/.obsidian-wiki` if that already exists):

   ```bash
   CONFIG_DIR="$( [[ -d "$HOME/.obsidian-wiki" && ! -e "${XDG_CONFIG_HOME:-$HOME/.config}/obsidian-wiki" ]] && echo "$HOME/.obsidian-wiki" || echo "${XDG_CONFIG_HOME:-$HOME/.config}/obsidian-wiki" )"
   mkdir -p "$CONFIG_DIR/hooks"
   curl -fsSL https://raw.githubusercontent.com/Ar9av/obsidian-wiki/main/.claude/hooks/wiki-stop-capture.sh \
     -o "$CONFIG_DIR/hooks/wiki-stop-capture.sh"
   chmod +x "$CONFIG_DIR/hooks/wiki-stop-capture.sh"
   ```

   Use the resolved absolute path as `<HOOK_PATH>` below.

3. Merge the hook entry into `~/.claude/settings.json`:

```json
{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash <HOOK_PATH>"
          }
        ]
      }
    ]
  }
}
```

   If `~/.claude/settings.json` already exists and has a `hooks.Stop` array, **append** the new
   entry rather than replacing — don't clobber existing hooks.

   > **Note — expect a duplicate nudge inside this repo.** The obsidian-wiki repo ships its own
   > git-tracked `.claude/settings.json` registering the same Stop hook at a relative path. Claude
   > Code *merges* project-level and user-level hook config rather than letting one override the
   > other, so sessions ending inside the repo itself fire both registrations. This is expected and
   > harmless — the hook claims an atomic per-session sentinel, so only one nudge is emitted. Leave
   > both in place: removing the project entry dirties a tracked framework file and disables capture
   > for anyone who clones the repo without doing the global install.

4. Confirm: "Stop hook installed. Claude Code will prompt `/wiki-capture --quick` at the
   end of any session where you write files or run ≥ 4 shell commands."

**To uninstall later:** remove the hook entry from `~/.claude/settings.json` or set
`WIKI_STOP_CAPTURE=false` in your shell to skip capture for a single session
(`HIVEMIND_CAPTURE=false` is still honoured).

## Optional: Configure GitHub Sync

Ask the user: **"Want to sync your vault to a private GitHub repo?"**

The vault is plain markdown, so pushing it to git gets you version history, backup, and
cross-device sync for free. This is opt-in — skip it if the user declines or has no repo ready.

If yes:

1. Ask for the repo URL (e.g. `https://github.com/you/my-wiki.git`). Recommend it be **private**
   if the vault holds personal notes.
2. Run the CLI, which handles `git init`, a default `.gitignore`, and wiring the `origin` remote —
   this is the same code path `obsidian-wiki setup`'s interactive prompt and `setup.sh` use, so
   there's one implementation to keep correct (see issue #153 for why that matters):
   ```bash
   obsidian-wiki sync-setup "<repo-url>" --vault "$OBSIDIAN_VAULT_PATH"
   ```
   If the `obsidian-wiki` binary isn't on PATH (source checkout without an install), run it from
   the repo instead: `PYTHONPATH="$OBSIDIAN_WIKI_REPO" python3 -m obsidian_wiki.cli sync-setup ...`
   using whichever of `OBSIDIAN_WIKI_REPO` or a local checkout path is available.
3. Tell the user they can run `obsidian-wiki sync` any time afterward to commit and push pending
   vault changes (stages everything, commits with a timestamp, pushes). There's no config file to
   check for sync status — the vault's own `git remote` is the source of truth.

## Optional: Refresh QMD After Setup

If `QMD_WIKI_COLLECTION` is configured and the local QMD CLI is available, run `qmd update` after the initial vault files exist so the fresh vault is immediately queryable. No embedding pass is usually needed at setup time because the vault starts empty, so a plain update is enough unless you have already populated pages. Before running it, confirm the `_raw/` exclusion described in Step 1.4 is in place — otherwise this update indexes the (currently empty) staging directory into the wiki collection too, and every future draft dropped there joins it silently.

© Ar9av · MIT · Ar9av/obsidian-wiki

Similar skills

All skills for Agent setup: memory, context, orchestration →

From the same set38

llm-wiki The schema side of a personal Obsidian wiki: source layers, categories, project trees and a page template. Use it when you're deciding how knowledge should be stored. CX Codex +1 4,100installs wiki-query Searches and synthesizes answers from a compiled Obsidian vault using graph indexing without modifying existing notes. CX Codex +1 3,600installs wiki-ingest Pulls documents, folders, pasted text and URLs into an Obsidian wiki, turning them into linked pages and skipping sources that have not changed. CX Codex +1 3,600installs wiki-lint Audits Obsidian vault health by identifying broken wikilinks, orphan pages, missing frontmatter, and stale content without reading every file in full. CX Codex +1 3,500installs wiki-update Distills architecture decisions and project context from your current repository into an Obsidian vault. Useful when you need durable notes without manual copy-pasting. CX Codex +1 3,400installs wiki-status Reports what an Obsidian wiki has ingested, what changed since the last run, and which pages went stale. Run it before deciding whether to append or rebuild the vault. CX Codex +1 3,400installs cross-linker Finds wiki pages that ought to reference each other but don't, then inserts the missing [[wikilinks]]. Useful right after a bulk import of notes. CX Codex +1 3,300installs tag-taxonomy This skill audits and normalizes tags across an Obsidian vault using a controlled vocabulary. It spots aliases, cleans up excess tags, and suggests canonical labels for new notes. CX Codex +1 3,200installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor