A small CLI for reading and writing notes in a local Obsidian vault.
Project description
odcli
odcli is a command-line tool for reading and writing notes in a local Obsidian vault.
It works directly on Markdown files inside the vault, so you can use it without any private Obsidian API.
Install
From PyPI:
pip install odcli
Or with uv:
uv tool install odcli
After installation, both command names are available:
odcli --help
obsidian-cli --help
Quickstart
If your vault is already in a common location, odcli can usually find it automatically:
odcli check
odcli list
If you want to set the vault explicitly:
export OBSIDIAN_VAULT="/path/to/MyVault"
odcli check
You can also override the vault per command:
odcli --vault "/path/to/MyVault" list
Remote Vault over SSH
You can operate on an Obsidian vault stored on another machine over SSH.
Example with explicit flags:
odcli \
--ssh-host your-server \
--ssh-user your-user \
--vault /path/to/ObsidianVault \
list
SSH config alias (recommended)
If you already have a host defined in ~/.ssh/config, you can use it the same
way you would with ssh:
odcli vm list
odcli vm read Inbox/today.md
odcli vm write Inbox/today.md --content "# Remote note"
The alias form is equivalent to odcli --ssh-alias vm .... HostName, User,
Port, and IdentityFile are read from your SSH config, and any explicit flag
or environment variable overrides the config value.
Environment variables
To avoid repeating the same flags every time, set defaults in your shell:
export ODCLI_SSH_HOST=your-server
export ODCLI_SSH_USER=your-user
export ODCLI_SSH_PORT=22
export ODCLI_SSH_IDENTITY=~/.ssh/id_ed25519
export ODCLI_VAULT=/path/to/ObsidianVault # OBSIDIAN_VAULT also works
Resolution order for each SSH field:
- CLI flag (
--ssh-host,--ssh-user,--ssh-port,--ssh-identity) - Environment variable (
ODCLI_SSH_HOST,ODCLI_SSH_USER,ODCLI_SSH_PORT,ODCLI_SSH_IDENTITY) ~/.ssh/configentry for the alias (when usingodcli <alias> ...)- Built-in defaults:
- user: the current OS user (
getpass.getuser()) - identity file: first existing key in
~/.ssh(id_ed25519,id_ecdsa,id_rsa) - vault: OS-aware default path
- macOS/Linux:
~/Documents/Obsidian Vault - Windows:
Documents\Obsidian Vault
- macOS/Linux:
- user: the current OS user (
For the identity file, either set ODCLI_SSH_IDENTITY explicitly or rely on
auto-discovery — you do not need both.
Optional SSH flags:
--ssh-port--ssh-identity--ssh-alias
In SSH mode, --vault, ODCLI_VAULT, or OBSIDIAN_VAULT should point to the
remote vault path. If none is provided, an OS-aware default is used.
Common Commands
Read a note:
odcli read Inbox/today.md
Read specific lines:
odcli read-lines Inbox/today.md 3 8
Create or overwrite a note:
odcli write Inbox/today.md --content "# Today"
Replace a line range:
odcli write-lines Inbox/today.md 3 4 --content "- replaced\n- lines\n"
Append content:
odcli append Inbox/today.md --content "\n- new item"
Search across the vault:
odcli search "project alpha"
Skill Install
odcli can install helper skills for local coding tools.
Install into Codex:
odcli plugin install codex-skill
Install into Claude Code:
odcli plugin install claude-skill
Install both:
odcli plugin install all-skills
Installed paths:
- Codex:
~/.codex/skills/odcli/SKILL.md - Claude Code:
~/.claude/skills/odcli/SKILL.md
Vault Discovery
Resolution priority:
--vault /path/to/vaultOBSIDIAN_VAULT- The most recently opened vault recorded by local Obsidian config
- Common default directories
Built-in default locations:
- macOS:
~/Documents/Obsidian Vault - macOS:
~/Documents/Obsidian - macOS iCloud:
~/Library/Mobile Documents/iCloud~md~obsidian/Documents - Windows:
%USERPROFILE%\\Documents\\Obsidian Vault - Windows:
%USERPROFILE%\\Documents\\Obsidian
Command Summary
check
Validate that the vault exists and report whether .obsidian is present.
list
List Markdown notes in the vault.
Optional arguments:
--limit N
read
Read a note.
Arguments:
note_path: path relative to the vault root
write
Overwrite a note. Parent directories are created automatically if needed.
Arguments:
note_path--content TEXT--stdin
Optional arguments:
--create-only
read-lines
Read a line range. Line numbers are 1-based and inclusive.
Arguments:
note_pathstart_lineend_line
write-lines
Replace a line range. Line numbers are 1-based and inclusive.
Arguments:
note_pathstart_lineend_line--content TEXT--stdin
append
Append content to the end of a note.
Arguments:
note_path--content TEXT--stdin
search
Search across all Markdown notes in the vault.
Arguments:
query--case-sensitive
Global Options
--vault--ssh-alias(or the bareodcli <alias> <command>form)--ssh-host--ssh-user--ssh-port--ssh-identity
Environment Variables
OBSIDIAN_VAULT/ODCLI_VAULT: vault pathODCLI_SSH_HOST: SSH hostODCLI_SSH_USER: SSH usernameODCLI_SSH_PORT: SSH portODCLI_SSH_IDENTITY: SSH private key path
For Developers
Run from source:
cd path/to/obsidian_cli
uv sync
uv run odcli --help
Run tests:
cd path/to/obsidian_cli
uv run python -m unittest discover -s tests
Build distributions:
cd path/to/obsidian_cli
uv build
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file odcli-0.1.9.tar.gz.
File metadata
- Download URL: odcli-0.1.9.tar.gz
- Upload date:
- Size: 16.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa4519deb1e3521f9c469db4a1ab7d1e68b97c2d34f56984173f718bc1d807ff
|
|
| MD5 |
97cbbf870d80249965aa702977b2834e
|
|
| BLAKE2b-256 |
94a7918f724e3ce74c984385c6313f952cacc3716041de83a188fc49f2cb6c2f
|
File details
Details for the file odcli-0.1.9-py3-none-any.whl.
File metadata
- Download URL: odcli-0.1.9-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b278d14ab74670ceefbbb3352dcb1084026c7cfb6bd077eaec9402cd3821d20a
|
|
| MD5 |
759e1007d009dad6ff73cee0becd492e
|
|
| BLAKE2b-256 |
e709895b072274fdf8825341373e5e11f838a9634b8cf8ddce405b9b9b029f07
|