The PARA-ZK CLI is for LLMs, scripts, and other automation driving a running Obsidian vault.
It uses the same workflow logic as the Obsidian GUI, but exposes explicit arguments and token-efficient JSON results.
Invocation
Use Obsidian’s native CLI directly or through Optsidian:
obsidian para-zk:describe format=json
optsidian para-zk:describe format=jsonUse format=json for automation.
Successful responses use stable fields such as:
{
"ok": true,
"command": "para-zk:create-project",
"path": "PARA/Projects/Example/Example.md",
"created": true
}Errors return ok: false with an error message.
Load Conventions Once
Automation should start each task with:
optsidian para-zk:conventions format=jsonIt returns the vault orientation, ownership/routing rules, citation rules, and wiki-compounding rules. Then use para-zk:describe as the live surface reference.
Discover The Live Surface
Start with:
optsidian para-zk:describe format=jsonThen drill into a surface type:
optsidian para-zk:describe type=project format=json
optsidian para-zk:describe type=resource format=json
optsidian para-zk:describe type=permanent format=jsondescribe type=<surface> returns selectors, create inputs, read keys, write keys, collections, and supported operations for that note type. Keys absent from writeKeys are not writable through PARA-ZK; route raw file edits, raw frontmatter, and full-text search to the host CLI.
For one command’s arguments, use help=true:
optsidian para-zk:create-area help=true format=jsonFind Notes
To enumerate notes by type before addressing one, use para-zk:list:
optsidian para-zk:list type=project format=json
optsidian para-zk:list type=resource query=attention format=jsonIt returns { title, type, path } items and supports archived, query, and offset/limit paging. Full-text content search is left to the host CLI’s own grep/search.
LLM-Wiki Ingest
Use para-zk:wiki-ingest-candidates to list active, non-template canonical sources (resource, digest, permanent, subnote) that should be folded into LLM-Wiki/ without reading source or wiki bodies:
optsidian para-zk:wiki-ingest-candidates mode=uncited limit=all format=json
optsidian para-zk:wiki-ingest-candidates mode=uncited type=resource limit=all format=json
optsidian para-zk:wiki-ingest-candidates mode=delta limit=50 format=json
optsidian para-zk:wiki-ingest-candidates mode=per-import source_paths='["PARA/Resources/Source Paper.md"]' format=json
optsidian para-zk:wiki-ingest-candidates mode=re-ingest source_path="PARA/Resources/Source Paper.md" format=jsonmode is one of per-import, delta, uncited, or re-ingest. source_path or source_paths=<json|comma-list> is required for per-import and re-ingest, and rejected for delta and uncited. The command also accepts type=<resource|digest|permanent|subnote>, offset=<n>, limit=<n|all> (default 50), and format. Results include { ok, command, count, offset, limit, returned, has_more, candidates }; each candidate has { path, type, title, updated, updated_ms, stale_llm_wikis, reason }.
Reason codes are missing_wiki_citation, source_newer_than_wiki, per_import, and reingest_requested. source_newer_than_wiki derives staleness from page updated: the source is newer than at least one citing wiki page, listed in stale_llm_wikis as { path, title, updated_ms }.
For retopology, use para-zk:wiki-retopology-candidates to rank domain index pairs before reading hubs:
optsidian para-zk:wiki-retopology-candidates limit=20
optsidian para-zk:wiki-retopology-candidates domain=language-models limit=10
optsidian para-zk:wiki-retopology-candidates domain=language-models depth=3 limit=10It compares <domain>/index hubs only with TF-IDF weighted cosine scores and returns { mode, domain?, graph?, count, limit, returned, has_more, candidates, warnings? } with { domains, indexes, score, shared_terms, explicit_links, evidence, connection } candidates. Wikilinks are reduced to their visible labels (alias text, or the target basename when no alias), and body bigrams such as diffusion policy are included with a lighter weight. Explicit cross-domain links appear as evidence and graph connections without boosting scores or breaking score ties. In Obsidian, per-index term counts are cached in .obsidian/plugins/para-zk/retopology-cache.json and invalidated by a hash of the term-counting rules plus index path, modified time, and size. The cache read limit defaults to 16 MiB and can be raised with retopologyCacheMaxMiB in the plugin config; results include a warning after the cache exceeds 95% of that limit. connection is the shortest undirected index-to-index path within depth; focused mode also includes an undirected index graph neighborhood. depth defaults to 2.
The audit checks include upward_wiki_link (medium), which flags a non-llm-wiki note that links into an llm-wiki note; orphan_wiki_page (low), an advisory hint for a wiki page that no other wiki page links to; and wiki_tag_domain_mismatch (low), which can be fixed with audit fix=true.
create-llm-wiki and update-llm-wiki accept by=<model-id> for authorship: create stamps created_by and updated_by, while changed updates stamp updated_by. Move a concept page between domains with refile-llm-wiki title=<current> domain=<target>; rename-llm-wiki only changes the concept name in its current domain. LLM-Wiki pages include managed props plus Cited-by scoped to LLM-Wiki/, then References. Cross-link wiki concept pages with body [[link]]; use references plus backtick code-span `PZ[<id>]` citations only for canonical sources outside LLM-Wiki. Bare PZ[<id>] text does not render.
Canonical Arguments
PARA-ZK commands use one canonical argument name per concept.
Examples:
titlefor project, area, resource, retro, and ZK titlesdatefor journal and retro dateskindfor ZK kindarea_titleswhen creating or linking project areassource_titlefor source notes used by create/distill workflowsroot_type,root_title,relpath, andtitleforcreate-child,read-child,update-child,rename-child, anddelete-child
Notes are addressed by name, not by vault file path. Subfoldered child subnotes can be addressed by basename when unique or by subdir/title(.md) through the title field.
Top-level parent CRUD commands do not accept child=. Address child notes, fallback notes, and nested areas through the dedicated *-child command family.
Locale-Neutral Codes
CLI values are stable codes even when the vault renders localized labels.
Common examples:
status=in_progress
priority=high
maturity=draft
kind=permanent
energy=normalLarge Bodies From Files
Create commands support file-backed body input, and update commands support file-backed value input:
optsidian para-zk:create-resource title="Attention Is All You Need" body=@/absolute/path/to/note.md
optsidian para-zk:update-child root_type=project root_title="Model Evaluation" title="Planning Meeting" key=body op=set value=@/absolute/path/to/body.mdUse an absolute path. The plugin reads the file from the Obsidian process, which keeps multiline Markdown, quotes, $, and backticks intact.
Note
Only create
bodyand updatevalueare file-backed. Short fields such as journalcontent,match, andwithare literal, so@mentionsremain text.
References And Citations
Reference registries expose stable ids. Read them with:
optsidian para-zk:read-resource title="Source Paper" key=references limit=all format=jsonBody prose cites references with backtick code spans such as `PZ[<id>]`, `PZ[<id>, <id>]`, or `PZ[<id>#<section>]`. The id is not the visible registry index. Citations render as the reference’s current position, so reordering references changes the displayed number but not the stored citation target.
More Detail
The exhaustive CLI contract lives in the repo at docs/CLI.md. Use that document for the complete command reference; use para-zk:describe for the live surface in your current vault.