# Siyuan Mcp Server

> 思源笔记MCP / SiYuan MCP Server

- **Type:** MCP server
- **Install:** `agentstack add mcp-xgq18237-siyuan-mcp-server`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [xgq18237](https://agentstack.voostack.com/s/xgq18237)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [xgq18237](https://github.com/xgq18237)
- **Source:** https://github.com/xgq18237/siyuan_mcp_server

## Install

```sh
agentstack add mcp-xgq18237-siyuan-mcp-server
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 🧠 SiYuan MCP Server

[简体中文](./README.md) | [English](./README_EN.md)

> 让 Claude、Cursor、Codex 等 AI 客户端安全地读取和操作思源笔记。

`siyuan-mcp` 是一个基于 [Model Context Protocol](https://modelcontextprotocol.io/) 的思源笔记 MCP 服务器。它通过思源 Kernel API 提供笔记本、文档、内容块、全文搜索、原生数据库、资源文件和导出等能力，并针对 AI 自动化场景增加了结构化返回、安全注解与默认防护。

当前版本：`1.1.1`

---

## ✨ 核心亮点

| 能力 | 说明 |
| --- | --- |
| 📚 笔记本与文档 | 创建、浏览、搜索、重命名、移动和删除 |
| 🧱 内容块 | Markdown/DOM 插入、更新、移动、折叠、引用和批量操作 |
| 🔎 搜索 | 文档标题搜索、全文块搜索和 SQL 查询 |
| 🗃️ 原生数据库 | 创建 AV 数据库、字段、条目、单元格和批量更新 |
| 📎 文件与资源 | Multipart 上传、工作空间文件读写和二进制 Base64 返回 |
| 🧩 模板与转换 | Template、Sprig、Pandoc、Markdown 和资源导出 |
| 🛡️ 可选防护 | 删除类操作保护开关、路径白名单和响应上限 |
| 🤖 MCP 友好 | `structuredContent`、`isError`、工具安全注解和纯净 stdio |

项目目前提供约 69 个面向 AI 使用场景设计的工具。它选择性封装稳定且实用的思源接口，不追求暴露全部内核私有 API。

## 🧭 工作原理

```mermaid
flowchart LR
    A["AI 客户端Claude / Cursor / Codex"] -->|MCP stdio| B["SiYuan MCP Server"]
    B -->|HTTP + Token| C["SiYuan Kernel API"]
    C --> D["笔记本 / 文档 / 内容块"]
    C --> E["数据库 AV"]
    C --> F["资源 / 模板 / 导出"]
```

所有调试信息只写入 `stderr`，`stdout` 始终保留给 MCP JSON-RPC，避免客户端因混入普通日志而断开连接。

---

## 🚀 快速开始

### 🤖 让智能体自动配置

只需复制下面的提示词，并填写 MCP 客户端和思源 Token。默认连接本机 `127.0.0.1:6806`；使用其他地址时再修改 HOST 和 PORT。

```text
请帮我配置最新版 siyuan-mcp。

用户配置：
- MCP 客户端：{{填写 Codex、Claude Desktop、Cursor 等}}
- 思源 API Token：{{填写 Token}}
- SIYUAN_HOST：127.0.0.1
- SIYUAN_PORT：6806

请直接执行：

1. 检查 Node.js 是否已安装且版本不低于 18。
   - 如果 Node.js 未安装或版本低于 18，只告诉我需要安装或升级 Node.js，然后停止。
   - 不要尝试用其他方式绕过 Node.js 要求。

2. 自动找到当前 MCP 客户端的配置文件，保留已有配置，只新增或更新名为 `siyuan_note` 的 MCP 配置：
   - command: `npx`
   - args: `["-y", "siyuan-mcp@latest"]`
   - env:
     - `SIYUAN_HOST`
     - `SIYUAN_PORT`
     - `SIYUAN_TOKEN`

3. 安全要求：
   - 不要覆盖、删除或重排其他 MCP 配置。
   - 不要在回复中回显完整 Token。
   - 不要把 Token 写入项目代码、仓库文件、临时脚本或日志。
   - Token 只能写入 MCP 客户端的用户级配置文件。

4. 配置完成后，尝试让当前 MCP 客户端重新加载 MCP 配置。
   - 如果当前客户端支持在设置里重启/刷新 MCP 配置，请提示我去设置里执行该操作，然后停止，等我完成后再继续测试。
   - 如果当前客户端必须完整重启才能加载新的 MCP，请明确告诉我“需要重启客户端”，然后停止。
   - 不要为了测试连接而手写 MCP JSON-RPC 脚本、临时 Node 脚本或自定义客户端。

5. MCP 重新加载成功后，只使用当前 MCP 客户端已经加载的 `siyuan_note` MCP 能力测试连接：
   - 优先直接调用 `list_notebooks` 工具。
   - 如果客户端只暴露了等价的 notebooks 资源而没有暴露工具函数，可以读取该 notebooks 资源。
   - 不要调用其他工具或读取其他内容。

6. 最后只告诉我：
   - 配置是否成功；
   - 是否需要在设置里重启/刷新 MCP，或是否需要完整重启客户端；
   - 当前已开启的笔记本名称。

除非 Node.js 不满足要求、找不到配置文件、需要你去设置里重启/刷新 MCP、或必须完整重启客户端，否则不要中途询问，直接完成配置。
```

### 1. 准备环境

- Node.js `>= 18`
- 已启动的思源笔记
- 思源 API Token

API Token 获取位置：

> 思源笔记 → 设置 → 关于 → API Token

### 2. 使用 npx 启动

```bash
npx -y siyuan-mcp@latest
```

MCP 服务器通常由 AI 客户端自动启动，不需要单独打开终端常驻运行。

### 3. 配置 MCP 客户端

```json
{
  "mcpServers": {
    "siyuan_note": {
      "command": "npx",
      "args": ["-y", "siyuan-mcp@latest"],
      "env": {
        "SIYUAN_HOST": "127.0.0.1",
        "SIYUAN_PORT": "6806",
        "SIYUAN_TOKEN": "your-api-token-here"
      }
    }
  }
}
```

该配置形式可用于 Cursor、Claude Desktop 以及其他支持 stdio MCP 的客户端。不同客户端的配置文件位置可能不同，但 `command`、`args` 和 `env` 内容基本一致。

为兼容旧版配置，推荐继续使用 `SIYUAN_HOST`、`SIYUAN_PORT` 和 `SIYUAN_TOKEN`。连接远程实例、反向代理或带路径前缀的实例时，可以使用 `SIYUAN_URL` 覆盖 HOST/PORT：

```json
{
  "env": {
    "SIYUAN_URL": "https://siyuan.example.com",
    "SIYUAN_TOKEN": "your-api-token-here"
  }
}
```

### 4. 验证连接

连接后可以让 AI 尝试：

```text
检查思源连接状态，并列出当前打开的笔记本。
```

或者直接调用：

- `check_siyuan_status`
- `list_notebooks`
- `get_version`

---

## 🧰 功能地图

### 📚 笔记本

| 工具 | 用途 |
| --- | --- |
| `list_notebooks` | 列出所有笔记本及打开状态 |
| `create_notebook` | 创建笔记本 |
| `open_notebook` / `close_notebook` | 打开或关闭笔记本 |
| `rename_notebook` | 重命名笔记本 |
| `get_notebook_conf` / `set_notebook_conf` | 读取或保存配置 |
| `remove_notebook` | 删除笔记本，属于危险操作 |

### 📄 文档与文档树

| 工具 | 用途 |
| --- | --- |
| `create_doc` | 使用 Markdown 创建文档 |
| `search_docs` | 按标题搜索文档 |
| `list_docs` | 浏览指定路径下的文档 |
| `rename_doc` / `rename_doc_by_id` | 重命名文档 |
| `move_docs` / `move_docs_by_id` | 移动文档 |
| `get_hpath_by_id` | 获取人类可读路径 |
| `get_path_by_id` | 获取底层存储路径 |
| `remove_doc` / `remove_doc_by_id` | 删除文档 |

### 🧱 内容块

支持 Markdown 和思源 DOM 两种输入格式。

| 工具 | 用途 |
| --- | --- |
| `insert_block` | 在指定锚点插入块 |
| `append_block` / `prepend_block` | 在父块前后插入子块 |
| `update_block` | 更新块内容 |
| `move_block` | 调整块位置 |
| `batch_insert_blocks` | 批量插入 |
| `batch_update_blocks` | 批量更新 |
| `get_block_info` | 获取块元数据 |
| `get_block_kramdown` | 获取 Kramdown 源码 |
| `get_block_breadcrumb` | 获取块面包屑 |
| `fold_block` / `unfold_block` | 折叠或展开 |
| `transfer_block_ref` | 转移块引用 |
| `set_block_attrs` / `get_block_attrs` | 操作块属性 |

`insert_block` 需要至少提供一个位置参数：

- `nextID`
- `previousID`
- `parentID`

### 🔎 搜索与查询

#### 全文搜索

`search_blocks` 使用思源原生全文搜索，支持：

- 普通关键词
- 查询语法
- 正则表达式
- 文档路径过滤
- 块类型过滤
- 分页、排序和按文档分组

#### SQL 查询

`sql_query` 会将 SQL 原样交给思源 Kernel API，不限制语句类型，也不会自动补充 `LIMIT`。调用写入、删除或结构变更语句前，请自行确认影响；查询大量数据时应主动添加 `LIMIT`。

示例：

```sql
SELECT id, content, hpath, updated
FROM blocks
WHERE type = 'd'
ORDER BY updated DESC
LIMIT 20
```

优先使用 `search_docs` 和 `search_blocks`。只有在需要精确字段、聚合或复杂过滤时才建议使用 SQL。

---

## 🗃️ 原生数据库支持

数据库工具直接操作思源 Attribute View（AV），不是 Markdown 表格。

| 工具 | 用途 |
| --- | --- |
| `create_database` | 插入 AV 块并初始化数据库存储 |
| `get_database` | 分页渲染数据库 |
| `get_database_keys` | 获取字段定义 |
| `rename_database` | 重命名数据库 |
| `add_database_column` | 添加字段 |
| `remove_database_column` | 删除字段 |
| `append_database_rows` | 添加非绑定条目 |
| `set_database_cell` | 设置单元格 |
| `batch_set_database_cells` | 批量设置单元格 |
| `remove_database_rows` | 删除条目 |

### 创建数据库

```json
{
  "parentID": "20260628160104-6d71dw0",
  "name": "项目清单",
  "columns": [
    {
      "name": "状态",
      "type": "select"
    },
    {
      "name": "完成",
      "type": "checkbox"
    },
    {
      "name": "备注",
      "type": "text"
    }
  ]
}
```

创建过程会自动完成：

1. 生成合法 AV ID。
2. 插入 `NodeAttributeView` 块。
3. 调用 `renderAttributeView` 创建数据库存储。
4. 设置数据库名称。
5. 创建附加字段。

如果初始化失败，服务器会尝试回滚已插入的数据库块。

### 添加条目

```json
{
  "avID": "20260628163701-rc230o0",
  "blockID": "20260628163701-7rmjwsl",
  "titles": [
    "整理需求",
    "实现功能",
    "发布版本"
  ]
}
```

### 更新单元格

`set_database_cell` 的 `value` 使用思源 AV Value 结构。

文本字段示例：

```json
{
  "avID": "数据库 ID",
  "keyID": "字段 ID",
  "itemID": "条目 ID",
  "value": {
    "text": {
      "content": "已经完成"
    }
  }
}
```

复选框字段示例：

```json
{
  "value": {
    "checkbox": {
      "checked": true
    }
  }
}
```

常用字段类型包括：

`text`、`number`、`date`、`select`、`mSelect`、`url`、`email`、`phone`、`mAsset`、`checkbox`、`created` 和 `updated`。

---

## 📎 文件与资源

### 资源上传

`upload_asset` 使用真正的 HTTP Multipart 表单，不会把文件路径误当作 JSON 发送。

```json
{
  "assetsDirPath": "/assets/",
  "files": [
    "C:\\Users\\me\\Pictures\\diagram.png"
  ]
}
```

本地文件必须位于 `SIYUAN_MCP_UPLOAD_ROOTS` 允许的目录中。

### 工作空间文件

| 工具 | 用途 |
| --- | --- |
| `get_file` | 获取文本、JSON 或二进制文件 |
| `put_file` | Multipart 写入文件或创建目录 |
| `read_dir` | 浏览目录 |
| `rename_file` | 重命名文件 |
| `remove_file` | 删除文件 |

返回策略：

- JSON：直接返回结构化对象
- 文本：返回 UTF-8 字符串
- 二进制：返回 Base64、MIME 类型和字节数

`put_file` 支持三种输入方式：

- `filePath`：本地文件路径
- `file`：UTF-8 文本
- `contentBase64`：Base64 数据

---

## 🛡️ 安全设计

### 可选的危险操作保护

删除类操作默认可用。若希望 MCP 只允许创建、读取和普通更新，可显式开启保护：

```text
SIYUAN_MCP_PROTECT_DESTRUCTIVE=true
```

只有该参数显式为 `true` 或 `1` 时，以下操作才会被拒绝：

- 删除笔记本、文档和内容块
- 删除数据库字段或条目
- 覆盖、移动或删除工作空间文件

未配置、设为 `false` 或设为 `0` 时，删除类操作正常可用。

> 升级提醒：旧变量 `SIYUAN_MCP_ALLOW_DESTRUCTIVE` 已不再参与判断。若希望继续保持“拒绝删除”的行为，请改为 `SIYUAN_MCP_PROTECT_DESTRUCTIVE=true`。

### SQL 直接执行

`sql_query` 默认允许思源 Kernel API 支持的 SQL，不再区分“安全 SQL”和“危险 SQL”，也不自动添加行数限制。建议在查询语句中自行添加 `LIMIT`，并谨慎执行写入或结构变更语句。

旧变量 `SIYUAN_MCP_ALLOW_UNSAFE_SQL` 和 `SIYUAN_MCP_SQL_MAX_ROWS` 已不再使用。

### 工作空间写入白名单

默认允许：

```text
/data/assets,/temp
```

自定义：

```text
SIYUAN_MCP_WRITE_PATH_PREFIXES=/data/assets,/data/templates,/temp
```

### 本地上传目录白名单

默认只允许 MCP 进程当前目录。

Windows：

```text
SIYUAN_MCP_UPLOAD_ROOTS=C:\Users\me\Pictures;C:\Users\me\Documents
```

Linux/macOS：

```text
SIYUAN_MCP_UPLOAD_ROOTS=/home/me/Pictures:/home/me/Documents
```

### 连接地址

`SIYUAN_HOST` 和 `SIYUAN_URL` 均可指向本机或远程实例，HTTP 与 HTTPS 都可以使用，MCP 不额外限制协议。通过公网或不可信网络连接时，仍建议由部署者使用 HTTPS 保护 API Token 和传输内容。

---

## ⚙️ 环境变量

| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `SIYUAN_URL` | — | 完整思源 URL，优先于 HOST/PORT |
| `SIYUAN_HOST` | `127.0.0.1` | 思源主机 |
| `SIYUAN_PORT` | `6806` | 思源端口 |
| `SIYUAN_TOKEN` | 空 | 思源 API Token |
| `SIYUAN_MCP_PROTECT_DESTRUCTIVE` | `false` | 显式设为 `true` 或 `1` 时拒绝删除类操作 |
| `SIYUAN_MCP_WRITE_PATH_PREFIXES` | `/data/assets,/temp` | 工作空间写入白名单 |
| `SIYUAN_MCP_UPLOAD_ROOTS` | 当前目录 | 本地上传目录白名单 |
| `SIYUAN_MCP_TIMEOUT_MS` | `120000` | 单次 API 请求超时（2 分钟） |
| `SIYUAN_MCP_MAX_RESPONSE_BYTES` | `10485760` | 最大响应字节数 |
| `SIYUAN_MCP_MAX_TEXT_CHARS` | `30000` | MCP 文本预览长度 |
| `SIYUAN_MCP_DEBUG` | `0` | 向 stderr 输出端点、状态和耗时 |

调试模式不会输出请求 Token 或笔记正文。

---

## 🐳 Docker

本项目采用 MCP stdio 传输。容器必须由 MCP 客户端以前台交互模式启动，因此需要 `-i`。

### 使用已发布镜像

Docker Hub 镜像为 `zhizhiqq/siyuan-mcp`。使用 `latest` 可获得最新版，也可以固定版本标签以确保环境可复现：

```bash
docker pull zhizhiqq/siyuan-mcp:latest
# 当前版本：
docker pull zhizhiqq/siyuan-mcp:v1.1.1
```

### MCP 客户端配置

下面的配置用于连接运行在宿主机上的思源：

```json
{
  "mcpServers": {
    "siyuan_note": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "--add-host",
        "host.docker.internal:host-gateway",
        "-e",
        "SIYUAN_HOST=host.docker.internal",
        "-e",
        "SIYUAN_PORT=6806",
        "-e",
        "SIYUAN_TOKEN",
        "zhizhiqq/siyuan-mcp:latest"
      ],
      "env": {
        "SIYUAN_TOKEN": "your-api-token-here"
      }
    }
  }
}
```

注意：

- 容器内的 `127.0.0.1` 指向容器自身。
- 访问宿主机思源应使用 `host.docker.internal`。
- `--add-host=host.docker.internal:host-gateway` 让 Linux 也能使用相同的宿主机地址；Docker Desktop 已原生支持该地址。
- 必须保留 `-i`，MCP 通过容器的 stdin/stdout 通信。
- `--rm` 会在进程停止后自动删除容器。
- stdio MCP 不应使用普通后台 Compose 服务代替客户端进程。
- `docker compose run --rm siyuan-mcp-server` 可用于手工连通性检查。

### 在 Docker 中上传本地文件

容器不能直接读取任意宿主机文件。需要将允许上传的宿主机目录以只读方式挂载到 `/uploads`，并设置 `SIYUAN_MCP_UPLOAD_ROOTS=/uploads`。在上方配置的镜像名称之前加入：

```json
[
  "--mount",
  "type=bind,src=/宿主机/文件绝对路径,dst=/uploads,readonly",
  "-e",
  "SIYUAN_MCP_UPLOAD_ROOTS=/uploads"
]
```

请将 `/宿主机/文件绝对路径` 替换为实际绝对路径。只有该挂载目录内的文件能够上传。

### 本地构建镜像

如需从当前仓库自行构建，而不是使用 Docker Hub 镜像：

```bash
docker build -t siyuan-mcp-server .
```

然后将 MCP 配置中的 `zhizhiqq/siyuan-mcp:latest` 替换为 `siyuan-mcp-server`。

---

## 📦 本地安装

```bash
git clone https://github.com/xgq18237/siyuan_mcp_server.git
cd siyuan_mcp_server
npm ci
npm run build
node dist/index.js
```

本地源码配置示例：

```json
{
  "mcpServers": {
    "siyuan_note": {
      "command": "node",
      "args": [
        "C:\\path\\to\\siyuan_mcp_server\\dist\\index.js"
      ],
      "env": {
        "SIYUAN_HOST": "127.0.0.1",
        "SIYUAN_PORT": "6806",
        "SIYUAN_TOKEN": "your-api-token-here"
      }
    }
  }
}
```

---

## 🧪 开发与检查

```bash
npm ci
npm run check
npm test
```

| 命令 | 说明 |
| --- | --- |
| `npm run dev` | 使用 `tsx` 运行源码 |
| `npm run check` | TypeScript 严格类型检查 |
| `npm run build` | 构建到 `dist/` |
| `npm test` | 执行类型检查并重新构建 |
| `npm run rebuild` | 清理后重新构建 |
| `npm run test:docker` | 构建测试 Docker 镜像 |

涉及真实思源数据的集成验证应在隔离笔记本中进行，并在完成后清理临时文档、数据库、资源与导出文件。

### 项目结构

```text
siyuan_mcp_server/
├─ src/
│  ├─ index.ts           # MCP 服务与资源
│  ├─ siyuan-client.ts   # JSON / Multipart / 二进制传输层
│  └─ tools.ts           # 工具定义、安全策略与调用实现
├─ dist/                 # 编译后的发布文件
├─ Dockerfile
├─ docker-compose.yml
├─ env.example
└─ package.json
```

---

## 🔧 常见问题

### MCP 客户端无法连接

依次确认：

1. 思源是否正在运行。
2. `SIYUAN_HOST`、`SIYUAN_PORT` 是否正确；使用远程反向代理时再检查 `SIYUAN_URL`。
3. API Token 是否有效。
4. Node.js 是否满足版本要求。
5. 是否有普通日志写入 stdout。

可以先在浏览器打开：

```text
http://127.0.0.1:6806
```

### 返回 `401`、`403` 或鉴权失败

重新复制思源“设置 → 关于”中的 API Token，并重启 MCP 进程。不要在 Token 前后加入引号以外的空格。

### 删除工具提示危险操作保护已开启

当前 MCP 进程显式开启了保护。需要恢复删除能力时，移除该变量或设置：

```text
SIYUAN_MCP_PROTECT_DESTRUCTIVE=false
```

### 上传文件提示不在允许目录

将文件移动到允许目录，或配置：

```text
SIYUAN_MCP_UPLOAD_ROOTS=允许的本地目录
```

### Docker 中无法访问思源

不要使用 `127.0.0.1` 访问宿主机，改用：

```text
SIYUAN_HOST=host.docker.internal
```

### 数据库块存在但无法正常显示

数据库不仅需要 AV 块，还需要对应的 AV 存储。请使用 `create_database`，它会自动调用 `renderAttributeView` 完成初始化。

### 输出过大被截断

优先使用分页、搜索条件或 SQL `LIMIT`。必要时调整：

```text
SIYUAN_MCP_MAX_RESPONSE_BYTES
SIYUAN_MCP_MAX_TEXT_CHARS
```

---

## 🤝 贡献

欢迎提交 Issue 和 Pull Request。新增工具时建议同时考虑：

- 是否适合 AI 自动调用
- 是否属于危险或破坏性操作
- 是否需要分页和输出上限
- 是否应返回结构化数据
- 是否涉及 Multipart 或二进制响应
- 是否会把敏感内容写入日志

## 📄 License

[MIT](./LICENSE)

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [xgq18237](https://github.com/xgq18237)
- **Source:** [xgq18237/siyuan_mcp_server](https://github.com/xgq18237/siyuan_mcp_server)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-xgq18237-siyuan-mcp-server
- Seller: https://agentstack.voostack.com/s/xgq18237
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
