agentleFS
uvwtuvwt/agentdock-skills/skills/trilium/SKILL.md

trilium

Skill6 starsChanged 3 months agoApache-2.0View on GitHub

Search, read, create, update and organize notes in a Trilium Notes instance through the official ETAPI, including revisions, branches, attributes, attachments, calendar notes and explicitly confirmed destructive operations.

The file

Files
SKILL.md

Trilium Skill

通过 Trilium 官方 ETAPI 查询和管理个人知识库。Skill 只依赖 Python 标准库,不包含 Trilium 服务端,也不调用内部 /api/* 或任意自定义路径。

适用场景

使用本 Skill 处理:

  • 检查 Trilium 实例版本、连通性和 ETAPI 鉴权;
  • 使用 Trilium 搜索语法查询笔记;
  • 读取、创建、修改和删除笔记;
  • 读取、替换、追加或精确局部编辑笔记正文;
  • 查询最近变更和笔记版本,创建版本或恢复已删除笔记;
  • 查询子节点和子树,创建、克隆、移动和调整笔记树 Branch;
  • 查询、创建和修改 Label / Relation 属性;
  • 查询附件元数据并读取文本型附件内容;
  • 获取 Inbox、日记、周记、月记和年记;
  • 在明确确认后触发 Trilium 数据库备份。

不要使用本 Skill 处理用户密码登录、ETAPI Token 创建或吊销、内部 API、任意路径透传、批量删除、二进制上传、ZIP 导入导出或直接修改 Trilium 数据库。

环境变量

变量类型必填说明
TRILIUM_URLconfig是Trilium 实例根地址,例如 https://notes.example.com;也接受以 /etapi 结尾的地址
TRILIUM_ETAPI_TOKENsecret是在 Trilium Options → ETAPI 中创建的 Token
TRILIUM_INSECURE_TLSconfig否仅自签名证书调试时设为 1;会跳过 TLS 证书校验

Token 只从当前进程环境读取,不支持通过输入 JSON 传递。缺少环境变量时只返回变量名,不读取浏览器 Cookie、配置文件或宿主私有目录。

重要内容格式

ETAPI 返回和接收的是 Trilium 实际存储格式:

  • text 富文本笔记正文是 HTML,不是 Markdown;
  • code、search、mermaid 等文本型笔记通常是原始文本;
  • 图片、PDF 等二进制正文不会写入 JSON 输出,只返回 binary、content_type 和 size_bytes;
  • 不做 Markdown 与 HTML 转换,避免无损性和格式语义不明确;
  • append-note-content 对富文本笔记要求输入 HTML 片段,对其他文本笔记自动补一个换行;
  • edit-note-content 只支持非富文本笔记,每个 old_text 必须在当前正文中恰好出现一次。

替换正文前先读取笔记类型和当前正文。只修改标题时使用 update-note,不要重写正文。

执行方式

在 Skill 包根目录运行:

printf '%s' '{"skill_action":"status"}' | python3 run.py

输入必须是 JSON 对象,动作字段为 skill_action。输出始终为 JSON。除 status 可报告未配置状态外,其余动作均要求 URL 和 Token。

动作

笔记与正文

动作类型主要输入说明
status只读无检查配置并调用 /etapi/app-info
search-notes只读query,以及可选搜索参数使用 Trilium 搜索语法查询笔记
get-note只读note_id获取笔记元数据、Branch ID、属性等
get-note-content只读note_id获取笔记实际存储正文
create-note写入parent_note_id, title, type, content?在指定父笔记下创建笔记
update-note写入note_id 及需修改的字段修改标题、类型、MIME 或创建时间
set-note-content写入note_id, content替换完整正文;允许空字符串
append-note-content写入note_id, content读取并重新校验版本后追加正文
edit-note-content写入note_id, edits对非富文本正文执行唯一片段替换
delete-note删除note_id, confirm: true, confirm_title读取当前标题并精确匹配后软删除

edit-note-content 的 edits 是 1 至 50 个对象,按顺序执行:

{
  "old_text": "必须唯一出现的旧片段",
  "new_text": "替换后的片段"
}

search-notes 可选参数:

fast_search
include_archived_notes
ancestor_note_id
ancestor_depth
order_by
order_direction
limit
debug

创建笔记的可选字段:

mime
note_position
prefix
is_expanded
note_id
date_created
utc_date_created

版本与恢复

动作类型主要输入说明
note-history只读ancestor_note_id?查询最近变更,可限定子树
list-note-revisions只读note_id查询一个笔记的版本列表
get-revision只读revision_id获取版本元数据
get-revision-content只读revision_id获取版本正文
create-revision写入note_id, description?手动保存当前版本
undelete-note恢复写入note_id, confirm: true, confirm_note_idID 精确匹配后恢复软删除笔记

树结构与属性

动作类型主要输入说明
get-child-notes只读note_id, limit?返回直接子笔记、类型和各自子节点数量
get-subtree只读note_id, depth?, node_limit?递归读取子树,深度最多 5,每层最多 10 个节点
get-branch只读branch_id获取 Branch
create-branch写入note_id, parent_note_id把笔记放入另一个父节点;已有 Branch 时更新它
clone-note写入note_id, parent_note_id, prefix?为同一笔记新增一个父节点,内容保持同步
move-note高影响写入note_id, new_parent_note_id, confirm: true, confirm_title, branch_id?新建目标 Branch 后删除原 Branch并验证结果
update-branch写入branch_id 及修改字段修改位置、前缀或展开状态
delete-branch删除branch_id, confirm: true, confirm_branch_id删除 Branch;若是最后一个 Branch,还需 confirm_delete_note: true 和 confirm_title
refresh-note-ordering写入parent_note_id通知 Trilium 刷新该父节点排序
get-attributes只读note_id返回当前笔记自己拥有的非自动链接属性
get-attribute只读attribute_id获取 Label 或 Relation
create-attribute写入note_id, type, name, value?创建属性;未指定 attribute_id 时生成 12 位 ID
set-attribute写入note_id, type, name, value?同名属性存在时更新,否则创建;Relation 改目标时替换属性实体
update-attribute写入attribute_id, value?, position?修改属性值或位置;Relation 改目标时替换属性实体
delete-attribute删除attribute_id, confirm: true, confirm_attribute_id精确匹配 ID 后删除属性

create-branch 和 update-branch 的可选字段是 note_position、prefix、is_expanded。type 只接受 label 或 relation;Relation 的 value 必须是非空且真实存在的目标笔记 ID。

get-child-notes 默认最多返回 100 个直接子节点,可将 limit 调整到 500。get-subtree 默认深度为 2、总节点上限为 100,总节点上限最多设为 500,避免远程 ETAPI 产生失控请求量。

公开 ETAPI 的 Branch 创建接口不会调用 Trilium 内部的树环路校验。因此 create-branch、clone-note 和 move-note 会在写入前遍历源笔记子树,拒绝把笔记放到自身或后代下面;安全校验最多读取 5000 个节点,超限时拒绝写入。

move-note 在笔记只有一个父 Branch 时自动选择它;若笔记已经被克隆到多个父节点,必须显式提供 branch_id。ETAPI 没有原子移动端点,因此 Skill 始终先创建新 Branch,再删除旧 Branch;若删除结果不确定,会返回 move_incomplete 并保留新位置,不执行可能导致孤儿笔记的自动回滚。

ETAPI 不允许直接修改 Relation 的目标值。set-attribute 和 update-attribute 会先创建新 Relation,再删除旧 Relation并重新读取验证;若删除结果不确定,会返回 attribute_replace_incomplete 并保留两个实体,避免误删。

删除 Branch 可能改变笔记在树中的可见位置。若目标是笔记最后一个 Branch,Trilium 会连同笔记及其子树一起软删除,因此必须额外提供 confirm_delete_note: true 和当前 confirm_title。

附件、日历与备份

动作类型主要输入说明
list-note-attachments只读note_id列出笔记附件
get-attachment只读attachment_id获取附件元数据
get-attachment-content只读attachment_id只直接返回文本内容;二进制仅返回元数据
get-inbox-note只读/按需创建date获取指定 YYYY-MM-DD 的 Inbox 笔记
get-day-note只读/按需创建date获取日记
get-week-note只读week获取 YYYY-Www 周记
get-month-note只读/按需创建month获取 YYYY-MM 月记
get-year-note只读/按需创建year获取 YYYY 年记
create-backup高影响写入backup_name, confirm: true, confirm_backup_name触发数据库备份

Trilium 的特殊笔记接口可能在笔记不存在时自动创建对应节点,因此日历类动作虽按查询使用,也可能造成服务端数据变化。

安全约束

  • 服务地址只允许 http 或 https,禁止 URL 内嵌凭据、查询参数和片段。
  • 所有请求路径均由固定动作生成,不开放任意 endpoint。
  • Token 不通过输入参数、命令行或输出传递;服务端错误中出现 Token 时会被替换为 <redacted>。
  • 单次响应限制为 8 MiB,避免把大型附件直接装入模型上下文。
  • 追加和局部编辑在写回前重新读取 blobId 与 utcDateModified,检测到并发修改时拒绝覆盖。
  • 创建子笔记、创建或修改 Branch、属性写入和删除操作都会先读取目标,拒绝 protected 笔记;系统笔记不能移动、克隆或删除。
  • delete-note 必须先读取目标并要求当前标题精确匹配。
  • move-note 必须确认当前标题;多父节点笔记必须明确指定要移动的 Branch,并在写入前检查树环路。
  • delete-branch、delete-attribute 和 undelete-note 必须额外匹配目标 ID;删除最后一个 Branch 还需确认会删除整棵子树。
  • create-attribute、set-attribute 和 update-attribute 拒绝 Trilium 官方标记为危险的执行、Widget、共享脚本等属性。
  • create-backup 必须匹配备份名,备份名仅允许字母、数字、点、下划线和连字符。
  • 写操作后根据返回值或重新读取目标验证最终状态;失败时保留 HTTP 状态、固定 endpoint 和脱敏响应。
  • Protected 内容仍以 Trilium ETAPI 为最终权限边界;Skill 对高影响写入额外提前拒绝,不尝试会话解锁或其他绕过。

推荐操作流程

  1. 首次使用先执行 status,确认实例、Token 和版本。
  2. 搜索后使用 get-note 确认真实 note_id、标题、类型和父子关系。
  3. 改正文前先执行 get-note-content;富文本必须按 HTML 处理,小改动优先使用 append-note-content 或 edit-note-content。
  4. 移动被克隆的笔记前先读取 parentBranchIds,明确要移动的是哪个树位置。
  5. 删除、移动、恢复和备份前向用户复述目标,并只在确认信息完全匹配时执行。
  6. 写入完成后读取目标或相关父节点验证,不用成功提示代替真实状态。

与官方内置 MCP 的关系

本 Skill 已覆盖官方 MCP 中可通过公开 ETAPI 稳定复刻的核心模型操作,包括正文追加与局部编辑、属性 upsert、子节点、子树、移动和克隆。仍不实现 search_icons 和 Trilium 内部 load_skill:这两项没有公开 ETAPI,不能通过内部 API 或硬编码数据伪造。

接口依据和字段映射见 references/etapi.md。

AgentDock 适配

在 AgentDock 中,把 URL 和 Token 配置到该 Skill 的独立环境,再通过绑定当前激活 Skill 的命令执行能力运行 python3 run.py。不要手工拼接已安装版本目录,也不要把真实 Token 写入 Skill 包、源码仓库或 Recall。

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.