skills/feishu-cli-auth/SKILL.md
飞书 OAuth 认证和 User Access Token 管理(Device Flow,RFC 8628)。 支持一键创建飞书应用、按域申请推荐权限、auth check 预检 scope、auth login 登录、Token 自动刷新。 覆盖 AI Agent 两步授权(--no-wait 拿链接 → --device-code 续轮询)、JSON 事件流解析、部分 scope 未授予(missing_scopes)的判读与补授。 当用户请求登录飞书、获取 Token、OAuth 授权、用户身份授权、device flow、权限缺失、Token 过期、create-app、99991672、99991679, 或其他飞书技能遇到 User Access Token 问题时使用。 本技能同时承载两个相关子命令:doctor 做配置/网络/代理体检(错误信息不指向 scope/token 时用), profile 管理多 App / 多账号独立配置(多租户切换)。 注意:profile 指 CLI 配置切换,与邮箱 mailbox profile(feishu-cli-mail)无关。
npx skillsauth add riba2534/feishu-cli feishu-cli-authInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
本项目默认使用 App Token。只有搜索、消息历史/互动、审批任务、会议/妙记、邮箱等用户身份场景需要 User Access Token。
# 1. 预检:缺什么 scope 一目了然(auth check 返回 missing 时先到开放平台开通)
feishu-cli auth check --scope "search:docs:read search:message"
# 2a. 按业务域登录,自动带该域推荐 scope
feishu-cli auth login --domain search --recommend
# 2b. 一次授全:对全部业务域申请推荐 scope(单独用 --recommend,不带 --domain)
feishu-cli auth login --recommend
# 2c. 精确控制:显式指定 scope(与 --domain/--recommend 互斥)
feishu-cli auth login --scope "search:docs:read search:message"
--recommend 三种用法:单独用 = 全部 20 个业务域的推荐 scope;配 --domain X = 仅该域推荐 scope;都不传且在交互终端下 = 弹出选择提示。非交互环境(无 tty)必须显式指定范围,否则报错。
💡
auth login是增量授权:多次登录申请的 scope 在飞书服务端累积,补授新 scope 不会丢掉之前已授的。(本地token.json虽被新 token 覆盖,但其scope是服务端返回的累积值。)
AI Agent 的 harness 通常只把最终回复发给用户、且单轮有 timeout,不适合在同一轮里阻塞等授权。用两步模式:第一步拿链接发给用户并结束本轮,用户授权后下一轮再续轮询。
# 第一步:只取 device_code + 授权链接,立即返回不轮询
feishu-cli auth login --recommend --no-wait --json
# → 输出一行 device_authorization 事件,把 verification_uri_complete 发给用户后结束本轮
# 第二步(用户回复已授权后):用 device_code 续上轮询
feishu-cli auth login --device-code <device_code> --json
要点:
--scope/--domain/--recommend(重传会报错)。若 harness 支持后台任务,也可一步阻塞 + 后台运行:
# run_in_background 跑:阻塞轮询最长约 10 分钟,stdout 逐行出 JSON 事件
feishu-cli auth login --recommend --json
阻塞模式务必 run_in_background,或把单命令 timeout 设到 ≥ 600s。
--json 模式按 JSONL 逐行输出事件,Agent 解析这两个即可:
device_authorization(第一步 / 阻塞模式开头):
{"event":"device_authorization","verification_uri_complete":"https://accounts.feishu.cn/oauth/v1/device/verify?flow_id=...&user_code=XXXX-XXXX","user_code":"XXXX-XXXX","device_code":"...","expires_in":600,"interval":5,"requested_scopes":["..."]}
→ 把 verification_uri_complete(已含 user_code,可直接点开)原样发给用户,不要做任何 URL 编码/改写。
authorization_complete(授权成功,token 已落盘):
{"event":"authorization_complete","expires_at":"...","scope":"...","refresh_token_present":true,"granted_scopes":["..."],"missing_scopes":["..."],"requested_scopes":["..."]}
→ 上述 6 个字段常驻(scope 即落盘 token.json 的累积 scope 值);refresh_expires_at(拿到 refresh token 时)、warnings/hints(refresh 缺失或 scope 未授予时)为条件字段,无对应情况时 key 不出现——解析勿假设必存。
收到 authorization_complete 即代表登录成功、token 已写入 token.json——但还要看这几个字段:
| 字段 | 含义 | 处理 |
|---|---|---|
| refresh_token_present: false | 没拿到 refresh token | 应用未开通 offline_access,开通后 auth logout && auth login |
| missing_scopes 非空 | 部分申请的 scope 未授予(warning,不是失败) | 这些 scope 没在开放平台开通;其余 granted_scopes 照常可用 |
| granted_scopes | 实际拿到的 scope | 以此为准,可 auth check 复核 |
补授权(增量):missing_scopes 非空时,先到飞书开放平台开通这些 scope,再照 CLI 的 hint 执行 auth login --scope "<缺失的>" 即可。多次 login 的 scope 在服务端累积,补授只需带缺失的那几个,不会丢掉之前已授的,无需重跑全量。
feishu-cli auth status
feishu-cli auth status -o json --verify
feishu-cli auth check --scope "REQ_SCOPES"
feishu-cli auth login --domain <domain> --recommend
feishu-cli auth logout
feishu-cli auth token --as user|bot|auto # v1.29+ 导出 token 给 curl/Python 用
feishu-cli config create-app --save
feishu-cli doctor --json
feishu-cli profile current
auth token 导出 Token 给外部工具用(v1.29+)让 curl / Python requests / 任何 HTTP 工具复用本 CLI 的 Token 全生命周期管理 (Device Flow 登录、2 小时自动刷新、多 profile),不再各自实现 OAuth 流程。
| --as | 输出 | 适用场景 |
|---|---|---|
| user | User Access Token(eyJhbGc...,自动刷新) | 真人身份调 API,含 auth login 授权过的 scope |
| bot | Tenant Access Token(t-g10...,2h 有效) | App 身份,调 tenant scope API |
| auto(默认) | 优先 user,没有再回退 bot | 兼容兜底 |
# 给 curl 用
TOKEN=$(feishu-cli auth token --as user)
curl -H "Authorization: Bearer $TOKEN" \
https://open.feishu.cn/open-apis/authen/v1/user_info
# 给 Python 用
TOKEN=$(feishu-cli auth token --as bot)
python3 -c "import requests; print(requests.get('https://open.feishu.cn/open-apis/im/v1/chats', headers={'Authorization': f'Bearer $TOKEN'}).json())"
想直接调任意 OpenAPI 而不写 curl?用
feishu-cli api <method> <path>(详见feishu-cli-schemaskill)。
auth check --scope "..." —— 执行业务前预检某组 scope 够不够。退出码 0=满足、非 0=缺失或未登录;stdout 出 JSON:
| 字段 | 说明 |
|---|---|
| ok | true 表示所有 required scope 都已授权 |
| granted / missing | 已有 / 缺失的 scope 列表 |
| error | 仅失败时出现:not_logged_in(没登录)/ token_expired(access + refresh 都失效) |
| suggestion | ok=false 时给出的修复命令(已拼好 auth login --scope) |
# 满足才往下执行业务命令
feishu-cli auth check --scope "search:docs:read" && feishu-cli search docs --query "..."
auth status -o json —— 看本地 token 现状(默认不连服务端,加 --verify 才在线核验)。JSON 字段按字母序输出,已登录时关键字段(按实际输出顺序):
| 字段 | 说明 |
|---|---|
| access_token | 脱敏后的 access token(前 6 + 末 6) |
| access_token_valid | access token 是否还在有效期内 |
| expires_at | access token 过期时间(RFC3339) |
| health | healthy / missing_refresh_token(没拿到 refresh,对应未开 offline_access)/ needs_relogin(refresh 也过期) |
| identity | user(User Token 可用)/ bot(仅剩 App Token 可用) |
| logged_in | 是否登录 |
| refresh_expires_at | refresh token 过期时间(有 refresh 时出现) |
| refresh_token_present | 是否拿到 refresh token |
| refresh_token_valid | refresh token 是否还在有效期内 |
| scope | 当前 token 已授权 scope 列表(空格分隔) |
| token_status | valid / needs_refresh(access 过期但 refresh 可用,下次调用自动刷新)/ expired |
| cached_user.open_id / .name | 当前登录的是谁——需要本人 open_id(发消息给自己、查自己任务)时从这里取(仅当本地有 user cache 时出现) |
| note | 健康度提示文案(如 missing_refresh_token / expired 场景出现) |
| verified / verify_error | 仅 --verify:在线调 user_info 核验 token 是否仍被服务端接受 |
未登录时返回 {"logged_in": false, "identity": "bot", "note": "..."}。
判断"任务能不能干"优先用
auth check(按 scope 精确判定);auth status看整体健康度和当前身份。下面「排错」表的状态值即来自这两个命令(auth check的error/auth status的health)。
CLI 把命令分成三类,对应 cmd/utils.go 里三个 helper:
resolveOptionalUserTokenWithFallback)登录后自动用 token.json 里的 User Token;未登录则回落 App Token(要求 Bot 在群/有相应权限)。
优先级链:--user-access-token → FEISHU_USER_ACCESS_TOKEN → ~/.feishu-cli/token.json(access 过期会自动刷新)→ config.yaml 的 user_access_token → App Token 兜底。
涉及命令:
msg history(container 路径)、msg list、msg get、msg mget、msg thread-messages、msg resource-downloadtask get、task list、task subtask list、task comment list、tasklist get/list/taskscalendar get/list/primary/agenda/freebusy/suggestion/room-find、calendar event get/list/search、calendar attendee listfile meta/stats/list/version list/version get、file download、doc blocks(读)、board image/nodes/export-code/lintsheet read/export/get/meta/list-sheets/find/replace/write/append/insert/delete/clear/import-md/dropdown/filter/filter-view/protect/style/merge/...,所有 sheet 子命令都走 fallback,登录后默认 User、未登录 Tenant 兜底wiki get/nodes/spaces/space-get/export/export-tree、wiki member listdrive pull/push/statususer readresolveOptionalUserToken)默认 App Token(Bot 身份),仅当显式传 --user-access-token 或 FEISHU_USER_ACCESS_TOKEN 时才切到 User Token,不会自动加载 token.json。
涉及命令:所有 add/create/update/delete/move/copy/import/upload/send/reply/forward/merge-forward 类、comment reply、doc content-update / table 写、msg delete(Bot 自撤回,传显式 User Token 给管理员撤回)等。
resolveRequiredUserToken / requireUserToken)强制 User Token,没登录直接报错。
| 命令 | 典型 scope |
|---|---|
| search docs / messages / apps | search:docs:read / search:message |
| msg pin/unpin/pins | im:message.pins |
| msg reaction add/remove/list | im:message.reactions |
| msg search-chats | im:chat:read |
| msg flag create/cancel/list | im:feed.flag:read/write |
| chat get/update/delete、chat member list/add/remove | im:chat:*、im:chat.members:* |
| approval task query/approve/reject/transfer + instance get/cancel/cc | approval:task / approval:instance:* |
| task my (my_tasks) | task:task:read |
| vc search/notes/recording、minutes * | vc:*、minutes:* 相关 scope |
| mail * | mail:user_mailbox:* |
| drive upload/download/export/import/move/add-comment/task-result/search | drive:drive、drive:file:*、search:docs:read |
| calendar rsvp | calendar:calendar.event:reply |
| markdown create/fetch/overwrite | docx:document |
chat create 和 chat link 不在此表:默认走 App Token,仅显式 --user-access-token 时切到 User 身份创建群/获取链接。
登录时 CLI 会自动注入 offline_access 和 auth:user.id:read。如果 refresh_token_present=false,通常是应用未开通 offline_access,需要开通后重新登录。
--domain 可重复或逗号分隔。可选域:approval attendance bitable calendar chat contact doc_access docs drive event im mail minutes search sheets slides task vc whiteboard wiki,或 all。
feishu-cli auth login --domain search --recommend # 单域
feishu-cli auth login --domain vc --domain minutes --recommend # 多域
feishu-cli auth login --recommend # 全部域(等价 --domain all --recommend)
--scope 与 --domain/--recommend 互斥;最终以 auth check --scope 结果为准。
| 现象 | 处理 |
|---|---|
| not_logged_in | 执行 auth login --scope "..." --json |
| token_expired 且 refresh 可用 | 业务命令会自动刷新;也可重新登录 |
| needs_relogin | refresh token 已过期,重新登录 |
| missing_refresh_token | 开通 offline_access 后 auth logout && auth login |
| 99991672 | access token 无效或过期,重新登录 |
| 99991679 | 应用未开通 scope,先在开放平台开通权限 |
用户报“feishu-cli 不工作”“突然连不上”“配置有问题”时,先用 doctor 缩小问题面:
feishu-cli doctor
feishu-cli doctor --json
feishu-cli doctor --offline
feishu-cli doctor --only user_token
feishu-cli doctor --only proxy
feishu-cli doctor --only user_token,endpoint_open # 多值,逗号分隔
doctor 共 6 项检查;--only 支持单个值或逗号分隔多个值(typo 会被本地校验拒收):
| 检查名 | 含义 |
|---|---|
| config_file | 配置文件存在性、字段完整性 |
| user_token | ~/.feishu-cli/token.json 是否存在 / 过期 / refresh 可用 |
| endpoint_open | open.feishu.cn 可达性 |
| endpoint_larksuite | open.larksuite.com 可达性(海外站) |
| proxy | HTTPS_PROXY / NO_PROXY 是否会拦截 OpenAPI 域名 |
| dependencies | 二进制依赖(如 jq、git)状态 |
每项状态为 pass / warn / fail / skip。整体退出码:全部 pass/skip 或仅 warn → 0;任一 fail → 1。
--json 输出 schema:
{
"ok": true,
"checks": [
{"name": "user_token", "status": "pass", "message": "...", "hint": "..."}
]
}
CI 用法:feishu-cli doctor --offline --json | jq -e '.ok == true'。
常见命中:proxy 检查发现 HTTPS_PROXY 拦截 → 把 .feishu.cn,.larkoffice.com,.larksuite.com 加入 NO_PROXY;HTTPS_PROXY 中的 userinfo(user:pass@host)会被 redact 后再上报,无需担心日志泄漏。
已经明确是 scope 缺失时,不需要 doctor,直接 auth check --scope "..."。
v1.27.1 新增:使用
--config <path>显式覆盖配置时,CLI 会在 stderr 打印 warning,提示 profile 系统被绕过(token.json自动加载等行为失效)。AI Agent 调试时若看到该 warning,意味着当前命令未走 profile 体系,token 解析仅依赖该--config文件中的字段。
用户需要在多个飞书租户、多个 App ID 或工作/个人账号之间切换时,用 profile 管理独立的 config.yaml 和 token.json:
feishu-cli profile add work --app-id cli_xxx --app-secret secret_xxx --use
feishu-cli profile list --json
feishu-cli profile current
feishu-cli profile use work
feishu-cli profile use - # toggle 到上一个 profile(previous-profile 指针)
feishu-cli profile rename old-name new-name
feishu-cli profile remove old-name
feishu-cli profile migrate --name work
解析优先级:
FEISHU_PROFILE=<name> 环境变量强制覆盖。~/.feishu-cli/active-profile 指针。profiles/ 下字典序第一个(可能不是预期的那个)。~/.feishu-cli/config.yaml 和 ~/.feishu-cli/token.json。踩坑(违反直觉、可能丢数据,逐条留意):
profile add 不会自动迁移旧配置;已有配置接入 profile 系统必须显式运行 profile migrate,避免静默改变当前环境。profile migrate 不可逆且不删旧文件:~/.feishu-cli/config.yaml / token.json 仍留在原位,需要时手动清理;不要把 migrate 当成"备份+迁移"用。profile use <name> 不会自动登录:切到一个新建的 profile 后,必须再 auth login 才有 User Token。sync.Mutex,不跨进程:并发 profile use / profile rename 在不同 shell 里同时跑会有 race。profile use - 在没有上一个 profile 时直接报错:CLI 不会自动回退到字典序首位;先 profile list 确认目标,再 profile use <name> 显式切换。profile 名校验规则 [A-Za-z0-9_-]{1,64}(禁止 . / .. / profiles / cache 等保留名),违反时 CLI 自身会报错。profile rename 会自动同步 active 与 previous 指针,不需要手动改文件。
auth logout 会清理当前 profile 的 token 和用户 profile 缓存。
auth check --scope,缺什么报什么。--no-wait --json 拿链接 → 用户授权后 --device-code --json 续轮询);能开后台任务时也可 --json 阻塞 + run_in_background。把 verification_uri_complete 原样发给用户,不改写 URL。authorization_complete 的 missing_scopes:非空只是 warning,开通后按需补授(增量授权,补缺失的几个即可,不会丢已授 scope)。user_access_token / device_code 写入文档、代码或日志。auth check;只有错误不明确("突然不工作"/网络异常)才用 doctor 缩小问题面,不要混用。tools
飞书多维表格(Bitable/Base)操作。底层使用 base/v3 新 API,支持视图完整配置写入、 记录 upsert、记录批量获取、记录附件上传下载、记录修改历史、角色 CRUD + 协作者增删、 多维表格本体重命名/高级权限开关、数据聚合查询、 仪表盘 + 仪表盘块 CRUD、表单 + 表单问题 CRUD、工作流 CRUD 等。 当用户请求"创建多维表格"、"操作数据表"、"添加记录"、"查询记录"、"管理字段"、 "多维表格"、"base"、"bitable"、"数据表"、"视图排序"、"视图过滤"、"视图分组"、 "角色"、"role"、"高级权限"、"advperm"、"数据聚合"、"data query"、 "仪表盘"、"dashboard"、"表单"、"form"、"工作流"、"workflow"、"记录附件"、 "复制多维表格"时使用。 支持 --as bot|user|auto 身份切换:默认 auto(User 优先、Tenant 兜底), --as bot 用 App Token 操作多维表格,无需 auth login、永不过期, 适合 cron / 无人值守 / 脚本自动抓取多维表格内容。 凡涉及"App Token 读写 bitable"、"不登录抓多维表格"、"cron 定时同步多维表格"、 "bitable 报需要 User Token / 91403 没权限"时也应使用本技能。
tools
在飞书云文档里画**会动的图 / 可交互图表 / 数据大屏**——妙笔BOX 是飞书文档里唯一能真实跑 CSS/JS 的载体 (iframe 沙箱)。能画:ECharts 全家桶(折线/柱/饼/雷达/散点/热力/桑基/漏斗/仪表/K线/箱线/平行坐标/旭日/treemap/ 力导向关系图/时序/甘特)、真实地图与经纬度飞线、echarts-gl 3D(map3D/3D柱/3D散点/3D曲面)、Three.js 真 3D 场景、 词云、水球、纯 CSS 动画、Canvas 粒子、SVG 矢量动画、KPI 滚动大屏。 当用户要"在飞书文档里画图/做动画/能动的图/可交互图表/数据大屏/Dashboard/折线图/柱状图/地图/飞线图/3D图/ 关系图/流程动画/ECharts/可视化",或要做**能调 AI / 读写多维表 / 持久化状态 / 拿用户身份的交互式文档小程序**, 或提到"妙笔BOX/HTML 小组件/让飞书文档里的图动起来/嵌入网页到飞书文档/window.magic"时, **必须用本技能**。注意:要"动"只能用妙笔BOX;画板(feishu-cli-board)的 SVG 节点会被服务端栅格化成静态图、不会动。
tools
飞书 OpenAPI 裸调。api GET/POST/PUT/DELETE/PATCH <path> 直接调用任意飞书 OpenAPI 接口, 覆盖 feishu-cli 尚未封装的接口(对齐 lark-cli 的 api 能力)。支持 --params(query)/--data(body JSON)/--data-file(从文件读 body)/ --as auto|user|bot 身份/--dry-run 预览/-o 二进制下载/--format/--jq。 当用户请求"调用 X API"、"裸调飞书接口"、"feishu-cli 没封装的接口怎么调"、"raw api"、 "用 api 命令发请求"、"下载飞书媒体/文件 binary"时使用。 不适用:仅查 schema 不调用(用 feishu-cli schema);已有专用命令的高频场景(用对应 feishu-cli <模块>)。
tools
飞书电子表格高级能力(筛选视图 + 筛选条件 + 下拉单元格 + 浮动图片 + 批量样式)。 filter-view CRUD 管理筛选视图,filter-view condition CRUD 写筛选条件(V3 API); dropdown set/get/update/delete 管理单元格下拉框(V2 dataValidation); image get/update/media-upload/write-image 操作浮动图片与单元格写图; batch-set-style 批量设置多范围单元格样式。 基础读写(read/write/style/add-rows/add-sheet)仍在 feishu-cli 主命令 sheet/bitable, 本 skill 专注高级能力。 当用户请求"筛选视图"、"筛选条件"、"加下拉框"、"数据验证"、"列下拉"、"浮动图片"、"插入图片"、"批量样式"时使用。