OptionalProductivityVersion 1.0.0

Query and Edit a SiYuan Knowledge Base via API with Hermes Agent

Query and edit a SiYuan knowledge base via its API.

Written by Neura Market from the official Hermes Agent documentation for Siyuan. Commands, paths, and version numbers are reproduced from the source unchanged.

Read the official documentation

SiYuan Kernel API Reference

This reference documents how to interact with a self-hosted SiYuan knowledge base through its kernel API using curl. All operations are performed via POST requests with JSON bodies. The API enables full programmatic management of blocks, documents, and notebooks without a graphical interface.

Prerequisites

Before using the API, ensure SiYuan is installed and running (desktop or Docker). Obtain your API token from Settings > About > API token. Store the token and optionally the base URL in ${HERMES_HOME:-~/.hermes}/.env as shown below. The tools curl and jq should be installed for JSON processing.

SIYUAN_TOKEN=your_token_here
SIYUAN_URL=http://127.0.0.1:6806

If SIYUAN_URL is not set, the default http://127.0.0.1:6806 is used.

General API Call Structure

All API calls use the same pattern: a POST request with an Authorization header and a JSON body. The generic template is:

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/..." \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"param": "value"}'

A successful response has the structure:

{"code": 0, "msg": "", "data": { ... }}

Always check the code field: code: 0 means success. Any other value indicates an error; inspect the msg field for details. A non-zero code (code != 0) signals failure.

Search and Query

Full-Text Search

Search across all blocks using the endpoint /api/search/fullTextSearchBlock. Provide a query string and a 0-based page number. Results are in .data.blocks.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/search/fullTextSearchBlock" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "meeting notes", "page": 0}' | jq '.data.blocks[:5]'

SQL Query

Execute SELECT-only SQL statements against the blocks database using /api/query/sql. Useful columns include id, parent_id, root_id, box (notebook ID), path, content, type, subtype, created, and updated. Use LIMIT to control result size. Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/query/sql" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"stmt": "SELECT id, content, type, box FROM blocks WHERE content LIKE '\''%keyword%'\'' AND type='\''p'\'' LIMIT 20"}' | jq '.data'

Only SELECT statements are allowed. INSERT, UPDATE, DELETE, or DROP statements are dangerous and prohibited.

Reading Blocks and Documents

Read Block Content

Get the Kramdown content of a block using /api/block/getBlockKramdown. Provide the block id. Response data is in .data.kramdown.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/block/getBlockKramdown" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "20210808180117-6v0mkxr"}' | jq '.data.kramdown'

Read Child Blocks

Retrieve child blocks of a given block using /api/block/getChildBlocks. Provide the parent block id. Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/block/getChildBlocks" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "20210808180117-6v0mkxr"}' | jq '.data'

Get Human-Readable Path

Get the human-readable path for a block or document using /api/filetree/getHPathByID. Provide the block or document id. Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/filetree/getHPathByID" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "20210808180117-6v0mkxr"}' | jq '.data'

Get Block Attributes

Retrieve custom attributes of a block using /api/attr/getBlockAttrs. Provide the block id. Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/attr/getBlockAttrs" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "20210808180117-6v0mkxr"}' | jq '.data'

Managing Notebooks

List Notebooks

List all notebooks using /api/notebook/lsNotebooks. Response data is in .data.notebooks, each with id, name, and closed.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/notebook/lsNotebooks" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' | jq '.data.notebooks[] | {id, name, closed}'

List Documents in a Notebook

List documents in a notebook by path using /api/filetree/listDocsByPath. Provide notebook (notebook ID) and path (e.g., /). Response data is in .data.files, each with id and name.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/filetree/listDocsByPath" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"notebook": "NOTEBOOK_ID", "path": "/"}' | jq '.data.files[] | {id, name}'

Create a Notebook

Create a new notebook using /api/notebook/createNotebook. Provide a name. Response contains .data.notebook.id.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/notebook/createNotebook" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My New Notebook"}' | jq '.data.notebook.id'

Delete a Notebook

Delete a notebook using /api/notebook/removeNotebook. Provide {"notebook": "NOTEBOOK_ID"}.

Managing Documents

Create a Document

Create a new document with initial Markdown content using /api/filetree/createDocWithMd. Provide notebook (notebook ID), path (document path, e.g., /Meeting Notes/2026-03-22), and markdown (initial content). Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/filetree/createDocWithMd" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "notebook": "NOTEBOOK_ID",
    "path": "/Meeting Notes/2026-03-22",
    "markdown": "# Meeting Notes\n\n- Discussed project timeline\n- Assigned tasks"
  }' | jq '.data'

Rename a Document

Rename a document using /api/filetree/renameDocByID. Provide id (document ID) and title (new title).

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/filetree/renameDocByID" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "DOCUMENT_ID", "title": "New Title"}'

Delete a Document

Delete a document using /api/filetree/removeDocByID. Provide {"id": "DOC_ID"}.

Export Document as Markdown

Export a document's Markdown content using /api/export/exportMdContent. Provide the document id. Response data is in .data.content. Use jq -r to get the raw string.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/export/exportMdContent" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "DOCUMENT_ID"}' | jq -r '.data.content'

Block Operations

Append, Prepend, or Insert Blocks

Append a block to a parent using /api/block/appendBlock. Provide parentID (document or block ID), data (content string), and dataType (e.g., markdown). Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/block/appendBlock" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "parentID": "DOCUMENT_OR_BLOCK_ID",
    "data": "New paragraph added at the end.",
    "dataType": "markdown"
  }' | jq '.data'

For inserting at the beginning, use /api/block/prependBlock with the same parameters (parentID, data, dataType). To insert after a specific sibling block, use /api/block/insertBlock with previousID instead of parentID.

Update Block Content

Update a block's content using /api/block/updateBlock. Provide id (block ID), data (new content), and dataType (e.g., markdown). Response data is in .data.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/block/updateBlock" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "BLOCK_ID",
    "data": "Updated content here.",
    "dataType": "markdown"
  }' | jq '.data'

Set Block Attributes

Set custom attributes on a block using /api/attr/setBlockAttrs. Provide id (block ID) and attrs (object of key-value pairs). Keys must be prefixed with custom-.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/attr/setBlockAttrs" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "BLOCK_ID",
    "attrs": {
      "custom-status": "reviewed",
      "custom-priority": "high"
    }
  }'

Delete a Block

Delete a single block using /api/block/deleteBlock. Provide the block id.

curl -s -X POST "${SIYUAN_URL:-http://127.0.0.1:6806}/api/block/deleteBlock" \
  -H "Authorization: Token $SIYUAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "BLOCK_ID"}'

Constraints and Caveats

  • All API calls must be POST with JSON bodies. GET requests are not supported.
  • SQL queries must only be SELECT statements. Non-SELECT SQL may corrupt the database.
  • Block IDs follow the pattern YYYYMMDDHHmmss-xxxxxxx (14-digit timestamp + 7 alphanumeric characters). An example is 20210808180117-6v0mkxr.
  • Custom attributes must be prefixed with custom-.
  • Large documents may produce large responses. Use LIMIT in SQL and pipe through jq to extract needed data.
  • Notebook IDs must be obtained via lsNotebooks before use.
  • The API token must be stored in ${HERMES_HOME:-~/.hermes}/.env as SIYUAN_TOKEN.
  • SIYUAN_URL defaults to http://127.0.0.1:6806 if not set.

Failure Modes

  • A non-zero code in the response indicates an error. Check the msg field for details.
  • Using GET instead of POST will fail.
  • Sending non-SELECT SQL statements may corrupt the database.
  • Invalid block ID format will cause errors.
  • Missing or incorrect API token results in authentication failure.
  • Network issues or SiYuan not running will cause connection errors.

MCP Server Configuration

For integration with an MCP server, configure as follows in ~/.hermes/config.yaml:

# In ~/.hermes/config.yaml under mcp_servers:
mcp_servers:
  siyuan:
    command: npx
    args: ["-y", "@porkll/siyuan-mcp"]
    env:
      SIYUAN_TOKEN: "your_token"
      SIYUAN_URL: "http://127.0.0.1:6806"

Skills the docs pair this with

More Productivity skills