logseq-cli
Prefer the local `logseq` CLI whenever a user mentions a Logseq page, journal, namespace, block UUID, graph query, Logseq API token. Use it for reading pages, mutating blocks, creating journal pages, querying the graph, checking auth, and installing/showing the packaged agent skill. Prefer CLI operations over manual Markdown edits whenever the command surface supports the task.
Logseq CLI First
Use the logseq CLI before reading or editing graph files directly. Treat pages and blocks as graph objects first, not as Markdown files first.
Start Here
- Run
logseq --helpto confirm the CLI exists. - Run the narrowest relevant help command before acting:
logseq page --helplogseq block --helplogseq graph --helplogseq query --helplogseq auth --helplogseq skill --help
- If the CLI is missing, stop and say so explicitly. Suggest:
- Windows PowerShell:
py -m pip install --user .orpipx install . - macOS / Linux:
python3 -m pip install --user .orpipx install .
- Windows PowerShell:
- If installation succeeds but
logseqis still missing fromPATH, point the user to their user script directory:- Windows:
%APPDATA%\Python\Python310\Scriptsor equivalent - Linux:
~/.local/bin - macOS: user Python bin directory from
python3 -m site --user-base
- Windows:
- If commands fail because no token is configured, use:
logseq auth statuslogseq auth set-token
Agent Rules
- Prefer
logseqover direct file edits for page lookup, page creation, journal creation, block mutation, graph inspection, and Datalog queries. - Prefer NDJSON output for agent workflows. Use
--plainonly for human-facing display. - Use
--fieldswhenever a command supports it. This is the main token-saving mechanism. - Use pagination on broad reads:
logseq page list --page 1 --page-size 20logseq query run ... --page 1 --page-size 20
- Prefer targeted commands over broad scans:
- Use
page get,page properties,page refs,page ns-list, orquery runbeforepage list.
- Use
- Use
block insert-batchfor multi-block writes instead of manyblock insertcalls. - Fall back to raw Markdown edits only when the CLI cannot express the task cleanly.
Output Contract
- Default stdout is NDJSON.
- A list prints one JSON value per line.
- A single object prints as one JSON line.
--fieldstrims dict keys before printing.--plainprints human-readablekey: valueblocks and is not pipeline-friendly.- Errors go to stderr.
Use these defaults for agents:
logseq page get "My Page" --fields name,uuid
logseq block get "block-uuid" --fields uuid,content,page
logseq page list --fields name,uuid --page 1 --page-size 20
Stdin Contract
Only these commands consume omitted identifiers from piped NDJSON:
| Command | Reads |
|---|---|
logseq page get [NAME] | .name |
logseq page delete [NAME] | .name |
logseq block get [UUID] | .uuid |
logseq block insert CONTENT [--uuid UUID] | .uuid when --uuid is omitted |
logseq block remove [UUID] | .uuid |
Do not assume other commands read stdin just because they take a name or uuid.
Efficient Piping Patterns
Prefer short NDJSON pipelines when the downstream command explicitly supports stdin.
Good patterns:
logseq page list --fields name,uuid --page 1 --page-size 20 | logseq page get --fields name,uuid
logseq page get "Project Alpha" --fields name | logseq page delete
logseq block get "2c4d..." --fields uuid,content | logseq block remove
logseq block get "2c4d..." --fields uuid | logseq block insert "Follow-up note"
logseq page list --fields name,uuid | jq -c "select(.name | startswith(\"Projects/\"))" | logseq page get --fields name,uuid
Bad patterns:
logseq page get "Page" --plain | logseq page deletelogseq page get "Page" | logseq page refslogseq page get "Page" | logseq block getlogseq page list | logseq block remove
Why they are bad:
--plaindestroys machine-readable NDJSON.page refsrequires an explicit page name and does not read stdin.block getexpects a block.uuid, not a page UUID.block removerequires block UUID input, not page objects.
Token-Efficient Usage
Prefer the smallest command that answers the question:
- Need page existence or ID:
logseq page get "Page" --fields name,uuid - Need only page metadata:
logseq page properties "Page" - Need block metadata without children:
logseq block get "uuid" --fields uuid,content,page - Need child tree too:
logseq block get "uuid" --include-children - Need namespace discovery:
logseq page ns-list "Projects" --fields name,uuid - Need namespace hierarchy:
logseq page ns-tree "Projects" - Need targeted graph search:
logseq query run '[:find ... :where ...]' - Need many sibling/child blocks inserted:
logseq block insert-batch ...
Prefer these heuristics:
- Avoid
logseq page liston large graphs unless the task truly needs a wide page scan. - If you only need names or UUIDs, always add
--fields. - If the query can be narrowed in Datalog, do that instead of listing many pages and filtering later.
- If the final consumer is another
logseqcommand, keep the upstream object minimal. - If the user only needs a rendered answer, use
--plainonly at the final step.
Fallback And Compatibility Notes
logseq page propertiesis a fallback over the first block from the page tree.logseq page journaluses aYYYY_MM_DDcreate-page fallback.logseq block appenduses a page-tree fallback that appends after the last top-level block.- Some raw Logseq HTTP methods are unsupported. Trust the CLI behavior and repo tests over assumptions about the upstream API.
Command Reference
Top-level
| Command | Usage | Purpose |
|---|---|---|
logseq version | logseq version | Print CLI version |
logseq auth | logseq auth --help | Manage stored API token |
logseq page | logseq page --help | Page operations |
logseq block | logseq block --help | Block operations |
logseq graph | logseq graph --help | Graph inspection |
logseq query | logseq query --help | Datalog queries |
logseq skill | logseq skill --help | Install or inspect this packaged skill |
auth
| Command | Usage | Purpose |
|---|---|---|
auth set-token | logseq auth set-token [TOKEN] | Store or replace the API token; prompt securely when omitted |
auth status | logseq auth status | Show config path and token presence |
page
| Command | Usage | Purpose |
|---|---|---|
page list | logseq page list [--fields name,uuid] [--page N --page-size N] [--plain] | List pages |
page get | logseq page get [NAME] [--fields ...] [--plain] | Get a page by name or piped .name |
page create | logseq page create NAME [--fields ...] [--plain] | Create a page |
page delete | logseq page delete [NAME] | Delete a page by name or piped .name |
page rename | logseq page rename SRC DEST | Rename a page |
page refs | logseq page refs NAME [--fields ...] [--plain] | Get linked references for a page |
page properties | logseq page properties NAME [--plain] | Get page properties |
page journal | logseq page journal YYYY-MM-DD [--plain] | Create or get a journal page |
page ns-list | logseq page ns-list NAMESPACE [--fields ...] [--plain] | List pages in a namespace |
page ns-tree | logseq page ns-tree NAMESPACE [--plain] | Get namespace tree structure |
block
| Command | Usage | Purpose |
|---|---|---|
block get | logseq block get [UUID] [--fields ...] [--include-children] [--plain] | Get a block by UUID or piped .uuid |
block insert | logseq block insert CONTENT [--uuid UUID] [--sibling] [--plain] | Insert relative to a block; read piped .uuid when --uuid is omitted |
block update | logseq block update UUID CONTENT [--plain] | Replace block content |
block remove | logseq block remove [UUID] | Remove a block by UUID or piped .uuid |
block prepend | logseq block prepend PAGE CONTENT [--plain] | Insert at top of page |
block append | logseq block append PAGE CONTENT [--plain] | Insert at bottom of page |
block move | logseq block move SRC_UUID TARGET_UUID [--sibling] [--plain] | Move a block relative to another block |
block collapse | `logseq block collapse UUID [--expand | --toggle]` |
block properties | logseq block properties UUID [--plain] | Read all block properties |
block prop-set | logseq block prop-set UUID KEY VALUE | Set or update a property |
block prop-remove | logseq block prop-remove UUID KEY | Remove a property |
block insert-batch | logseq block insert-batch UUID BATCH_JSON [--sibling] [--plain] | Insert multiple blocks in one call |
graph
| Command | Usage | Purpose |
|---|---|---|
graph info | logseq graph info [--plain] | Get current graph name and path |
query
| Command | Usage | Purpose |
|---|---|---|
query run | logseq query run DATALOG [--input VALUE ...] [--page N --page-size N] [--plain] | Run a Datalog query |
skill
| Command | Usage | Purpose |
|---|---|---|
skill install | `logseq skill install [--scope user | project] [--target all |
skill status | `logseq skill status [--scope user | project] [--target all |
skill uninstall | `logseq skill uninstall [--scope user | project] [--target all |
skill show | `logseq skill show [--scope user | project] [--target source |
Recommended Agent Playbooks
Read one page cheaply
logseq page get "Page Name" --fields name,uuid,properties
Find namespace members, then expand only the interesting pages
logseq page ns-list "Projects" --fields name,uuid |
jq -c "select(.name | contains(\"Alpha\"))" |
logseq page get --fields name,uuid,properties
Insert a child block under a known block
logseq block get "2c4d..." --fields uuid | logseq block insert "New child block"
Create many nested blocks in one call
logseq block insert-batch "2c4d..." '[{"content":"Parent","children":[{"content":"Child 1"},{"content":"Child 2"}]}]'
Use human-readable output only at the end
logseq page get "Page Name" --fields name,uuid | logseq page get --plain