odcli
CLI for reading and writing Obsidian vault notes — locally or over SSH.
odcli operates directly on Markdown files, so it needs no Obsidian API or
running Obsidian instance. Point it at a local vault or connect to a remote
machine the same way you would with ssh.
Install
pip install odcli
Or with uv:
uv tool install odcli
After installation both odcli and obsidian-cli are available.
Quick start
Local vault
odcli auto-discovers the vault from your Obsidian config or common default
locations. No setup needed in most cases:
odcli list
odcli read Inbox/today.md
To point at a specific vault:
export OBSIDIAN_VAULT="/path/to/MyVault" # or ODCLI_VAULT
odcli list
Or per-command:
odcli --vault "/path/to/MyVault" list
Remote vault over SSH
If the host is in your ~/.ssh/config, use it like ssh:
odcli myserver list
odcli myserver read Inbox/today.md
odcli myserver write Inbox/today.md --content "# Hello"
Or use explicit flags:
odcli --ssh-host myserver --ssh-user me list
SSH details
How the alias is resolved
odcli myserver list is rewritten to odcli --ssh-alias myserver list.
HostName, User, Port, and IdentityFile are pulled from ~/.ssh/config
(including Include-d files). Any explicit flag or environment variable
overrides the config value.
Environment variables
Set defaults in your shell profile so you never have to repeat flags:
| Variable | Description |
|---|---|
ODCLI_SSH_HOST |
SSH host |
ODCLI_SSH_USER |
SSH username |
ODCLI_SSH_PORT |
SSH port |
ODCLI_SSH_IDENTITY |
SSH private key path |
ODCLI_VAULT / OBSIDIAN_VAULT |
Vault path (local or remote) |
Resolution order
Each SSH field is resolved in this order:
- CLI flag (
--ssh-host,--ssh-user,--ssh-port,--ssh-identity) - Environment variable (
ODCLI_SSH_*) ~/.ssh/configentry for the alias- Built-in default:
- user — current OS user
- identity — first key found in
~/.ssh(id_ed25519>id_ecdsa>id_rsa) - vault —
~/Documents/Obsidian Vault(macOS/Linux) orDocuments\Obsidian Vault(Windows)
Commands
| Command | Description |
|---|---|
check |
Validate the vault path |
list [--limit N] |
List Markdown notes |
read <note> |
Print a note |
read-lines <note> <start> <end> |
Print a line range (1-based, inclusive) |
write <note> --content TEXT |
Create or overwrite a note |
write-lines <note> <start> <end> --content TEXT |
Replace a line range |
append <note> --content TEXT |
Append to a note |
search <query> [--case-sensitive] |
Full-text search across all notes |
mkdir <dir> [--no-parents] |
Create a directory inside the vault |
All write commands accept --stdin instead of --content to read from stdin.
write also accepts --create-only to fail if the note already exists.
mkdir creates the directory and any missing parents by default (like
mkdir -p); pass --no-parents for strict mkdir semantics that fail on a
missing parent or an existing directory.
AI coding assistant integration
odcli can install helper skills so AI coding tools know how to use it:
odcli plugin install all-skills # Codex + Claude Code
odcli plugin install codex-skill # Codex only
odcli plugin install claude-skill # Claude Code only
Vault discovery
When no vault is specified, odcli searches in this order:
--vaultflagOBSIDIAN_VAULT/ODCLI_VAULTenvironment variable- Most recently opened vault from Obsidian's own config
- Common default directories:
- macOS:
~/Documents/Obsidian Vault,~/Documents/Obsidian, iCloud - Windows:
%USERPROFILE%\Documents\Obsidian Vault,%USERPROFILE%\Documents\Obsidian
- macOS:
Development
uv sync # install deps
uv run python -m unittest discover -s tests # run tests
uv build # build wheel + sdist
Metadata
Release files for odcli 0.1.14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| odcli-0.1.14.tar.gz | 18.5 kB | Without provenance | Details for odcli-0.1.14.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| odcli-0.1.14-py3-none-any.whl | Python 3 | none | any | Details for odcli-0.1.14-py3-none-any.whl |
Total release size: 34.8 kB
Release files / odcli-0.1.14.tar.gz
| Download URL | odcli-0.1.14.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7c2687f58996f7b37cae38974d94f65f87d0f34a82ae30ff16679b40381b03e3
|
|
BLAKE2b-256 checksum How to use checksums |
5a858a1e689f6fbc55347c4655aebc73c130c105ee51fde96c91c9bc9c722737
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / odcli-0.1.14-py3-none-any.whl
| Download URL | odcli-0.1.14-py3-none-any.whl |
|---|---|
| Size | 16.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
af89aaf92072c454fe82bedc7a395e228219459e3003fa02cea0fb0e60764dda
|
|
BLAKE2b-256 checksum How to use checksums |
4b24e343ac0b13d6aeacee7ab34f4eb668deddf3b07bfc3a2c6e33bdedec14e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Security for odcli 0.1.14
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.