插件 Quickstart
先用 liyan plugin init 创建一个独立插件,构建打包,在 Desktop 导入、授权,再让 AI 调用 plugin.ping。整个流程不需要提交 PR、合入 LiyanLabs、注册官方目录或运行官方发布 CI;把匹配设备平台的包交给用户本地导入即可。
需要业务工具时,可以继续复制飞书参考项目并增加只读工具 team.botInfo;需要 Capsule 界面时,参考本页的科学数据插件。项目有独立 go.mod,插件身份、工具和实现都在自己的项目中修改,无需重新编译宿主。
飞书示例沿用现有的设备本地配置和消息适配。新平台的 Channel、新 Agent Runtime 仍需宿主扩展,见能力类型。
准备环境
需要包含本页能力的 LiyanLabs Desktop / Runner 和 Go 1.25 或更新版本。最小模板不需要飞书账号或其他业务凭据。复制飞书参考项目另需 Git、该项目指定的 Go 工具链,以及运行资源编辑脚本的 Python 3。宿主 CLI 和 Runner 使用 Rust;Go 是模板和参考插件的实现语言。
本地工具 provider 没有实现语言白名单,Rust、Go、Python、Node.js 都可以实现同一契约。不过,只有 stdio 通信还不够:程序必须读取私有 bootstrap,完成约定的 stdio MCP 初始化、工具发现和调用,并与清单中的工具目录一致;配置注册入口另有注册协议。stdout 只输出协议帧。
入口必须指向包内可在目标设备直接启动的程序,Runner 不通过 shell 启动,也不查找用户 PATH 中的解释器。当前 pack 收集声明的程序和资源,不会自动收集任意脚本、解释器或 pip/npm 依赖。Python / Node.js 作者需要交付包含所需运行时与依赖的可执行产物;普通的 python main.py 或 node index.js 项目尚无即装即用的打包支持。Go 示例不意味着其他语言已经有官方模板或完成了各平台运行验收。
只有复制飞书或从源码构建 CLI 时才需要取得仓库;使用 Desktop 内置 CLI 创建最小插件可以跳过:
已有 checkout 时,在仓库根目录运行 git submodule update --init --recursive。源码构建 CLI 会用到这些子模块。下文插件开发命令使用 Bash:macOS / Linux 使用终端,Windows 可使用 Git Bash;标为 PowerShell 的命令在 PowerShell 中运行。获取 CLI 与后续操作使用同一个终端,保留 plugin_cli 变量。
获取并运行 CLI
CLI 的命令名是 liyan,Windows 程序名是 liyan.exe;它同时是 Desktop 使用的 Rust Runner。安装 Desktop 不会自动把 CLI 加入终端 PATH。选择下面一种方式取得程序,然后检查帮助。
使用 Desktop 内置程序
使用包含 plugin 子命令的匹配版本 Desktop。macOS 默认安装位置:
Beta 和 RC 分别将应用目录换成 LiyanLabs Beta.app、LiyanLabs RC.app;安装在其他目录时使用实际路径。Linux deb 的 Stable 默认路径为 /opt/LiyanLabs/resources/liyan;其他渠道使用各自安装目录下的 resources/liyan。AppImage 需先用其 --appimage-extract 选项解包,再使用解包目录 squashfs-root/resources/liyan。
Windows 在 Desktop 快捷方式上选择“打开文件所在的位置”,取得安装目录,然后在 PowerShell 输入该目录:
Windows Git Bash 使用同一文件的 POSIX 路径,例如 plugin_cli="/c/实际安装目录/resources/liyan.exe",随后用 "$plugin_cli" 调用。
从源码构建
如果内置程序尚未包含这些命令,可以从当前源码构建。需要 Rust stable 和本机 C/C++ 构建工具链;Windows MSVC target 需要 Visual Studio C++ Build Tools,macOS 需要 Command Line Tools,Linux 需要 C 编译器和链接器。在前面取得的仓库根目录执行:
Windows PowerShell 使用:
上述路径对应默认本机 target;如果显式设置了 Cargo build target,程序在 runner/target/<target>/debug/。Cargo 包名仍是 liyanlabs-cli,产出的可执行文件名是 liyan。
确认可用与设置 PATH
plugin --help 应列出 init、validate、pack、doctor。找不到文件时检查路径;提示不认识 plugin 时使用包含该能力的 Desktop / Runner,或从源码构建。版本号本身不能代替子命令检查。
本页的智能体模板还要求 init 生成 skills/local-tools-setup/SKILL.md 和 skills/local-tools-usage/SKILL.md。如果你的 CLI 只有旧模板,更新匹配的 Desktop / Runner,或按上面的源码构建方式取得当前 CLI。不要把旧发行的能力当作本页所在源码提交的能力。
本教程使用 "$plugin_cli" 的完整路径,无需安装全局命令。如需直接运行 liyan,可仅在当前 Bash 终端加入程序所在目录:
PowerShell 对应:
init / validate / pack 不需要启动 Desktop、登录或连接设备;doctor 和聊天实际调用需要在线且已认证的匹配 Desktop / Runner。Desktop 管理自己的连接,插件开发无需额外启动 daemon 或手动执行 connect。
创建第一个本地插件
在上一步设置了 plugin_cli 的终端中创建项目。下面分别以 Windows x64 和 Apple Silicon Mac 为例;程序与 pack 目标必须匹配实际运行设备,其他目标见构建与打包。
Windows PowerShell:
macOS Bash:
模板生成 plugin.json、configuration.json、tools.json、图标、独立 Go 程序、项目 README,以及声明了 setup / usage 用途的两份 skills/*/SKILL.md。setup Skill 使安装后的“让 AI 帮我初始化”可用,usage Skill 说明如何调用工具。plugin.ping 已实现并返回 pong;配置没有凭据字段。init 不编译程序,未构建时验证会因入口文件缺失而失败。
打包前编辑 plugin.json:将 name 改成自己的稳定标识(例如 com.example.my-tools),设置 author.name 和 extensions["com.liyanlabs"].displayName。保留宿主扩展命名空间 com.liyanlabs。模板的 provider 标签 example 不需要在宿主注册。首次版本可保留 1.0.0。
智能体可直接编辑 JSON 文件。Windows PowerShell 也可以准确写入 UTF-8 无 BOM:
选择其他自己的标识时,后续聊天指令也使用同一个标识。不要改 localProviders[].provider 来代替插件身份;不同安装的相同 provider 标签会由宿主隔离。
Windows PowerShell:
Apple Silicon Mac:
输出目录必须尚不存在。validate 的结果应为 status: "valid",pack 应为 status: "packed"。交付文件是 release-1.0.0/package.tar.gz,其中已经包含程序、声明和资源。
- 在安装设备上启动并登录 Desktop,打开插件 → 导入本地插件,选择该压缩包;也可以直接选择已经构建好的项目目录。
- 检查名称、版本和设备,完成安装确认,审查本地执行及工具读取权限,并启用插件。
- 打开“待初始化”,选择 AI 帮助或手动配置,创建并保存真实设备配置;最小模板没有业务凭据,不需要飞书扫码或入站消息绑定。空配置仍需保存,不能跳过。
- 在使用该设备的聊天中发送:
调用 com.example.my-tools 的 plugin.ping,报告工具实际返回的内容。使用你填写的实际插件标识。 - 检查工具调用记录和返回的
pong。验证通过、列表中出现插件或 AI 自行回答pong都不能替代真实调用证据。
有这次真实调用结果后,最小本地开发流程即完成。修改工具时同时更新 tools.json 和程序实现;修改已导入版本的内容时提高版本、重新构建打包并导入,更新后重新启用。详细更新和诊断步骤见本页后续章节。
扩展自己的业务工具
先确认模板的 plugin.ping 可以真实调用,再实现业务需求。普通工具作者只需要这个独立项目,不需要运行 LiyanLabs 服务栈、修改数据库或申请官方签名凭据。
例如增加只读 local.echo,可在完整工具列表中添加:
这只是完整 tools.json 的一个工具元素,不是整个文件。保留顶层 schema: "liyanlabs.plugin-tools/1" 和 tools 数组;在程序中解析 arguments.text,验证参数,再返回 content: [{"type":"text","text":"用户传入的内容"}] 和 isError: false。模板用 go:embed 嵌入工具和配置资源,所以每次修改这些文件后都必须重新构建程序。
模板已实现私有 bootstrap、MCP 初始化、工具发现和调用循环。增加业务处理时保留这条链路。改用 Rust、Python 或 Node.js 时,也必须完整实现该契约,并交付能被 Runner 直接启动的产物;语言不限不意味着任意 stdin/stdout 程序或一个裸脚本都能工作。详细协议见工具协议与运行产物。
首次使用的完整验收
手动路径是“待初始化 → 手动配置 → 批准所请求的访问 → 连接 → 打开安全凭据窗口 → 在原生窗口保存 → 检查配置”。空配置窗口没有凭据字段,也需要保存。用户可以拒绝权限;智能体应报告未授权状态,不得绕过。普通本地工具不需要选择接收入站消息的 Agent。
AI 路径由包内 setup Skill 引导:读取当前状态、提问收集权限选择、准备原生配置、等待真实完成,再检查和调用。智能体不能在聊天中索取业务凭据,也不能把“连接请求已创建”当成“配置已完成”。如果执行开发的智能体没有 Desktop 操作能力,应交付压缩包的完整绝对路径,并明确提示用户完成上述原生导入/确认步骤;继续读取实际状态验证,不把打包完成报告为全流程完成。
卡点与恢复
失败时记录阶段、命令或操作、退出码/安全错误、插件版本与 target;不要输出凭据、bootstrap、设备签名 token。doctor 只观察已发生的会话;discoveryVerified: false 不能单独证明包坏了。业务结果始终以真实调用为准。
复制飞书项目
在源码仓库根目录执行,项目放在仓库外:
参考目录包含:
名称与图标
编辑 plugin.json 中的以下字段,并设置自己的作者和版本。它们分别决定插件身份、用户看到的名称和图标:
com.liyanlabs 是宿主扩展命名空间,保持不变。保留 provider 标签 feishu 和现有 Channel 声明;不同安装可使用同一标签,配置和进程按完整安装身份隔离。同一个包内的 provider 标签必须唯一。
参考项目已带飞书图标。替换 assets/icon.png 即可使用自己的图片;PNG、JPEG、WebP 均可,单张最多 256 KiB,宽高各为 1–1024 像素。声明使用小写扩展名 .png、.jpg、.jpeg 或 .webp 的包内相对路径,不能是链接、远程 URL 或绝对路径。图标属于公开展示元数据,程序和凭据仍只存设备。名称和图标修改后提高版本、重新打包,列表、详情与设置导航会使用新版本的展示信息。
显示名称和图标都可省略:缺少名称时显示标识,缺少图标时使用通用图标。下面的脚本会写入本教程的名称和图标声明。
增加一个工具
这次复制已有的机器人信息查询,增加一个名字不同、描述清楚的只读工具。它会查询当前应用的机器人,不读取个人飞书账户,也不发送消息:
真实业务扩展还可以修改 Go 实现。readOnly 必须如实描述效果;写操作需要宿主审批。不要只改生成的 tools.json:运行时发现的名字、输入 schema 和只读分类必须与声明逐项一致,不一致时整份目录会被拒绝。
构建与打包
下面以 Apple Silicon Mac 为例:
验证输出包含 status: "valid"、pluginKey: "com.liyanlabs.team-feishu"、目标平台和包摘要;打包输出包含 status: "packed"、archive 大小与摘要。摘要随内容变化,不能照抄一个固定值。
pack 创建 package-manifest.json 和 package.tar.gz。作者清单仍叫 plugin.json;生成的运行清单使用 liyanlabs.plugin-package/2,记录文件用途、大小、摘要和入口。输出目录必须尚不存在,并放在项目目录外;不要把上次 archive 再装进新包。验证不会执行插件代码。
构建目标必须匹配实际 Runner。Windows 将两个清单里的 provider 和 registration 入口都改成 bin/liyanlabs-plugin-feishu.exe,构建对应 .exe。使用 PowerShell 时把导出结果保存为 UTF-8 无 BOM;旧 PowerShell 的 > 可能生成 UTF-16。跨平台编译成功不等于已完成对应平台客户端验收。
飞书示例保留可运行的业务实现和配置流程;不需要飞书业务时,使用前面的最小本地插件即可。
安装和配置
- 在 Desktop 的插件页点击“导入本地插件”,选择项目目录或生成的
package.tar.gz。名称和版本从plugin.json自动读取,不需要手动输入标识。完成后在目录中查看该插件。 - 核对插件身份、版本和运行设备,完成安装和包启用确认。程序与 Skill 留在该 Runner;服务端接收声明、摘要、公开图标和安装元数据。
- 审核本地程序执行权限及业务读取权限。第三方包通过格式校验不会自动获得执行许可。
- 打开配置,创建命名 profile。扫码注册在 Desktop 原生窗口完成;已有飞书应用可输入区域、App ID、App Secret。不要把凭据发给 AI 或写入项目。
- 需要接收消息时,单独开启入站同意并选择 Agent。只查询机器人信息无需开启入站消息。
包启用、配置完成和连接健康是三个状态。配置窗口由 configuration.json 驱动;注册程序只能输出约定的验证链接和配置结果,凭据保存在设备私有安全存储。安装页的 AI 帮助会使用包内 setup Skill,但不会替用户授予权限。
调用与诊断
在使用该设备的聊天中,让 AI 完成一个明确的只读任务:
模型看到的工具名可能带宿主生成的安装前缀;Runner 给插件的原始工具名仍为 team.botInfo。成功证据是工具调用和实际返回的机器人信息,不能用静态校验或 setup 完成代替。
doctor 是可选诊断,不是创建、安装或使用的前置条件。已取得安装操作/API 的 installation UUID 时在当前通道运行;不要把插件标识、release UUID 或设备 UUID 传给 --installation。没有 UUID 时先通过配置面板和真实聊天调用验收,不必为运行 doctor 阻塞使用:
Dev Desktop 的 channel home 独立,开发时指定:
Doctor 通过当前通道私有诊断能力连接已认证的 Runner,输出设备、包确认与完整性,以及已经观察到的 provider 会话、配置和工具发现状态。它不读取凭据、不启动插件、不请求飞书 API。configurationObserved: false 或 discoveryVerified: false 可能表示尚未调用或会话正在执行,不能单凭它断言缺少配置;它也不是业务健康探测。没有当前 Desktop 连接时返回 plugin_diagnostics_unavailable,不会报告虚假的成功。
目录漂移、配置失败或离线恢复参见开发与排障。
更新和卸载
修改内容后提高 version,重新构建程序、导出工具目录、验证并打包,再在原设备导入新版本。已发布的同身份同版本内容不能覆写。更新或修复后重新启用;配置绑定 release 与配置 schema,按新版本要求重新配置。不要通过改摘要、数据库状态或旧凭据绑定绕过确认。
卸载通过插件页完成。旧进程和请求会被撤销,另一安装的同标签 provider 继续保持自己的生命周期。设备离线时能力不可用;不自动换机或转到服务端执行。该阶段没有公共第三方下载市场,分发方式是将匹配平台的本地包交给用户导入。
Capsule 客户端界面
需要界面时参考仓库的 plugins/science-data/:独立 provider 提供 PubChem、ChEBI、ChEMBL 查询,client/web 与 client/native 分别实现 React 和 React Native Capsule。它通过当前安装的模块图加载,导出 apply(ctx, config),在 ctx.effect 中拥有样式、资源订阅和清理。
在 extensions["com.liyanlabs"].clientModules 中声明 id、platform、包内 entry、files 和 inject。Web 与原生入口分别构建为注册 factory 的 JavaScript;React 和 @liyanlabs/plugin-ui 由当前平台提供,必须声明依赖,不能打包第二份 React。先构建程序与客户端文件,再用同一个 liyan plugin validate / pack 验证并打包。具体构建命令见 plugins/science-data/README.md。
科学数据也可以复制到仓库外,改成自己的插件并本地导入。它的 UI 和 provider 是一个包;不用加入官方 catalog,也不用运行 update-science-data-catalog.mjs。下面以 Windows x64 为例,在仓库根目录且已经设置 $plugin_cli 时运行:
客户端构建需要 Node.js 和精确版本的 esbuild 0.27.4。上面的 frontend 必须已有依赖安装;第三方可以把 esbuild 单独装在自己的工具目录,无需安装宿主前端:npm install --prefix <工具目录> --save-exact --no-audit --no-fund esbuild@0.27.4,然后把 SCIENCE_DATA_ESBUILD_ROOT 设为该目录的绝对路径。Bash 对应 export SCIENCE_DATA_ESBUILD_ROOT="/absolute/tool-directory",程序入口和 pack target 按实际设备调整。类型导入会被构建移除;运行时依赖来自声明的平台注入,不能私自把宿主 React 再打包进去。
完成导入、安装、空配置和权限确认后,从工作台菜单打开 Science data Capsule,选中该安装的连接,查询 PubChem 的 aspirin。验收应看到真实分子记录及 Runner 返回的结构图;界面能打开不证明查询或图像链路成功。原生模块同包提供,但桌面验收不代表已完成手机/平板客户端验收。
UI 代码直接运行在客户端的 JavaScript 环境中,安装前需要信任作者。ctx.resources 提供按地址共享、末位释放时取消的资源;ctx.connections.list 只返回公开连接状态;ctx.tools.call 仅调用当前获准的只读工具,并通过选定在线 Runner 执行。界面不获得操作凭据或服务端执行权限。更新、禁用、卸载、权限撤销或设备离线会撤回旧模块。
交给 AI 开发
下面的提示可和本页一起交给开发智能体。先完成最小本地闭环,再添加用户业务;不需要先提交仓库 PR。
飞书业务扩展示例: