OpenClaw.NET 外部 CLI 连接器 (External CLI Connectors) 详细技术总结
基于文档: https://github.com/clawdotnet/openclaw.net/blob/main/docs/EXTERNAL_CLI_CONNECTORS.md基于代码 Commit: https://github.com/clawdotnet/openclaw.net/commit/bde72ea12f05457d0d36422d627ffbe383fce1d8整理日期: 2026-05-10
一、架构概述
External CLI Connectors 是 OpenClaw.NET 的一个受控原生工具 (external_cli),用于将官方平台 CLI(如 GitHub CLI、Azure CLI、kubectl、Stripe CLI、Lark/Feishu CLI 等)包装为可被 AI Agent 安全调用的工具。
核心设计哲学:
- 默认禁用
— 功能不会自动启用,需要显式配置 - 不是通用 Shell
— 不接受任意命令字符串,只允许预配置的具名命令 - 深度防御
— 通过命名命令白名单、风险评分、预览、审批、脱敏、超时、审计记录和运行时事件实现多层安全控制
二、安全模型 (Security Model)
2.1 核心安全原则
外部 CLI 可以在强大的用户、机器人、云、集群或支付身份下运行,因此:
-
所有变更性命令 (mutating commands) 被视为高风险 -
使用最小权限原则 (least privilege) -
支持 dry-run 预览、审批流程 和 审计日志
2.2 命令调用方式
连接器不接受原始命令字符串。Agent 通过指定连接器名、命令名和命名参数来调用:
{"action":"execute","connector":"gh","command":"issue_list","parameters":{"repo":"clawdotnet/openclaw.net"}}
运行时通过配置化的参数模板直接展开为 ProcessStartInfo.ArgumentList,不经过 Shell 解释器,且拒绝缺失或未知参数(除非命令显式允许)。
2.3 关键安全默认值
|
|
|
|
|---|---|---|
Enabled |
false |
|
AllowFreeformCommands |
false |
|
RequireApprovalForMutatingCommands |
true |
|
RiskLevel |
high |
|
ReadOnly |
false |
|
三、配置系统详解
3.1 顶层配置结构
{"OpenClaw":{"ExternalCli":{"Enabled":true,// 总开关"DefaultTimeoutSeconds":60,// 默认超时"MaxStdoutBytes":262144,// stdout 最大字节数 (256KB)"MaxStderrBytes":65536,// stderr 最大字节数 (64KB)"RedactSecrets":true,// 启用密钥脱敏"AllowFreeformCommands":false,// 禁止自由命令"RequireApprovalForMutatingCommands":true,// 变更命令需审批"Connectors":{// 连接器配置// 各平台CLI连接器定义}}}}
3.2 连接器配置结构
以 GitHub CLI (gh) 为例:
{"gh":{"Enabled":true,"DisplayName":"GitHub CLI","Executable":"gh","DefaultOutputFormat":"json","StatusCommand":{"Args":["auth","status"],"TimeoutSeconds":20},"VersionCommand":{"Args":["--version"],"TimeoutSeconds":10},"Commands":{"repo_view":{"Description":"View repository metadata","ArgsTemplate":["repo","view","{{repo}}","--json","name,owner,description,url,isPrivate"],"RiskLevel":"low","ReadOnly":true,"StructuredOutput":"json","Parameters":{"repo":{"Required":true,"Pattern":"^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$"}}},"issue_create":{"Description":"Create a GitHub issue","ArgsTemplate":["issue","create","--repo","{{repo}}","--title","{{title}}","--body","{{body}}"],"RiskLevel":"medium","ReadOnly":false,"RequiresApproval":true,"StructuredOutput":"text","Parameters":{"repo":{"Required":true},"title":{"Required":true,"MaxLength":200},"body":{"Required":true,"MaxLength":16000}}}}}}
3.3 命令配置选项说明
|
|
|
|
|---|---|---|
Description |
|
|
ArgsTemplate |
|
{{param}} 占位符将被替换 |
RiskLevel |
|
low / medium / high |
ReadOnly |
|
|
RequiresApproval |
|
|
StructuredOutput |
|
json / ndjson / csv / table / text |
DryRunArgsTemplate |
|
|
Parameters |
|
|
RedactionRules |
|
|
RequiredScopes |
|
|
RequiredIdentity |
|
|
TimeoutSeconds |
|
|
WorkingDirectory |
|
|
Environment |
|
|
3.4 参数验证选项
每个参数可配置:
Required
— 是否必填 Description
— 参数描述 MaxLength
— 最大长度限制 Pattern
— 正则表达式验证 AllowedValues
— 允许值列表
四、预览与审批流程 (Preview & Approval)
4.1 预览命令
openclaw external preview gh repo_view --paramrepo=clawdotnet/openclaw.net
4.2 预览返回信息
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4.3 执行审批流程
# 1. 先预览openclaw external preview gh issue_create \--paramrepo=clawdotnet/openclaw.net \--paramtitle="Example"\--parambody="Example body"# 2. 确认后加 --yes 执行(自动携带指纹)openclaw external execute gh issue_create \--paramrepo=clawdotnet/openclaw.net \--paramtitle="Example"\--parambody="Example body"\--yes
指纹安全机制: 如果命令模板、解析参数或策略在审批和执行之间发生变化,指纹不匹配将导致执行被阻止。
4.4 Dry-Run 支持
预览时加上 --dry-run 可执行 dry-run 模式(需命令配置了 DryRunArgsTemplate):
openclaw external preview gh issue_create \--paramrepo=clawdotnet/openclaw.net \--paramtitle="Test"\--parambody="Test body"\ --dry-run
注意: 运行时不会猜测 dry-run 标志,必须在模板中显式配置。
五、审计、事件与脱敏 (Audit, Events & Redaction)
5.1 审计记录 (Append-Only Audit)
每次执行写入不可篡改的审计记录,包含:
-
连接器名和命令名 -
可执行文件路径 -
已脱敏的命令行预览 -
参数和参数哈希 -
执行者、会话、频道、发送者 -
审批指纹(如有) -
退出码、执行时长、超时标志 -
stdout/stderr 截断标志 -
风险等级和工作目录
5.2 运行时事件
触发以下事件类型:
status_check
— 状态检查 previewed
/ dry_run_previewed— 预览dry_run_executed
— Dry-run 执行 command_executed
— 命令执行 command_failed
— 命令失败 command_timed_out
— 超时 truncation
— 输出截断 redaction
— 密钥脱敏 command_blocked_by_policy
— 策略阻止
5.3 密钥脱敏 (Redaction)
脱敏应用于:参数预览、stdout、stderr、审计记录、运行时事件、错误消息。可为连接器或命令配置 RedactionRules,支持平台特定的密钥格式。
六、输出解析 (Output Parsing)
按命令配置 StructuredOutput:
|
|
|
|---|---|
json |
|
ndjson |
|
csv
table / text |
|
注意: 连接器不会注入全局 --json 标志,需要在每个命令模板中显式放置输出标志。
七、推荐配置预设 (Conservative Presets)
7.1 GitHub CLI (gh)
|
|
|
|---|---|
|
|
auth status
repo view, issue list, pr list, pr view, release list |
|
|
issue create
issue comment, pr review, pr merge, release create |
7.2 Azure CLI (az)
|
|
|
|---|---|
|
|
account show
group list, resource list, webapp list |
|
|
resource create/update/delete
deployment create, role assignment changes |
7.3 kubectl
|
|
|
|---|---|
|
|
config current-context
get pods/services/deployments -o json, describe |
|
|
apply
delete, scale, rollout restart, exec, port-forward |
日志可能暴露密钥,建议至少 medium 风险等级。
7.4 Stripe CLI
|
|
|
|---|---|
|
|
listen status
fixtures/list, customers/list(最小权限凭证) |
|
|
payment mutations
refunds, customer/subscription mutations, webhook trigger, event replay |
7.5 Lark / Feishu CLI
|
|
|
|---|---|
|
|
auth status
calendar agenda, docs search/read, sheets read, mail search/read, meeting minutes query |
|
|
|
八、管理 API (Admin API)
网关暴露以下 RESTful 端点:
|
|
|
|
|---|---|---|
|
|
/admin/external-cli/connectors |
|
|
|
/admin/external-cli/connectors/{connector} |
|
|
|
/admin/external-cli/connectors/{connector}/commands |
|
|
|
/admin/external-cli/preview |
|
|
|
/admin/external-cli/execute |
|
九、CLI 命令
# 列出所有连接器openclaw external list# 查看连接器状态openclaw external status gh# 列出连接器命令openclaw external commands gh# 预览命令openclaw external preview gh repo_view --paramrepo=clawdotnet/openclaw.net# 执行命令openclaw external execute gh repo_view --paramrepo=clawdotnet/openclaw.net# 使用 --json 获取机器可读输出openclaw external list --json
十、代码实现架构 (Commit bde72ea)
10.1 项目结构
本次 Commit 共修改 29 个文件,+2,966 行代码,涉及以下模块:
docs/ EXTERNAL_CLI_CONNECTORS.md # 新增完整文档 (278行) README.md # 添加文档链接 SITE_MAP.md # 添加站点地图src/OpenClaw.Agent/ OpenClawToolExecutor.cs # 工具执行器集成 (+29/-4) Tools/ExternalCliTool.cs # 新增 External CLI 工具实现 (251行)src/OpenClaw.Client/ OpenClawHttpClient.cs # HTTP 客户端新增 Admin API 方法 (+51行)src/OpenClaw.Cli/ CliArgs.cs # CLI 参数解析扩展 ExternalCliCommands.cs # 新增 CLI 命令实现 (250行) OpenClawHttpClient.cs # CLI HTTP 客户端包装 (+15行) Program.cs # 注册 external 子命令 (+3行)src/OpenClaw.Core/ Abstractions/IToolActionDescriptorProvider.cs # 抽象接口 ExternalCli/ ExternalCliServices.cs # DI 服务注册 ExternalCliConnectorRegistry.cs # 连接器注册表 ExternalCliRunner.cs # 命令执行器 Models/ ExternalCliModels.cs # 数据模型 (284行) GatewayConfig.cs # 配置集成 (+1行) Session.cs # JSON 序列化 (+26行) ToolingPolicyModels.cs # 策略模型 (+4行) Pipeline/ToolActionPolicyResolver.cs # 策略解析 (+27/-1) Validation/ConfigValidator.cs # 配置验证 (+78行)src/OpenClaw.Gateway/ Composition/ # DI 组合注册 Endpoints/AdminEndpoints.ExternalCli.cs # Admin API 端点 (264行) Endpoints/ExternalCliStores.cs # 存储抽象OpenClaw.Tests/ ExternalCliTests.cs # 单元测试
10.2 核心类型与接口
// 连接器注册表publicinterfaceIExternalCliConnectorRegistry{ExternalCliPreparedInvocationBuildPreview(ExternalCliPreviewRequest request,bool dryRun);}// 命令执行器publicinterfaceIExternalCliRunner{Task<ExternalCliExecutionResult>ExecuteAsync(ExternalCliPreparedInvocation prepared,CancellationToken ct);}// 审计 SinkpublicinterfaceIExternalCliAuditSink{voidRecord(ExternalCliAuditEntry entry);}// 事件 SinkpublicinterfaceIExternalCliEventSink{voidRecord(ExternalCliRuntimeEvent evt);}
10.3 关键数据模型
// 连接器配置选项publicsealedclassExternalCliConnectorOptions{publicbool Enabled {get;set;}=false;publicstring DisplayName {get;set;}="";publicstring Executable {get;set;}="";publicstring DefaultOutputFormat {get;set;}="json";publicExternalCliStatusCommandOptions? StatusCommand {get;set;}publicExternalCliStatusCommandOptions? VersionCommand {get;set;}publicDictionary<string, ExternalCliCommandOptions> Commands {get;set;}=new();// ...}// 命令配置选项publicsealedclassExternalCliCommandOptions{publicstring Description {get;set;}="";publicstring[] ArgsTemplate {get;set;}=[];publicstring[]? DryRunArgsTemplate {get;set;}publicstring RiskLevel {get;set;}= ExternalCliRiskLevel.High;publicbool ReadOnly {get;set;}=false;publicbool RequiresApproval {get;set;}=false;publicstring StructuredOutput {get;set;}= ExternalCliOutputFormat.Text;publicDictionary<string, ExternalCliParameterOptions> Parameters {get;set;}=new();// ...}// 执行结果publicsealedclassExternalCliExecutionResult{publicExternalCliInvocationPreview Preview {get;init;}=new();publicint ExitCode {get;init;}publicdouble DurationMs {get;init;}publicbool TimedOut {get;init;}publicbool Failed {get;init;}publicbool StdoutTruncated {get;init;}publicbool StderrTruncated {get;init;}// ...}// 审计记录publicsealedclassExternalCliAuditEntry{publicstring Id {get;init;}="";publicDateTimeOffset TimestampUtc {get;init;}publicstring SessionId {get;init;}="";publicstring Connector {get;init;}="";publicstring Command {get;init;}="";publicstring RedactedArgsPreview {get;init;}="";publicstring? ApprovalFingerprint {get;init;}publicint ExitCode {get;init;}// ...}
10.4 执行流程
- Agent 调用
→ ExternalCliTool接收工具请求 - 策略解析
→ ToolActionPolicyResolver解析操作描述符(含 IsMutation、RequiresApproval、ApprovalFingerprint、RiskLevel、ReadOnly) - 预览构建
→ ExternalCliConnectorRegistry.BuildPreview()解析模板、验证参数、计算指纹 - 审批检查
→ 如需审批,比较指纹是否匹配 - 执行命令
→ ExternalCliRunner.ExecuteAsync()通过ProcessStartInfo.ArgumentList启动进程 - 输出解析
→ 按 StructuredOutput设置解析输出 - 记录审计
→ 写入 ExternalCliAuditEntry(不可篡改) - 发送事件
→ 通过 ExternalCliEventSink发送运行时事件
10.5 策略解析增强
ToolActionDescriptor 新增字段:
RequiresApproval
— 是否需要审批 ApprovalFingerprint
— 审批指纹 RiskLevel
— 风险等级 ReadOnly
— 是否只读
OpenClawToolExecutor 中的审批逻辑增强:
-
支持指纹匹配验证 -
如模板、参数或策略在审批后变更,指纹不匹配将阻止执行
十一、飞书 (Feishu/Lark) CLI 配置详细教程
11.1 理解架构
OpenClaw 通过外部 CLI 连接器调用 lark-cli(官方 npm 包 @larksuite/cli)来操作飞书。这需要:
-
在飞书开放平台创建自建应用并获取凭证 -
安装并配置 lark-cli -
完成用户授权(OAuth 2.0 设备授权流程) -
在 OpenClaw 中配置 External CLI 连接器
11.2 步骤一:创建飞书自建应用
1. 访问飞书开放平台
-
国内版: https://open.feishu.cn -
国际版 (Lark): https://open.larksuite.com
2. 创建应用
-
登录后点击右上角 「开发者后台」 -
点击 「创建应用」 → 选择 「企业自建应用」 -
填写应用名称(如「我的AI助手」)和描述 -
点击 「确认创建」
3. 开启机器人能力
-
左侧菜单 → 「应用能力」→「机器人」 -
点击 「开启」
4. 获取凭证
-
左侧菜单 → 「凭证与基础信息」 -
复制以下信息备用: - App ID
(格式如 cli_xxxxxxxxx) - App Secret
(点击「查看」显示完整内容,请妥善保管)
5. 开通权限左侧菜单 → 「权限管理」,搜索并开通以下权限:
|
|
|
|---|---|
docx:document:readonly |
|
docx:document:write |
|
drive:drive:readonly |
|
drive:folder:write |
|
im:message |
|
im:message.group_at_msg |
|
im:message:send_as_bot |
|
im:chat |
|
im:resource |
|
search:docs:read |
|
6. 发布应用
-
左侧菜单 → 「版本管理与发布」 - 「创建版本」
→ 填写版本说明 → 「提交」 -
等待审批(企业内部应用通常自动通过)
11.3 步骤二:安装与配置 lark-cli
1. 安装 lark-cli
# 全局安装npminstall-g @larksuite/cli# 验证安装lark-cli --version
2. 配置凭证(交互式)
lark-cli config init --new
按提示输入 App ID 和 App Secret。
3. 配置凭证(非交互式/自动化)
echo"你的App Secret"| lark-cli config init \ --app-id "你的AppID"\ --app-secret-stdin \--brand feishu
--brand feishu用于国内版飞书,国际版 Lark 使用--brand lark。
4. 验证配置
lark-cli doctor
应显示配置正确、凭证有效。
11.4 步骤三:用户授权 (OAuth 2.0 设备授权)
1. 发起授权请求
lark-cli auth login --no-wait --recommend--json
输出示例:
{"device_code":"ABC123XYZ","user_code":"ABCD1234","verification_url":"https://open.feishu.cn/open-apis/authen/v1/scan?qrcode=..."}
2. 完成授权复制 verification_url 到浏览器打开,使用飞书 App 扫码确认。
3. 完成登录扫码确认后执行:
lark-cli auth login --device-code "ABC123XYZ"
4. 补充搜索权限(如需文档搜索能力)
lark-cli auth login --no-wait --scope"search:docs:read"--json
重复扫码授权流程。
11.5 步骤四:验证 lark-cli 功能
# 搜索文档lark-cli docs +search --query"文档"--as user# 创建文档lark-cli docs +create --title"测试文档"--markdown"# 你好世界"# 查询日历lark-cli calendar +agenda --as user# 发送消息lark-cli message +send --to-user "user_open_id"--text"Hello from CLI"
11.6 步骤五:在 OpenClaw 中配置 Feishu External CLI 连接器
在 OpenClaw 配置文件中添加:
{"OpenClaw":{"ExternalCli":{"Enabled":true,"DefaultTimeoutSeconds":60,"MaxStdoutBytes":262144,"MaxStderrBytes":65536,"RedactSecrets":true,"AllowFreeformCommands":false,"RequireApprovalForMutatingCommands":true,"Connectors":{"lark":{"Enabled":true,"DisplayName":"Lark/Feishu CLI","Executable":"lark-cli","DefaultOutputFormat":"json","StatusCommand":{"Args":["auth","status"],"TimeoutSeconds":20},"VersionCommand":{"Args":["--version"],"TimeoutSeconds":10},"Commands":{"auth_status":{"Description":"Check lark-cli auth status","ArgsTemplate":["auth","status"],"RiskLevel":"low","ReadOnly":true,"StructuredOutput":"text","Parameters":{}},"docs_search":{"Description":"Search Feishu documents","ArgsTemplate":["docs","+search","--query","{{query}}","--as","user","--json"],"RiskLevel":"low","ReadOnly":true,"StructuredOutput":"json","Parameters":{"query":{"Required":true,"MaxLength":200}}},"docs_read":{"Description":"Read a Feishu document","ArgsTemplate":["docs","+get","{{doc_id}}","--as","user"],"RiskLevel":"low","ReadOnly":true,"StructuredOutput":"json","Parameters":{"doc_id":{"Required":true}}},"docs_create":{"Description":"Create a Feishu document","ArgsTemplate":["docs","+create","--title","{{title}}","--markdown","{{content}}"],"RiskLevel":"medium","ReadOnly":false,"RequiresApproval":true,"StructuredOutput":"json","Parameters":{"title":{"Required":true,"MaxLength":200},"content":{"Required":true,"MaxLength":50000}}},"calendar_agenda":{"Description":"Query calendar agenda","ArgsTemplate":["calendar","+agenda","--as","user"],"RiskLevel":"low","ReadOnly":true,"StructuredOutput":"json","Parameters":{}},"message_send":{"Description":"Send a Feishu message","ArgsTemplate":["message","+send","--to-user","{{to}}","--text","{{text}}"],"RiskLevel":"medium","ReadOnly":false,"RequiresApproval":true,"StructuredOutput":"text","Parameters":{"to":{"Required":true},"text":{"Required":true,"MaxLength":2000}}}}}}}}}
11.7 步骤六:验证 OpenClaw 集成
# 查看连接器状态openclaw external status lark# 列出可用命令openclaw external commands lark# 预览搜索文档命令openclaw external preview lark docs_search --paramquery="项目计划"# 执行搜索(如需要审批,先预览再加 --yes)openclaw external execute lark docs_search --paramquery="项目计划"--yes# 预览创建文档(变更命令,需要审批)openclaw external preview lark docs_create \--paramtitle="会议纪要 2026-05-10"\--paramcontent="# 会议纪要\n\n## 参与人\n- ..."# 审批后执行openclaw external execute lark docs_create \--paramtitle="会议纪要 2026-05-10"\--paramcontent="# 会议纪要\n\n## 参与人\n- ..."\--yes
11.8 懒人方式(让 AI 助手自动配置)
你也可以让 AI 助手自动完成大部分配置工作:
帮我配置飞书云文档能力。请按以下步骤做:1. 检查是否安装了 lark-cli,如果没有则执行: npm install -g @larksuite/cli2. 运行 lark-cli doctor 检查当前状态3. 如果显示缺少凭证配置,问我 App ID 和 App Secret4. 拿到凭证后完成配置: echo "AppSecret" | lark-cli config init --app-id "AppID" --app-secret-stdin --brand feishu5. 运行 lark-cli auth login --no-wait --recommend --json 把返回的 verification_url 发给我,告诉我扫码授权6. 我扫码确认后,用返回的 device_code 执行登录7. 如果缺少搜索权限,按上面的方式再走一遍授权流程补充 search:docs:read8. 全部完成后,用以下命令验证各项能力: - lark-cli docs +search --query "文档" --as user - lark-cli docs +create --title "测试文档" --markdown "# 你好" - lark-cli calendar +agenda --as user
十二、完整 lark-cli 能力一览
|
|
|
|---|---|
| docs |
|
| sheets |
|
| message |
|
| calendar |
|
|
|
|
| contact |
|
| wiki |
|
| meeting |
|
| drive |
|
| bitable |
|
| approval |
|
| okr |
|
十三、最佳实践与注意事项
13.1 安全最佳实践
- 最小权限原则
— 只开通实际需要的权限 - 审批变更操作
— 所有写入/变更命令应设置 RequiresApproval: true - 使用只读预设
— 初始配置只启用读操作,按需开启写操作 - 监控审计日志
— 定期检查 external_cli的审计记录 - 配置密钥脱敏
— 为涉及敏感凭证的命令添加 RedactionRules - 设置合理超时
— 根据命令特性设置 TimeoutSeconds
13.2 常见问题排查
|
|
|
|---|---|
|
|
lark-cli doctor 输出,确认凭证和授权状态 |
|
|
|
|
|
|
|
|
StructuredOutput 设置是否与 CLI 实际输出格式匹配 |
|
|
TimeoutSeconds 设置 |
十四、总结
OpenClaw.NET 的 External CLI Connectors 提供了一个安全、受控、可审计的框架,将各种官方平台 CLI 集成到 AI Agent 的工具调用体系中。通过命名命令白名单、参数模板、风险评分、预览-审批流程、密钥脱敏和审计日志等多重安全机制,实现了在保持平台深度的同时确保操作安全。
对于飞书/Feishu 集成,通过 lark-cli 外部 CLI 连接器,AI Agent 可以安全地读写飞书云文档、查询日历、发送消息等,所有变更操作都需要显式审批,确保企业数据安全。
夜雨聆风