cli-anything-joplin
Use this skill to automate Joplin notebook, note, to-do, tag, attachment,
search, sync, and import/export workflows through a stateful harness backed by
the real joplin terminal binary.
Requirements
- Python 3.10+
- Joplin terminal binary available as
joplin
- Optional: pass
--profile to target a specific Joplin profile
Install
cd joplin/agent-harness
pip install -e .
Usage
# REPL mode (default)
cli-anything-joplin
# Machine-readable one-shot command
cli-anything-joplin --json notebooks list
# Stateful project
cli-anything-joplin project new --name demo -o ./demo.joplin-harness.json
cli-anything-joplin --project ./demo.joplin-harness.json notes create "Meeting note"
# Dry-run (no auto-save)
cli-anything-joplin --json --dry-run --project ./demo.joplin-harness.json notes create temp
JSON output contract
When --json is enabled, commands return:
ok: boolean
command: stable command identifier such as notes.list, todos.toggle
data: command payload
error: null on success, or { type, message } on failure
Command groups
project: new, open, save, info, json, status
notebooks: list, create, use, remove
notes: list, create, set, get, remove, copy, move, rename
todos: list, create, toggle, clear, done, undone
tags: list, add, remove, notetags, tagnotes
search: run
sync: run (--target, --upgrade, --use-lock)
interop: import, export
config: get, set, list, export, import-file
attach: add
status: show, restore
backend: version, dump, keymap, geoloc, export-sync-status
server: status, start, stop
e2ee: status, target-status, decrypt, decrypt-file
session: status, undo, redo, history
Agent guidance
- Prefer
--json for parseable output.
- Use
--project when running multi-step workflows so history is persisted.
- One-shot mutating commands auto-save the project unless
--dry-run is set.
- REPL mode does not auto-save; run
project save explicitly.
- Some Joplin CLI builds gate
search behind GUI mode; if you see
"only available in GUI mode", treat search as best-effort.
- Joplin 3.6.x can have a broken
version command in npm global layouts; the
harness falls back to installed package metadata for backend version,
probing the symlink-resolved binary directory, the Windows-style sibling
node_modules/joplin, the Unix-style parent lib/node_modules/joplin, and
finally npm root -g.
- Backend
stdout/stderr in command results are verbatim; do not assume
warnings were stripped from note bodies or exports.
- On failure, parse
error using the same command field as success
(config.import_file, e2ee.decrypt_file). Multi-word subcommands use
a single dot between group and subcommand.
Test workflow
# Quick feedback loop
python -m pytest -q cli_anything/joplin/tests/test_core.py
python -m pytest -q cli_anything/joplin/tests/test_full_e2e.py::TestCLISubprocess
# Real backend (joplin must be in PATH)
python -m pytest -v cli_anything/joplin/tests/test_full_e2e.py::TestBackendCommands
python -m pytest -v cli_anything/joplin/tests/test_full_e2e.py::TestBackendWorkflows
python -m pytest -v cli_anything/joplin/tests/test_full_e2e.py::TestBackendIntegration
# Full suite
python -m pytest -v --tb=no cli_anything/joplin/tests
# Verify the installed console script entry point
CLI_ANYTHING_FORCE_INSTALLED=1 python -m pytest -v -s cli_anything/joplin/tests/test_full_e2e.py
Current validation baseline (Windows + Joplin CLI 3.6.2):
python -m pytest -q cli_anything/joplin/tests/test_core.py -> 107 passed
python -m pytest -q cli_anything/joplin/tests -> 134 passed, 1 skipped
1---2name: cli-anything-joplin3description: Command-line interface for Joplin workflows using the real joplin terminal backend4---5
6# cli-anything-joplin
7
8Use this skill to automate Joplin notebook, note, to-do, tag, attachment,
9search, sync, and import/export workflows through a stateful harness backed by
10the real `joplin` terminal binary.
11
12## Requirements
13
14- Python 3.10+
15- Joplin terminal binary available as `joplin`
16- Optional: pass `--profile` to target a specific Joplin profile
17
18## Install
19
20```bash
21cd joplin/agent-harness
22pip install -e .
23```
24
25## Usage
26
27```bash
28# REPL mode (default)
29cli-anything-joplin
30
31# Machine-readable one-shot command
32cli-anything-joplin --json notebooks list
33
34# Stateful project
35cli-anything-joplin project new --name demo -o ./demo.joplin-harness.json
36cli-anything-joplin --project ./demo.joplin-harness.json notes create "Meeting note"
37
38# Dry-run (no auto-save)
39cli-anything-joplin --json --dry-run --project ./demo.joplin-harness.json notes create temp
40```
41
42## JSON output contract
43
44When `--json` is enabled, commands return:
45
46- `ok`: boolean
47- `command`: stable command identifier such as `notes.list`, `todos.toggle`
48- `data`: command payload
49- `error`: null on success, or `{ type, message }` on failure
50
51## Command groups
52
53- `project`: `new`, `open`, `save`, `info`, `json`, `status`
54- `notebooks`: `list`, `create`, `use`, `remove`
55- `notes`: `list`, `create`, `set`, `get`, `remove`, `copy`, `move`, `rename`
56- `todos`: `list`, `create`, `toggle`, `clear`, `done`, `undone`
57- `tags`: `list`, `add`, `remove`, `notetags`, `tagnotes`
58- `search`: `run`
59- `sync`: `run` (`--target`, `--upgrade`, `--use-lock`)
60- `interop`: `import`, `export`
61- `config`: `get`, `set`, `list`, `export`, `import-file`
62- `attach`: `add`
63- `status`: `show`, `restore`
64- `backend`: `version`, `dump`, `keymap`, `geoloc`, `export-sync-status`
65- `server`: `status`, `start`, `stop`
66- `e2ee`: `status`, `target-status`, `decrypt`, `decrypt-file`
67- `session`: `status`, `undo`, `redo`, `history`
68
69## Agent guidance
70
71- Prefer `--json` for parseable output.
72- Use `--project` when running multi-step workflows so history is persisted.
73- One-shot mutating commands auto-save the project unless `--dry-run` is set.
74- REPL mode does not auto-save; run `project save` explicitly.
75- Some Joplin CLI builds gate `search` behind GUI mode; if you see
76 `"only available in GUI mode"`, treat search as best-effort.
77- Joplin 3.6.x can have a broken `version` command in npm global layouts; the
78 harness falls back to installed package metadata for `backend version`,
79 probing the symlink-resolved binary directory, the Windows-style sibling
80 `node_modules/joplin`, the Unix-style parent `lib/node_modules/joplin`, and
81 finally `npm root -g`.
82- Backend `stdout`/`stderr` in command results are verbatim; do not assume
83 warnings were stripped from note bodies or exports.
84- On failure, parse `error` using the same `command` field as success
85 (`config.import_file`, `e2ee.decrypt_file`). Multi-word subcommands use
86 a single dot between group and subcommand.
87
88## Test workflow
89
90```bash
91# Quick feedback loop
92python -m pytest -q cli_anything/joplin/tests/test_core.py
93python -m pytest -q cli_anything/joplin/tests/test_full_e2e.py::TestCLISubprocess
94
95# Real backend (joplin must be in PATH)
96python -m pytest -v cli_anything/joplin/tests/test_full_e2e.py::TestBackendCommands
97python -m pytest -v cli_anything/joplin/tests/test_full_e2e.py::TestBackendWorkflows
98python -m pytest -v cli_anything/joplin/tests/test_full_e2e.py::TestBackendIntegration
99
100# Full suite
101python -m pytest -v --tb=no cli_anything/joplin/tests
102
103# Verify the installed console script entry point
104CLI_ANYTHING_FORCE_INSTALLED=1 python -m pytest -v -s cli_anything/joplin/tests/test_full_e2e.py
105```
106
107Current validation baseline (Windows + Joplin CLI 3.6.2):
108
109- `python -m pytest -q cli_anything/joplin/tests/test_core.py` -> `107 passed`
110- `python -m pytest -q cli_anything/joplin/tests` -> `134 passed, 1 skipped`