Metadata-Version: 2.4
Name: siyuan-cli
Version: 1.9.0
Summary: CLI tool + MCP server + Agent Skills for SiYuan Note (思源笔记) — zero deps, permission system, workspace management
Author: Milo
License-Expression: MIT
Project-URL: Homepage, https://github.com/xingrove/siyuan-cli
Project-URL: Repository, https://github.com/xingrove/siyuan-cli
Keywords: siyuan,思源笔记,notes,markdown,pkm,self-hosted,agent-skills
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Text Editors :: Documentation
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: Chinese (Simplified)
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-timeout; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Dynamic: license-file

# siyuan-cli

[![PyPI](https://img.shields.io/pypi/v/siyuan-cli)](https://pypi.org/project/siyuan-cli/)
[![Python](https://img.shields.io/pypi/pyversions/siyuan-cli)](https://pypi.org/project/siyuan-cli/)
[![License](https://img.shields.io/pypi/l/siyuan-cli)](LICENSE)
| [![Tests](https://img.shields.io/badge/tests-301%20passed-brightgreen)](https://github.com/xingrove/siyuan-cli)

> [中文](README.md)

A pure Python CLI for [SiYuan Note](https://github.com/siyuan-note/siyuan) with zero dependencies. Includes an MCP server and AI Agent Skills.

## Quick Start

```bash
# Option 1: pip install (recommended)
pip install siyuan-cli

# Option 2: one-liner installer (auto-detects token)
curl -fsSL https://raw.githubusercontent.com/xingrove/siyuan-cli/main/scripts/install.sh | bash

# Option 3: run from source
git clone https://github.com/xingrove/siyuan-cli.git && cd siyuan-cli && python3 -m siyuan_cli
```

### Setup Token

```bash
siyuan config token "your-api-token"          # manual setup
# Or via env vars (recommended for CI/containers):
export SIYUAN_TOKEN="your-token"
export SIYUAN_URL=http://127.0.0.1:6806
```

Find your token: SiYuan Desktop → Settings → About → API token. Docker: `conf.json → api.token`.

Verify connection:
```bash
siyuan health
```

### MCP Server (IDE Integration)

For Claude Desktop / Cursor / Windsurf:
```json
{
  "mcpServers": {
    "siyuan": {
      "command": "siyuan-mcp"
      // or pass SIYUAN_TOKEN / SIYUAN_URL via the env field
    }
  }
}
```

### AI Agent Skills

Install to Hermes / Claude Code / OpenCode / Codex CLI:
```bash
siyuan install-skills
```

Agents can then read and write your SiYuan notes directly.

---

Under 5,000 lines of Python. Install is under 80KB.

---

## What It Adds On Top of the API

SiYuan already has a REST API. `siyuan-cli` layers five things on top:

1. **Lazy config** — token stored in `~/.siyuan/config.json`, never passed per-command.
2. **Chinese encoding handled** — re-parses `sys.argv` via the Windows Unicode API, normalizes CRLF in responses, no mojibake.
3. **Structured output** — `--format json` gives `{"ok": true, "data": ...}` for scripting.
4. **Safety rails** — destructive ops need `--yes`, read-only mode available, endpoint-level permission rules.
5. **Response caching** — notebook lists and document trees cached for 30 seconds, auto-invalidated on writes.

In practice: `siyuan read "/path"` reads a note, `siyuan create "/path" "# title"` writes one. No need to remember notebook IDs, endpoint names, or payload shapes.

---

## Command Reference

Global flags:

| Flag | What It Does |
|------|-------------|
| `--format json\|pretty\|compact` | Output format |
| `--yes` | Skip confirmation on destructive ops |
| `--dry-run` | Preview without writing |
| `--no-color` | Disable ANSI colors |
| `--verbose` | Enable debug logging |
| `SIYUAN_READ_ONLY=1` | Env var that blocks all writes |

### Documents

| Command | Description |
|---------|-------------|
| `siyuan create /path [markdown]` | Create a note, supports `--file` |
| `siyuan read /path [--id <id>]` | Read a note |
| `siyuan delete /path --yes` | Delete a note |
| `siyuan doc rename <title> --path /path` | Rename |
| `siyuan doc move /path1 /path2 --to-notebook <id>` | Move to another notebook |
| `siyuan doc export /path [--id <id>]` | Export as Markdown |
| `siyuan tree [notebook-id]` | Document tree |

**Creating from a file** (recommended for AI agents — avoids shell escaping):

```bash
siyuan create "/articles/my-article" --file article.md
```

### Search & Query

```bash
siyuan search "keyword"           # Full-text search
siyuan sql "SELECT ..."           # Run SQL directly (SELECT only)
siyuan stats                      # Workspace statistics
siyuan overview                   # High-level overview: notebooks, recent docs, block types
siyuan health                     # Connection and auth diagnostics
```

`siyuan sql` is restricted to SELECT statements and auto-appends `LIMIT 100` to avoid long-running queries.

`siyuan overview` makes a single request and returns: notebook list with doc counts, the 5 most recently modified documents, and a breakdown of all block types. It covers the same ground as tree + stats in one call.

`siyuan health` checks 7 items: connection latency, token validity, document/block counts, search API availability, MCP server status, and config sources. Won't crash if SiYuan is down — shows a clean error report instead.

### Database / Attribute Views (v3.7+)

SiYuan 3.7+ has a full database/attribute view API. 13 CLI subcommands:

```bash
siyuan av list                         # List all databases
siyuan av get <id>                     # Get database definition
siyuan av search <id> [query]          # Search within a database
siyuan av render <id> --view <vid>     # Render a view

siyuan av add-entry <id> --block <id>  # Add block as entry
siyuan av rm-entry <id> --block <id>   # Remove entry
siyuan av add-field <id> --name Status --type select --options todo,done,wip
siyuan av rm-field <id> --key <k>
siyuan av set <id> --block <b> --key <k> --value done
siyuan av layout <id> --view <v> --type kanban
siyuan av filter <id> --view <v> --filter '[...]'
siyuan av sort   <id> --view <v> --sort '[...]'
siyuan av group  <id> --view <v> --key <k>
```

### Block Operations

Blocks are SiYuan's core abstraction — every paragraph, heading, and list item is an independently addressable block with a unique ID.

```bash
siyuan block children <id>           # List child blocks
siyuan block append <id> -c "content" # Append a child
siyuan block prepend <id> -c "content" # Prepend a child
siyuan block update <id> -c "new"    # Update a block
siyuan block insert <id> -c "content" # Insert at a position
siyuan block delete <id> --yes       # Delete a block
siyuan block move <id> --parent <pid> # Move to a new parent
siyuan block fold <id>               # Collapse heading
siyuan block unfold <id>             # Expand
```

**Block references** — SiYuan's signature feature. Reference any block from anywhere:

```bash
siyuan block ref 20200812220555-lj3enxa
# → ((20200812220555-lj3enxa 'Start Here'))

siyuan block embed 20200812220555-lj3enxa
# → {{embed ((20200812220555-lj3enxa 'Start Here'))}}

siyuan block link 20200812220555-lj3enxa
# → siyuan://blocks/20200812220555-lj3enxa
```

Pipe ref output into document creation for cross-document linking:

```bash
REF=$(siyuan block ref 20200812220555-lj3enxa)
siyuan create "/new-note" "As $REF explained..."
```

> **Windows users**: pipe through `--format json` to avoid encoding issues in PowerShell:

```powershell
$ref = (siyuan --format json block ref $id | ConvertFrom-Json).data.ref
siyuan create "/new-note" "As $ref explained..."
```

### Breadcrumbs & Backlinks

```bash
siyuan block breadcrumb <id>       # Hierarchy path
siyuan block siblings <id>         # Sibling blocks at same level
siyuan backlinks get <id>          # Reverse links
```

Backlink detection on SiYuan 3.6.x is limited — the API doesn't store `((id))` notation in the content column. Three-tier fallback: `((id))` pattern match → `block/getBlockBacklink` API → substring search on block content.

### Tags & Attributes

```bash
siyuan tag list [--limit 100]             # All tags
siyuan tag blocks <tag-name>              # Find blocks with a tag
siyuan attr get <id>                      # Read attributes
siyuan attr set <id> <key> <value>        # Set attribute
```

Attribute keys require a `custom-` or `bookmark-` prefix.

### Notebooks & Files

```bash
siyuan notebook list
siyuan notebook create "New Notebook"
siyuan notebook rename <id> "New Name"
siyuan notebook remove <id> --yes
siyuan notebook conf <id>

siyuan file list /data/
siyuan file get /path
siyuan file put local.txt /remote/path
```

### Daily Notes

```bash
siyuan daily-note note                 # Get or create today's note
siyuan daily-note append "did stuff"   # Append content
```

### Diff

```bash
siyuan diff /notes/v1 /notes/v2        # Side-by-side comparison
siyuan diff /notes/v1 /notes/v2 -c 5   # 5 lines of context
```

Color-coded output: green for additions, red for deletions, cyan for hunk headers. Cross-notebook diff supported via `--notebook-b`.

### Clone

```bash
siyuan clone /templates/weekly /weekly/2026-W27
siyuan clone /src /dst --dry-run        # Preview first
```

Deep-copies a document preserving all child blocks and structure.

### Batch Operations

```bash
siyuan batch create list.txt           # Batch create
siyuan batch delete list.txt --dry-run # Preview
siyuan batch delete list.txt --yes     # Execute
```

Input format — one path per line, optional content after `|`:
```
/note1|# Title\nContent
/note2|# Another
/note3
```

### Utilities

```bash
siyuan asset upload image.png          # Upload an asset
siyuan notify push "message"           # Push notification to SiYuan UI
siyuan mcp                              # Start MCP protocol server
```

---

## Multi-Server

```bash
siyuan workspace add hk --url http://192.168.1.100:6806 --token xxx
siyuan workspace use hk
siyuan workspace list
siyuan workspace which
```

For remote servers, tunnel via SSH first:

```bash
ssh -L 6806:127.0.0.1:6806 user@server -N -f
siyuan workspace use hk
siyuan stats
```

---

## Permission System

Lock down what an AI agent can do:

```bash
# Block all deletion
siyuan permission deny --endpoint "*remove*"

# Ask before touching the archive
siyuan permission ask --endpoint "*delete*" --path "/archive/*"

# Read-only on a sensitive notebook
siyuan permission deny --notebook "secret-notebook"

# Block all write operations (action matcher: read/write/any)
siyuan permission deny --action write

# Block writes to a document subtree
siyuan permission deny --root_id "20260101-abc123"

# Inspect rules
siyuan permission list
```

Rules are evaluated top-to-bottom, first match wins. The `endpoint`, `action`, `notebook`, `path`, and `root_id` matchers are all optional — omitting one means "match all" for that dimension. Supports fnmatch globs.

**Built-in safety net (cannot be bypassed by allow rules)**:
- **Destructive operations require `--yes`**: delete-type endpoints (`removeDoc`, `deleteBlock`, `removeNotebook`, …) require explicit `--yes` confirmation even when rules say `allow`
- **Response filtering**: `search` / `sql` / `notebook list` automatically strip results from deny-covered notebooks, so a bare `query/sql` cannot leak restricted content

Rules live in `~/.siyuan/permissions.json` with mode 600.

---

## MCP Server

Exposes 35 tools to any MCP-compatible AI tool (Claude Desktop, Cursor, etc.).

Add to your MCP client config:

```json
{
  "mcpServers": {
    "siyuan": {
      "command": "siyuan-mcp"
    }
  }
}
```

Or launch directly:

```bash
siyuan mcp
```

The MCP server speaks JSON-RPC 2.0 over stdio. Tools reuse the CLI's command handlers — no duplicate logic.

---

## Agent Skills

After installing siyuan-cli, a single command auto-installs skills to all detected AI agents:

```bash
# Auto-detect and install to Hermes / OpenCode / Claude Code / Codex CLI
siyuan install-skills

# Install only to a specific agent
siyuan install-skills --agent hermes

# Preview what would be installed (no writes)
siyuan install-skills --dry-run
```

`--dry-run` shows which files go where without writing anything.

If auto-detection misses your agent path, use environment variables:

```bash
SIYUAN_HERMES_SKILLS=/custom/path siyuan install-skills
```

| Agent | Env Variable | Default Path |
|-------|-------------|-------------|
| **Hermes** | `SIYUAN_HERMES_SKILLS` | `~/.hermes/skills/` |
| **OpenCode** | `SIYUAN_OPENCODE_SKILLS` | `~/.opencode/skills/` |
| **Claude Code** | `SIYUAN_CLAUDE_SKILLS` | `~/.claude/skills/` |
| **Codex CLI** | `SIYUAN_CODEX_SKILLS` | `~/.codex/skills/` |

Four skills are included:

| Skill | Purpose |
|-------|---------|
| **siyuan-cli** | Operate SiYuan via the CLI |
| **siyuan-api** | Direct REST API calls |
| **siyuan-markdown** | SiYuan-flavored Markdown reference |
| **siyuan-test** | Automated integration testing |

---

## Automated Testing

The project includes an integration test runner that validates every feature against a live SiYuan instance:

```bash
python scripts/siyuan_test.py
```

69 test items spanning: connection diagnostics, notebook CRUD, document creation (inline + file-based), block operations (append/prepend/insert/update/fold/ref/embed/link), tags and attributes, batch operations, diff and clone, daily notes.

Add `--keep` to leave the test documents in SiYuan for inspection:

```bash
python scripts/siyuan_test.py --keep
```

The test notebook contains three demo documents: a full-features showcase (code highlighting, LaTeX math, Mermaid diagrams, callout blocks), a math notes demo (linear algebra, calculus, probability), and a CLI operations demo (built dynamically with block references and embeds).

---

## Windows Notes

Three Windows-specific issues are handled in-code:

1. **Chinese characters in CLI arguments** — Python decodes `sys.argv` using the ANSI code page (GBK). On startup, the CLI re-parses the command line via the Windows Unicode API (`GetCommandLineW` / `CommandLineToArgvW`) to bypass this entirely.

2. **CRLF line endings** — SiYuan stores content with `\r\n`. The client layer normalizes all API responses: `\r\n` → `\n` before any command handler sees them.

3. **git-bash/MSYS path mangling** — MSYS converts `/path/to/doc` to `C:/Program Files/Git/path/to/doc`. Prefix with `MSYS_NO_PATHCONV=1`:

```bash
MSYS_NO_PATHCONV=1 siyuan create /path/to/doc
```

---

## Configuration Priority

Token and URL resolution order, highest to lowest:

1. Environment variables `SIYUAN_TOKEN` / `SIYUAN_URL`
2. Active workspace (`siyuan workspace use`)
3. System keyring (`pip install keyring; siyuan keyring-set <token>`)
4. `~/.siyuan/config.json`
5. `/tmp/siyuan_token` (legacy server-side)

---

## Known Limitations

- `search/search` returns 404 on SiYuan 3.6.5 — CLI falls back to SQL search automatically (v3.7+ OK)
- Block refs `((id))` not stored in content on v3.6.x — backlink detection is best-effort (v3.7+ OK)
- `tag rename/remove` has no effect on v3.6.x — the API doesn't persist tag changes (v3.7+ OK)
- No WebSocket real-time sync
- Database (attribute view) API requires SiYuan v3.7.0+

SiYuan v3.7.0+ adds 16 database/attribute view API endpoints — see the `siyuan-api` skill for details.

---

## Compared to Alternatives

| Feature | siyuan-cli | frostime/siyuan-cli | siyuan-agent-mcp |
|---------|-----------|---------------------|-------------------|
| Language | Python (stdlib) | Node.js | Python |
| Dependencies | 0 | npm packages | some |
| MCP server | Yes (35 tools) | No | Yes (15 tools) |
| Permission system | Yes | Yes | No |
| Multi-workspace | Yes | Yes | No |
| Agent Skills | 7 | No | No |
| Integration tests | 321 items | No | No |
| Audit logging | Yes | No | No |

---

## Roadmap

- Operation history / rollback (`/api/history/createDocHistory`)
- Web admin panel
- Database view templates

---

*Community project, not affiliated with SiYuan Note. MIT License.*
