Wolai Mcp Skill

TotalClaw 作者 cizixiu v1.2.12

通过 wolai Open API 操作 wolai 笔记,支持读取页面/块内容、创建各类块(文本、标题、代码、待办、列表、媒体等)、获取数据库、向数据库插入数据、获取/刷新 Token、分页遍历。当用户需要读取 wolai 页面、向 wolai 写入内容、操作 wolai 数据库、或与 wolai 进行任何数据交互时使用此 skill。触发场景:「读取 wolai 页面」、「在 wolai 里写入」、「查询 wolai 数据库」、「往 wolai 插入数据」、「获取 wolai token」、「遍历 wolai 所有内容」等。

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:cizixiu~wolai-mcp-skill
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Acizixiu~wolai-mcp-skill/file -o wolai-mcp-skill.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/24c44533da0b8747f4e5df85dca2367c7c17b515
# wolai API Skill

通过 wolai Open API(RESTful)操作 wolai 的块、页面、数据库。

Base URL:`https://openapi.wolai.com/v1`

---

## Setup

### 1. 创建应用并获取 Token

1. 前往 https://www.wolai.com/dev 创建应用(需空间管理员权限)
2. 选择所需**应用能力**(最小权限原则):
   - 读取页面内容
   - 插入页面内容
   - 更新页面内容
3. 创建后得到 `App ID` 和 `App Secret`
4. 调用 `POST /token` 换取 `app_token`
5. 将 Token 告知 AI 助手,由 AI 负责完成后续配置

> ⚠️ **Token 安全须知**
>
> wolai App Token 设计为永久有效(`expire_time: -1`),这是 wolai 平台的设计。使用时请勿将 Token 泄露给他人或公开到代码库/聊天记录中。如泄露:在 wolai 应用管理页面重置 App Secret,然后重新调用 `POST /token` 获取新 Token(旧 Token 立即失效)。

### 2. 工作空间权限说明

| 空间类型 | 权限规则 |
|--------|--------|
| **个人空间** | 默认拥有全部页面权限,无需额外操作 |
| **团队空间** | 每个页面需单独添加应用:页面右上角 → 页面协作 → 应用权限 → 添加应用 |

---

## 凭证预检

每次调用前先检查 Token:

```powershell
if (-not $env:WOLAI_TOKEN) {
    Write-Error "缺少 WOLAI_TOKEN,请按 Setup 步骤配置"
    exit 1
}
```

---

## API 调用封装

所有请求统一使用 PowerShell(Windows 环境),Token 放在 `Authorization` Header:

```powershell
function Invoke-WolaiApi {
    param(
        [string]$Method = "GET",
        [string]$Path,
        [hashtable]$Body = $null,
        [hashtable]$Query = $null,
        [switch]$RawJson  # 新增:返回原始 JSON 字符串而非对象(避免中文乱码)
    )
    # ⚠️ 必须强制 UTF-8,否则中文内容会变成问号
    [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    $OutputEncoding = [System.Text.Encoding]::UTF8

    $headers = @{
        "Authorization" = $env:WOLAI_TOKEN
        "Content-Type"  = "application/json; charset=utf-8"
    }

    $uri = "https://openapi.wolai.com/v1$Path"

    # 拼接 Query 参数(用于分页等)
    if ($Query) {
        $qs = ($Query.GetEnumerator() | ForEach-Object {
            # URL 编码值(防止特殊字符问题)
            "$($_.Key)=$([System.Web.HttpUtility]::UrlEncode("$($_.Value)"))"
        }) -join "&"
        $uri = "$uri?$qs"
    }

    try {
        if ($RawJson) {
            # 返回原始 JSON 字符串(适合中文内容)
            $resp = Invoke-WebRequest -Method $Method -Uri $uri -Headers $headers
            if ($Body) {
                $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes(($Body | ConvertTo-Json -Depth 10))
                $resp = Invoke-WebRequest -Method $Method -Uri $uri -Headers $headers -Body $bodyBytes
            }
            return $resp.Content
        } else {
            # 返回解析后的对象
            if ($Body) {
                $bodyBytes = [System.Text.Encoding]::UTF8.GetBytes(($Body | ConvertTo-Json -Depth 10))
                $response = Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers -Body $bodyBytes
            } else {
                $response = Invoke-RestMethod -Method $Method -Uri $uri -Headers $headers
            }
            return $response
        }
    } catch {
        # 解析 wolai API 错误响应
        $errBody = $_.ErrorDetails.Message | ConvertFrom-Json
        if ($errBody.error_code) {
            Write-Error "wolai API 错误 [$($errBody.error_code)]: $($errBody.message)"
        } else {
            Write-Error "请求失败: $($_.Exception.Message)"
        }
        return $null
    }
}
```

**解决中文乱码的两种方式:**

```powershell
# 方式1:写入文件(推荐,完美支持中文)
$json = Invoke-WolaiApi -Method GET -Path "/databases/p4NEGH7dgHEvKZDBzaKuRh" -RawJson
[System.IO.File]::WriteAllText("D:\output.json", $json, [System.Text.UTF8Encoding]::new($false))

# 方式2:通过对象属性访问(适合程序处理)
$db = Invoke-WolaiApi -Method GET -Path "/databases/p4NEGH7dgHEvKZDBzaKuRh"
$db.data.rows[0].data  # 直接访问嵌套属性,控制台可能乱码但值正确
```

**频率控制(5次/秒限制保护):**

```powershell
# 在连续多次调用 API 时,加入间隔避免触发频率限制
# wolai 限制:同一用户 5次/秒,即每次调用至少间隔 200ms
$script:lastWolaiCall = [DateTime]::MinValue

function Wait-WolaiRateLimit {
    param([int]$MinIntervalMs = 250)  # 留 50ms 余量
    $elapsed = ((Get-Date) - $script:lastWolaiCall).TotalMilliseconds
    if ($elapsed -lt $MinIntervalMs) {
        Start-Sleep -Milliseconds ($MinIntervalMs - $elapsed)
    }
    $script:lastWolaiCall = Get-Date
}

# 使用示例:在循环中调用
do {
    Wait-WolaiRateLimit
    $resp = Invoke-WolaiApi -Method GET -Path "/blocks/$pageId/children" -Query $query
    # ...
} while ($resp.has_more)
```

---

## 接口决策表

| 用户意图 | 接口 | 说明 |
|---------|------|------|
| 读取页面/块信息 | `GET /blocks/{id}` | id 为页面 ID 或块 ID |
| 读取页面下所有子块 | `GET /blocks/{id}/children` | 支持分页 `?page_size=&start_cursor=` |
| 向页面写入/追加内容 | `POST /blocks` | 需指定 `parent_id`,一次最多 20 个块 |
| 读取数据库(表格) | `GET /databases/{id}` | 支持分页,每次最多 200 行 |
| 向数据库插入行 | `POST /databases/{id}/rows` | 字段名需与列名完全匹配,一次最多 20 行 |
| 获取 Token | `POST /token` | 需要 `appId` + `appSecret` |
| 刷新 Token(泄露时) | `PUT /token` | 旧 Token 立即失效 |

---

## 接口限制

| 限制类型 | 说明 |
|--------|------|
| **频率** | 同一用户 5 次/秒 |
| **批量获取** | 一次最多 200 条,超出用分页 |
| **批量创建/更新** | 一次最多 20 条 |
| **删除** | 每次只能删除 1 条 |
| **附件上传** | 每次 1 个,最大 1024MB |

**每小时/每月用量限制(按套餐):**

| 套餐 | 每小时 | 每月 |
|-----|-------|------|
| 个人免费版 | 10次 | 100次 |
| 个人专业版 | 500次 | 10,000次 |
| 家庭版 | 800次 | 20,000次 |
| 小组版 | 1,000次 | 30,000次 |
| 团队版 | 1,500次 | 60,000次 |
| 企业版 | 3,000次 | 200,000次 |

---

## 常用工作流

### 读取页面/块信息

```powershell
# 页面 ID 从 URL 获取:wolai.com/ 后面的部分即为页面 ID
$pageId = "oaBQLqSBaMbS6S4NX4fJU7"

# 获取页面块基本信息(标题、类型等)
$page = Invoke-WolaiApi -Method GET -Path "/blocks/$pageId"
$page.data

# 获取页面第一层子块列表(默认最多 200 条)
$children = Invoke-WolaiApi -Method GET -Path "/blocks/$pageId/children"
$children.data
```

**返回的块对象字段说明:**

| 字段 | 类型 | 说明 |
|-----|-----|------|
| `id` | string | 块唯一 ID |
| `type` | string | 块类型(见块类型表) |
| `content` | array | 富文本内容数组 |
| `parent_id` | string | 父块 ID |
| `page_id` | string | 所在页面 ID |
| `children.ids` | array | 子块 ID 列表 |
| `created_at` | number | 创建时间戳(ms) |
| `edited_at` | number | 最后编辑时间戳(ms) |

---

### 分页遍历所有子块

当页面内容较多时,需要循环分页:

```powershell
$pageId = "your_page_id"
$allBlocks = @()
$cursor = $null

do {
    $query = @{ page_size = 200 }
    if ($cursor) { $query["start_cursor"] = $cursor }

    $resp = Invoke-WolaiApi -Method GET -Path "/blocks/$pageId/children" -Query $query
    $allBlocks += $resp.data
    $cursor = $resp.next_cursor
} while ($resp.has_more)

Write-Host "共获取 $($allBlocks.Count) 个块"
```

---

### 向页面写入内容(创建块)

```powershell
# 在指定页面末尾追加内容(可同时创建多个块,最多 20 个)
$result = Invoke-WolaiApi -Method POST -Path "/blocks" -Body @{
    parent_id = "oaBQLqSBaMbS6S4NX4fJU7"
    blocks = @(
        @{
            type    = "text"
            content = "这是一段普通文字"
        },
        @{
            type    = "heading"
            level   = 1
            content = "这是一级标题"
        },
        @{
            type    = "divider"  # 分隔线,无需 content
        }
    )
}
# 返回:成功时 $result.data 为新块的访问链接
```

---

### 创建富文本内容

`content` 字段(CreateRichText)支持三种写法:

```powershell
# 写法1:纯字符串(最简单)
content = "Hello World"

# 写法2:单个富文本对象(可设置样式)
content = @{
    title      = "加粗红色文字"
    bold       = $true
    front_color = "red"
}

# 写法3:混合数组(字符串和富文本对象混用)
content = @(
    @{ title = "加粗"; bold = $true },
    "普通文字",
    @{ title = "斜体高亮"; italic = $true; highlight = $true }
)
```

**RichText 可用样式属性:**

| 属性 | 类型 | 说明 |
|-----|-----|------|
| `title` | string | 文本内容(必填) |
| `bold` | boolean | 加粗 |
| `italic` | boolean | 斜体 |
| `underline` | boolean | 下划线 |
| `highlight` | boolean | 高亮 |
| `strikethrough` | boolean | 删除线 |
| `inline_code` | boolean | 行内代码 |
| `front_color` | BlockFrontColors | 文字颜色 |
| `back_color` | BlockBackColors | 背景色 |

> ⚠️ 注意:创建块时 RichText 的 `type` 字段暂只支持 `"text"` 和 `"equation"`(纯文本可不传 type)

---

### 各类块的完整创建示例

```powershell
# 文本块(支持富文本)
@{ type = "text"; content = "Hello" }

# 标题块(level 1-4)
@{ type = "heading"; level = 2; content = "二级标题"; toggle = $false }

# 引用块
@{ type = "quote"; content = "这是引用内容" }

# 着重文字块(callout)
@{
    type = "callout"
    content = "重要提示"
    icon = @{ type = "emoji"; icon = "⚠️" }
    # marquee_mode = $true  # 开启跑马灯滚动效果
}

# 代码块
@{
    type = "code"
    language = "python"  # 也可用 "mermaid" 画流程图/时序图
    content  = "print('Hello, wolai!')"
    caption  = "示例代码"
    code_setting = @{
        line_number = $true    # 显示行号
        line_break  = $true    # 自动换行
        ligatures   = $false   # 连字符
    }
}

# 任务列表(todo_list)
@{ type = "todo_list"; content = "待办事项"; checked = $false }

# 高级任务列表(todo_list_pro)
@{
    type