Joplin API(中文)
/install joplin-api-china
Joplin Data API Skill
Access Joplin data via the local HTTP REST API (clipper server).
Architecture
Joplin data model:
Folders (笔记本/Notebooks) Notes (笔记)
├── 顶层笔记本 ├── 笔记属于某个 folder (parent_id → folder.id)
│ ├── 子笔记本 (parent_id→父ID) ├── 笔记内容是 Markdown 格式 (body 字段)
│ │ ├── 孙笔记本 └── 可附加标签(tags)、资源(resources)
│ │ │ └── ...无限层级
│ │ └── 孙笔记本
│ └── 子笔记本
└── 顶层笔记本
Key Concepts
- Folders(笔记本) = 目录/文件夹,通过
parent_id形成无限层级的树形结构。每个 folder 可以有任意多个子 folder,没有层级深度限制。顶级 folder 的parent_id为空或指向一个不在当前列表中的父 ID。 - Notes(笔记) = 内容载体,每条笔记通过
parent_id归属到一个且仅一个 folder 下。笔记内容是 Markdown 格式(body字段)。 - Tags(标签) = 跨笔记本的分类标记,可附加到任意笔记上,不受 folder 层级限制。
- Resources(资源) = 附件文件(图片、文档等),可关联到笔记上。
parent_id 关系说明
| 对象 | parent_id 含义 | 示例 |
|---|---|---|
| Folder | 指向父 folder ID;顶级 folder 为空/根 | parent_id: "abc123..." 表示该笔记本是 abc123... 的子目录 |
| Note | 指向所属 folder ID | parent_id: "folder_xyz" 表示该笔记在 folder_xyz 笔记本下 |
Configuration: Token Lifecycle
Token 存储在 OpenClaw 配置 skills.entries.joplin-api.env.JOPLIN_TOKEN。
每次操作 Joplin API 之前,必须按以下流程确认 token:
Step 0: 确认 Token(每次操作前必做)
# 从 OpenClaw 配置读取 token
_jtoken() {
python3 -c "import json; d=json.load(open('$HOME/.openclaw/openclaw.json')); print(d['skills']['entries']['joplin-api']['env'].get('JOPLIN_TOKEN', ''))"
}
TOKEN=$(_jtoken)
然后判断:
| 情况 | 动作 |
|---|---|
TOKEN 有值(非空字符串) |
→ 继续调用 API,用此 token |
TOKEN 为空 |
→ 问用户要 token(见下方提示文案) |
Token 缺失时的用户提示
当 token 为空时,告知用户以下内容:
Joplin API Token 尚未配置。请按以下步骤获取:
- 打开 Joplin 桌面端
- 进入 选项/偏好设置 → Web Clipper
- 找到 Access password(访问密码),这就是 token
- 把这段密码发给我,我会写入配置文件
同时请确认 Joplin Clipper Server 已启用(同一页面有开关)。
安全防护说明
本技能直接调用 Joplin 官方本地 REST API,具备完整的 CRUD 能力。为保护数据安全:
- 读取操作(GET):自由执行,无需批准
- 写入/删除操作(POST/PUT/DELETE):必须在用户明确确认后才执行
- 默认软删除:删除笔记默认移至回收站,除非用户明确要求永久删除
用户给出 Token 后:写入配置
# 将用户提供的 token 写入 OpenClaw 配置
_jset_token \x3CTOKEN_VALUE> {
python3 -c "
import json, sys
path = '$HOME/.openclaw/openclaw.json'
d = json.load(open(path))
d.setdefault('skills', {}).setdefault('entries', {}).setdefault('joplin-api', {}).setdefault('env', {})
d['skills']['entries']['joplin-api']['env']['JOPLIN_TOKEN'] = sys.argv[1]
json.dump(d, open(path, 'w'), indent=2)
print('Token saved.')
" "$1"
}
写入完成后向用户确认 "Token 已保存,下次操作自动使用。"
后续每次操作
重复 Step 0:先读配置确认 token → 有值则用,无值则再问。
Base URL: http://localhost:41184
Verify service:
curl -s http://localhost:41184/ping
# Expected: "JoplinClipperServer"
完整操作示例(含 token 确认)
# 1. 确认 token
TOKEN=$(python3 -c "import json; d=json.load(open('$HOME/.openclaw/openclaw.json')); print(d['skills']['entries']['joplin-api']['env'].get('JOPLIN_TOKEN', ''))")
# 2. 检查是否有值
if [ -z "$TOKEN" ]; then
echo "TOKEN_MISSING"
fi
# 3. 有 token 则调用 API
curl -s "http://localhost:41184/notes?token=$TOKEN&limit=5" | jq .
Workflow: Search for a Topic
The recommended workflow to find content about a topic:
Step 1: Find relevant notebooks (folders)
# Search folders by title (case-insensitive, supports * wildcard)
curl -s "$JOPLIN_BASE/search?query=r730&type=folder&token=$JOPLIN_TOKEN" | jq .
Step 2: List notes inside a notebook
# Get all notes in a specific folder
curl -s "$JOPLIN_BASE/folders/FOLDER_ID/notes?token=$JOPLIN_TOKEN&fields=id,title,updated_time&limit=50" | jq .
Step 3: Read note content
# Get note body (Markdown)
curl -s "$JOPLIN_BASE/notes/NOTE_ID?token=$JOPLIN_TOKEN&fields=id,title,body" | jq .
Alternative: Full-text search across all notes
# Search notes by keyword (full-text, returns id/title only for speed)
curl -s "$JOPLIN_BASE/search?query=r730+购买&token=$JOPLIN_TOKEN&fields=id,title" | jq .
# Then read the matching note
curl -s "$JOPLIN_BASE/notes/NOTE_ID?token=$JOPLIN_TOKEN&fields=body" | jq .
Tip: When searching with
bodyfield, response can be large. Search withid,titlefirst, then fetchbodyfor the specific note you want.
Folder Hierarchy Operations
List all folders (flat list with parent_id)
# Returns flat list; use parent_id to reconstruct tree
curl -s "$JOPLIN_BASE/folders?token=$JOPLIN_TOKEN&fields=id,title,parent_id" | jq .
Each folder has:
id— folder IDtitle— folder nameparent_id— parent folder ID (empty/null = top-level)deleted_time— 0 = active, >0 = soft-deleted
Reconstruct folder tree in code
# Get all folders and build tree structure
curl -s "$JOPLIN_BASE/folders?token=$JOPLIN_TOKEN&fields=id,title,parent_id" | python3 -c "
import sys, json
folders = json.load(sys.stdin)
if isinstance(folders, dict):
folders = folders.get('items', folders)
# Build lookup
by_id = {f['id']: f for f in folders if f.get('deleted_time', 0) == 0}
# Attach children
for f in by_id.values():
pid = f.get('parent_id', '')
if pid and pid in by_id:
by_id[pid].setdefault('children', []).append(f)
# Print tree (top-level only parents)
def show(items, indent=0):
for item in sorted(items, key=lambda x: x['title']):
print(' ' * indent + f'[{item[\"id\"][:8]}] {item[\"title\"]}')
show(item.get('children', []), indent + 1)
roots = [f for f in by_id.values() if not f.get('parent_id') or f['parent_id'] not in by_id]
show(roots)
"
Find folder ID by name
# Search for a notebook by title
curl -s "$JOPLIN_BASE/search?query=r730&type=folder&token=$JOPLIN_TOKEN&fields=id,title,parent_id" | jq .
Note Operations
List notes in a folder
curl -s "$JOPLIN_BASE/folders/FOLDER_ID/notes?token=$JOPLIN_TOKEN&limit=100&order_by=updated_time&order_dir=DESC&fields=id,title,updated_time" | jq .
Read note content
# Title + body only
curl -s "$JOPLIN_BASE/notes/NOTE_ID?token=$JOPLIN_TOKEN&fields=id,title,body" | jq .
# With metadata
curl -s "$JOPLIN_BASE/notes/NOTE_ID?token=$JOPLIN_TOKEN&fields=id,title,body,parent_id,created_time,updated_time" | jq .
Create note (POST /notes) — ⚠️ 高影响操作,需用户明确批准
在执行前向用户展示将要创建的笔记标题、内容和目标笔记本,获得确认后再执行:
# 预览后执行
curl -s -X POST "$JOPLIN_BASE/notes?token=$JOPLIN_TOKEN" \
--data '{"title":"Title","body":"Markdown content","parent_id":"FOLDER_ID"}' | jq .
Update note (PUT /notes/:id) — ⚠️ 高影响操作,需用户明确批准
在执行前向用户展示将要修改的笔记标题、当前内容摘要和拟修改内容,获得确认后再执行:
# 预览后执行
curl -s -X PUT "$JOPLIN_BASE/notes/NOTE_ID?token=$JOPLIN_TOKEN" \
--data '{"title":"New Title"}' | jq .
Delete note (DELETE /notes/:id) — ⚠️ 高影响操作,需用户明确批准
默认行为:移至回收站(软删除),用户可恢复。
除非用户明确请求永久删除,否则不使用 permanent=1。
# 移至回收站(默认,可恢复)
curl -s -X DELETE "$JOPLIN_BASE/notes/NOTE_ID?token=$JOPLIN_TOKEN" | jq .
执行前必须:
- 展示目标笔记的标题和 ID
- 说明操作后果(移至回收站 / 永久删除)
- 获得用户明确确认后再执行
Note tags & resources
# Tags on a note
curl -s "$JOPLIN_BASE/notes/NOTE_ID/tags?token=$JOPLIN_TOKEN" | jq .
# Resources (attachments) on a note
curl -s "$JOPLIN_BASE/notes/NOTE_ID/resources?token=$JOPLIN_TOKEN" | jq .
Tag Operations
# List all tags
curl -s "$JOPLIN_BASE/tags?token=$JOPLIN_TOKEN&fields=id,title" | jq .
# Search tags (supports * wildcard)
curl -s "$JOPLIN_BASE/search?query=project-*&type=tag&token=$JOPLIN_TOKEN" | jq .
# Notes with a specific tag
curl -s "$JOPLIN_BASE/tags/TAG_ID/notes?token=$JOPLIN_TOKEN" | jq .
Pagination
All list endpoints return { "items": [...], "has_more": true/false }.
# Page 2
curl -s "$JOPLIN_BASE/notes?token=$JOPLIN_TOKEN&limit=10&page=2" | jq .
Parameters: page (starts at 1), limit (max 100), order_by, order_dir (ASC/DESC).
Data Types
- Text: UTF-8
- Dates/times: Unix timestamps in milliseconds
- Booleans: Integer
0or1 deleted_time:0= active,>0= soft-deleted
Iron Rules(铁律)
- 每次操作前先确认 token — 从配置读取 → 有值则用 → 无值则问用户 → 用户给出后写入配置 → 下次再确认
- GET free — 读取笔记、笔记本、标签可自由执行,无需额外批准
- 写/删操作必须经过用户明确批准 — POST(创建)、PUT(更新)、DELETE(删除)均为高影响操作:
- 创建:展示标题、内容摘要、目标笔记本,确认后再执行
- 更新:展示笔记标题、当前内容摘要、拟修改内容,确认后再执行
- 删除:展示笔记标题和 ID,说明操作后果(移至回收站/永久删除),确认后再执行
- 默认软删除 — 删除笔记时默认移至回收站(可恢复);除非用户明确说"永久删除",否则不加
permanent=1 - Search without body first — 搜索时用
fields=id,title提速,找到目标后再获取body - Use parent_id for hierarchy — folders 和 notes 都通过
parent_id构建树形关系
See references/api-docs.md for the complete API reference (all endpoints, properties, error handling).
- 确保已安装 OpenClaw(本地或 Docker 部署)
- 在对话框中输入安装命令:
/install joplin-api-china - 安装完成后,直接呼叫该 Skill 的名称或使用
/joplin-api-china触发 - 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
Joplin API(中文) 是什么?
通过 Joplin 官方本地 Data API(Clipper Server,端口 41184)查询和管理笔记、笔记本、标签。本技能仅对原始 Joplin REST API 做了 AI 调用引导和中文交互封装,不引入第三方服务,所有请求直连本机 Joplin 实例。触发词:"查 Joplin... 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 138 次。
如何安装 Joplin API(中文)?
在 OpenClaw 或 Claude Code 对话框中运行命令「/install joplin-api-china」即可一键安装,无需额外配置。
Joplin API(中文) 是免费的吗?
是的,Joplin API(中文) 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。
Joplin API(中文) 支持哪些平台?
Joplin API(中文) 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。
谁开发了 Joplin API(中文)?
由 yangyangupday(@yangyangupday)开发并维护,当前版本 v1.1.0。