$npx -y skills add AgriciDaniel/claude-obsidian --skill wiki-cliDefault vault-mutation transport for claude-obsidian v1.7+. Wraps the Obsidian CLI (Obsidian 1.12+) as the preferred way to read, write, search, and modify vault notes from Claude — no MCP server, no REST API plugin, no TLS workarounds. Falls back to direct filesystem Read/Write/
| 1 | # wiki-cli: Default Transport Layer |
| 2 | |
| 3 | claude-obsidian v1.7+ standardizes on the **Obsidian CLI** (shipped with Obsidian 1.12) as the preferred transport for all vault mutations on desktop. This skill is the recipe reference for using it. |
| 4 | |
| 5 | **Substrate preference (v1.7+)**: This skill is a self-contained fallback. **Prefer `kepano/obsidian-skills`** (by Steph Ango, Obsidian CEO) as the authoritative substrate — its `obsidian-cli` skill is the canonical CLI reference for any Agent-Skills runtime. If you see an `obsidian-cli` skill available without the `claude-obsidian:` namespace, that is kepano's version: use it. The recipes below are provided so claude-obsidian remains functional when kepano's marketplace is not installed. Install kepano: `claude plugin marketplace add kepano/obsidian-skills`. |
| 6 | |
| 7 | --- |
| 8 | |
| 9 | ## Why CLI over MCP |
| 10 | |
| 11 | | Concern | MCP (Options A/B) | Obsidian CLI | |
| 12 | |---|---|---| |
| 13 | | Install | Local REST API plugin + MCP server config | Built into Obsidian 1.12+ | |
| 14 | | Auth | API key + TLS bypass (`NODE_TLS_REJECT_UNAUTHORIZED=0`) | None — direct subprocess | |
| 15 | | Latency | HTTP round-trip per call | In-process binary | |
| 16 | | Failure mode | Plugin disabled → silent breakage | Binary missing → loud `command -v` failure | |
| 17 | | Reentrancy | Self-MCP-calls inside Claude session can deadlock | Pure subprocess, safe | |
| 18 | | Mobile / headless | Limited | Limited (CLI is desktop-only too) | |
| 19 | |
| 20 | CLI loses to MCP on exactly one axis: it only works on machines where Obsidian itself is installed. For headless servers and mobile, fall through to the next transport in the chain. |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## Detection |
| 25 | |
| 26 | At session start (or vault setup), run: |
| 27 | |
| 28 | ```bash |
| 29 | bash scripts/detect-transport.sh |
| 30 | ``` |
| 31 | |
| 32 | This writes `.vault-meta/transport.json` with the schema: |
| 33 | |
| 34 | ```json |
| 35 | { |
| 36 | "preferred": "cli", |
| 37 | "fallback_chain": ["cli", "filesystem"], |
| 38 | "available": { |
| 39 | "cli": {"present": true, "binary": "obsidian-cli", "version_string": "..."}, |
| 40 | "filesystem": {"present": true}, |
| 41 | "mcp_obsidian": {"present": null, "detection": "deferred"}, |
| 42 | "mcpvault": {"present": null, "detection": "deferred"} |
| 43 | } |
| 44 | } |
| 45 | ``` |
| 46 | |
| 47 | **Read this file before any non-trivial vault mutation.** Skills that need to read or write should consult `preferred` and pick the corresponding transport. The decision tree lives at `wiki/references/transport-fallback.md`. |
| 48 | |
| 49 | Refresh detection with `--force` after installing/removing the Obsidian CLI: |
| 50 | ```bash |
| 51 | bash scripts/detect-transport.sh --force |
| 52 | ``` |
| 53 | |
| 54 | --- |
| 55 | |
| 56 | ## Recipes (CLI-first; fallback noted inline) |
| 57 | |
| 58 | Each recipe shows the CLI form first. If the CLI is unavailable per the detection snapshot, fall through to the noted fallback. Variable substitution: `$VAULT` is the absolute vault root; `$NOTE` is a vault-relative path like `wiki/concepts/Foo.md`. |
| 59 | |
| 60 | ### Read a note |
| 61 | ```bash |
| 62 | # CLI |
| 63 | obsidian-cli read "$VAULT" "$NOTE" |
| 64 | |
| 65 | # Fallback: Claude's Read tool with absolute path |
| 66 | # Read $VAULT/$NOTE |
| 67 | ``` |
| 68 | |
| 69 | ### Create or overwrite a note |
| 70 | ```bash |
| 71 | # CLI |
| 72 | obsidian-cli write "$VAULT" "$NOTE" < /path/to/content.md |
| 73 | |
| 74 | # Fallback: Claude's Write tool with absolute path |
| 75 | # Write $VAULT/$NOTE with the desired content string |
| 76 | ``` |
| 77 | |
| 78 | ### Append to a note |
| 79 | ```bash |
| 80 | # CLI |
| 81 | echo "additional content" | obsidian-cli append "$VAULT" "$NOTE" |
| 82 | |
| 83 | # Fallback: Read $VAULT/$NOTE, append manually, Write back |
| 84 | ``` |
| 85 | |
| 86 | ### Search note content (CLI uses Obsidian's own search ranking) |
| 87 | ```bash |
| 88 | # CLI |
| 89 | obsidian-cli search "$VAULT" "<query>" |
| 90 | |
| 91 | # Fallback: ripgrep |
| 92 | rg --type=md "<query>" "$VAULT/wiki/" |
| 93 | ``` |
| 94 | |
| 95 | ### Today's daily note (if Daily Notes plugin is enabled) |
| 96 | ```bash |
| 97 | # CLI |
| 98 | obsidian-cli daily:today "$VAULT" |
| 99 | obsidian-cli daily:append "$VAULT" "captured at $(date)" |
| 100 | |
| 101 | # Fallback: compute path manually |
| 102 | NOTE="$VAULT/wiki/daily/$(date +%Y-%m-%d).md" |
| 103 | ``` |
| 104 | |
| 105 | ### Patch a frontmatter property |
| 106 | ```bash |
| 107 | # CLI |
| 108 | obsidian-cli property:set "$VAULT" "$NOTE" status "evergreen" |
| 109 | |
| 110 | # Fallback: read frontmatter, parse, mutate, rewrite (use mcp__obsidian-vault__update_frontmatter if MCP is configured) |
| 111 | ``` |
| 112 | |
| 113 | ### List backlinks for a page |
| 114 | ```bash |
| 115 | # CLI |
| 116 | obsidian-cli backlinks "$VAULT" "$NOTE" |
| 117 | |
| 118 | # Fallback: ripgrep for wikilink references |
| 119 | rg --type=md "\[\[$(basename "$NOTE" .md)" "$VAULT/wiki/" |
| 120 | ``` |
| 121 | |
| 122 | ### Open a Bases (.base) file's resolved view |
| 123 | ```bash |
| 124 | # CLI |
| 125 | obsidian-cli bases "$VAULT" "$NOTE" |
| 126 | # (returns the resolved row list; supplements obsidian-bases skill which handles the .base file's YAML) |
| 127 | |
| 128 | # Fallback: read the .base file directly; no resolved-view available without Obsidian itself |
| 129 | ``` |