
基于文档: 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 安全调用的工具。
核心设计哲学:
外部 CLI 可以在强大的用户、机器人、云、集群或支付身份下运行,因此:
连接器不接受原始命令字符串。Agent 通过指定连接器名、命令名和命名参数来调用:
{
"action": "execute",
"connector": "gh",
"command": "issue_list",
"parameters": {
"repo": "clawdotnet/openclaw.net"
}
}运行时通过配置化的参数模板直接展开为 ProcessStartInfo.ArgumentList,不经过 Shell 解释器,且拒绝缺失或未知参数(除非命令显式允许)。
配置项 | 默认值 | 含义 |
|---|---|---|
Enabled | false | 默认不注册工具 |
AllowFreeformCommands | false | 拒绝自由形式命令 |
RequireApprovalForMutatingCommands | true | 非只读命令需要审批 |
RiskLevel | high | 默认高风险,总是需要审批 |
ReadOnly | false | 默认可变操作 |
{
"OpenClaw": {
"ExternalCli": {
"Enabled": true, // 总开关
"DefaultTimeoutSeconds": 60, // 默认超时
"MaxStdoutBytes": 262144, // stdout 最大字节数 (256KB)
"MaxStderrBytes": 65536, // stderr 最大字节数 (64KB)
"RedactSecrets": true, // 启用密钥脱敏
"AllowFreeformCommands": false, // 禁止自由命令
"RequireApprovalForMutatingCommands": true, // 变更命令需审批
"Connectors": { // 连接器配置
// 各平台CLI连接器定义
}
}
}
}以 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 }
}
}
}
}
}字段 | 类型 | 说明 |
|---|---|---|
Description | string | 命令描述 |
ArgsTemplate | string[] | 参数模板,{{param}} 占位符将被替换 |
RiskLevel | string | 风险等级: low / medium / high |
ReadOnly | bool | 是否为只读操作 |
RequiresApproval | bool | 是否需要审批(覆盖默认策略) |
StructuredOutput | string | 输出格式: json / ndjson / csv / table / text |
DryRunArgsTemplate | string[] | (可选) Dry-run 模式的参数模板 |
Parameters | dict | 参数定义,含 Required/MaxLength/Pattern/AllowedValues |
RedactionRules | string[] | (可选) 平台特定的密钥脱敏规则 |
RequiredScopes | string[] | (可选) 所需身份/权限范围 |
RequiredIdentity | string | (可选) 所需身份标识 |
TimeoutSeconds | int | (可选) 命令级别超时覆盖 |
WorkingDirectory | string | (可选) 工作目录 |
Environment | dict | (可选) 环境变量 |
每个参数可配置:
Required — 是否必填Description — 参数描述MaxLength — 最大长度限制Pattern — 正则表达式验证AllowedValues — 允许值列表openclaw external preview gh repo_view --param repo=clawdotnet/openclaw.net字段 | 说明 |
|---|---|
可执行文件路径 | 解析后的 CLI 路径 |
参数列表 | 展开的参数(已脱敏) |
风险等级 | low / medium / high |
操作类型 | 只读 (ReadOnly) 或变更 (Mutating) |
是否需要审批 | true / false |
输出格式 | json / ndjson / csv / table / text |
所需身份/权限范围 | 如配置了 RequiredScopes |
审批指纹 (Approval Fingerprint) | 稳定的指纹值,用于审批匹配 |
# 1. 先预览
openclaw external preview gh issue_create \
--param repo=clawdotnet/openclaw.net \
--param title="Example" \
--param body="Example body"
# 2. 确认后加 --yes 执行(自动携带指纹)
openclaw external execute gh issue_create \
--param repo=clawdotnet/openclaw.net \
--param title="Example" \
--param body="Example body" \
--yes指纹安全机制: 如果命令模板、解析参数或策略在审批和执行之间发生变化,指纹不匹配将导致执行被阻止。
预览时加上 --dry-run 可执行 dry-run 模式(需命令配置了 DryRunArgsTemplate):
openclaw external preview gh issue_create \
--param repo=clawdotnet/openclaw.net \
--param title="Test" \
--param body="Test body" \
--dry-run注意: 运行时不会猜测 dry-run 标志,必须在模板中显式配置。
每次执行写入不可篡改的审计记录,包含:
触发以下事件类型:
status_check — 状态检查previewed / dry_run_previewed — 预览dry_run_executed — Dry-run 执行command_executed — 命令执行command_failed — 命令失败command_timed_out — 超时truncation — 输出截断redaction — 密钥脱敏command_blocked_by_policy — 策略阻止脱敏应用于:参数预览、stdout、stderr、审计记录、运行时事件、错误消息。可为连接器或命令配置 RedactionRules,支持平台特定的密钥格式。
按命令配置 StructuredOutput:
格式 | 处理方式 |
|---|---|
json | 解析 stdout 为 JSON,返回解析后的 JSON + 脱敏 stdout |
ndjson | 解析换行分隔 JSON 为 JSON 数组 |
csv / table / text | 作为脱敏文本返回 |
注意: 连接器不会注入全局 --json 标志,需要在每个命令模板中显式放置输出标志。
类别 | 命令示例 |
|---|---|
只读 | auth status, repo view, issue list, pr list, pr view, release list |
需审批 | issue create, issue comment, pr review, pr merge, release create |
类别 | 命令示例 |
|---|---|
只读 | account show, group list, resource list, webapp list |
需审批 | resource create/update/delete, deployment create, role assignment changes |
类别 | 命令示例 |
|---|---|
只读 | config current-context, get pods/services/deployments -o json, describe |
高风险需审批 | apply, delete, scale, rollout restart, exec, port-forward |
日志可能暴露密钥,建议至少 medium 风险等级。
类别 | 命令示例 |
|---|---|
只读 | listen status, fixtures/list, customers/list(最小权限凭证) |
高风险需审批 | payment mutations, refunds, customer/subscription mutations, webhook trigger, event replay |
类别 | 命令示例 |
|---|---|
只读 | auth status, schema inspection, calendar agenda, docs search/read, sheets read, mail search/read, meeting minutes query |
需审批 | send messages, write docs, write sheets, send email, approve/reject workflows, create/update OKRs, raw API calls |
网关暴露以下 RESTful 端点:
方法 | 端点 | 说明 |
|---|---|---|
GET | /admin/external-cli/connectors | 列出所有连接器 |
GET | /admin/external-cli/connectors/{connector} | 获取连接器状态 |
GET | /admin/external-cli/connectors/{connector}/commands | 列出连接器命令 |
POST | /admin/external-cli/preview | 预览命令(需 CSRF) |
POST | /admin/external-cli/execute | 执行命令(需 operator 角色 + 匹配审批元数据) |
# 列出所有连接器
openclaw external list
# 查看连接器状态
openclaw external status gh
# 列出连接器命令
openclaw external commands gh
# 预览命令
openclaw external preview gh repo_view --param repo=clawdotnet/openclaw.net
# 执行命令
openclaw external execute gh repo_view --param repo=clawdotnet/openclaw.net
# 使用 --json 获取机器可读输出
openclaw external list --json本次 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 # 单元测试// 连接器注册表
public interface IExternalCliConnectorRegistry
{
ExternalCliPreparedInvocation BuildPreview(ExternalCliPreviewRequest request, bool dryRun);
}
// 命令执行器
public interface IExternalCliRunner
{
Task<ExternalCliExecutionResult> ExecuteAsync(ExternalCliPreparedInvocation prepared, CancellationToken ct);
}
// 审计 Sink
public interface IExternalCliAuditSink { void Record(ExternalCliAuditEntry entry); }
// 事件 Sink
public interface IExternalCliEventSink { void Record(ExternalCliRuntimeEvent evt); }// 连接器配置选项
public sealed class ExternalCliConnectorOptions
{
public bool Enabled { get; set; } = false;
public string DisplayName { get; set; } = "";
public string Executable { get; set; } = "";
public string DefaultOutputFormat { get; set; } = "json";
public ExternalCliStatusCommandOptions? StatusCommand { get; set; }
public ExternalCliStatusCommandOptions? VersionCommand { get; set; }
public Dictionary<string, ExternalCliCommandOptions> Commands { get; set; } = new();
// ...
}
// 命令配置选项
public sealed class ExternalCliCommandOptions
{
public string Description { get; set; } = "";
public string[] ArgsTemplate { get; set; } = [];
public string[]? DryRunArgsTemplate { get; set; }
public string RiskLevel { get; set; } = ExternalCliRiskLevel.High;
public bool ReadOnly { get; set; } = false;
public bool RequiresApproval { get; set; } = false;
public string StructuredOutput { get; set; } = ExternalCliOutputFormat.Text;
public Dictionary<string, ExternalCliParameterOptions> Parameters { get; set; } = new();
// ...
}
// 执行结果
public sealed class ExternalCliExecutionResult
{
public ExternalCliInvocationPreview Preview { get; init; } = new();
public int ExitCode { get; init; }
public double DurationMs { get; init; }
public bool TimedOut { get; init; }
public bool Failed { get; init; }
public bool StdoutTruncated { get; init; }
public bool StderrTruncated { get; init; }
// ...
}
// 审计记录
public sealed class ExternalCliAuditEntry
{
public string Id { get; init; } = "";
public DateTimeOffset TimestampUtc { get; init; }
public string SessionId { get; init; } = "";
public string Connector { get; init; } = "";
public string Command { get; init; } = "";
public string RedactedArgsPreview { get; init; } = "";
public string? ApprovalFingerprint { get; init; }
public int ExitCode { get; init; }
// ...
}ExternalCliTool 接收工具请求ToolActionPolicyResolver 解析操作描述符(含 IsMutation、RequiresApproval、ApprovalFingerprint、RiskLevel、ReadOnly)ExternalCliConnectorRegistry.BuildPreview() 解析模板、验证参数、计算指纹ExternalCliRunner.ExecuteAsync() 通过 ProcessStartInfo.ArgumentList 启动进程StructuredOutput 设置解析输出ExternalCliAuditEntry(不可篡改)ExternalCliEventSink 发送运行时事件ToolActionDescriptor 新增字段:
RequiresApproval — 是否需要审批ApprovalFingerprint — 审批指纹RiskLevel — 风险等级ReadOnly — 是否只读OpenClawToolExecutor 中的审批逻辑增强:
OpenClaw 通过外部 CLI 连接器调用 lark-cli(官方 npm 包 @larksuite/cli)来操作飞书。这需要:
lark-cli1. 访问飞书开放平台
2. 创建应用
3. 开启机器人能力
4. 获取凭证
cli_xxxxxxxxx)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. 发布应用
1. 安装 lark-cli
# 全局安装
npm install -g @larksuite/cli
# 验证安装
lark-cli --version2. 配置凭证(交互式)
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应显示配置正确、凭证有效。
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重复扫码授权流程。
# 搜索文档
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"在 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 }
}
}
}
}
}
}
}
}# 查看连接器状态
openclaw external status lark
# 列出可用命令
openclaw external commands lark
# 预览搜索文档命令
openclaw external preview lark docs_search --param query="项目计划"
# 执行搜索(如需要审批,先预览再加 --yes)
openclaw external execute lark docs_search --param query="项目计划" --yes
# 预览创建文档(变更命令,需要审批)
openclaw external preview lark docs_create \
--param title="会议纪要 2026-05-10" \
--param content="# 会议纪要\n\n## 参与人\n- ..."
# 审批后执行
openclaw external execute lark docs_create \
--param title="会议纪要 2026-05-10" \
--param content="# 会议纪要\n\n## 参与人\n- ..." \
--yes你也可以让 AI 助手自动完成大部分配置工作:
帮我配置飞书云文档能力。请按以下步骤做:
1. 检查是否安装了 lark-cli,如果没有则执行:
npm install -g @larksuite/cli
2. 运行 lark-cli doctor 检查当前状态
3. 如果显示缺少凭证配置,问我 App ID 和 App Secret
4. 拿到凭证后完成配置:
echo "AppSecret" | lark-cli config init --app-id "AppID" --app-secret-stdin --brand feishu
5. 运行 lark-cli auth login --no-wait --recommend --json
把返回的 verification_url 发给我,告诉我扫码授权
6. 我扫码确认后,用返回的 device_code 执行登录
7. 如果缺少搜索权限,按上面的方式再走一遍授权流程补充 search:docs:read
8. 全部完成后,用以下命令验证各项能力:
- lark-cli docs +search --query "文档" --as user
- lark-cli docs +create --title "测试文档" --markdown "# 你好"
- lark-cli calendar +agenda --as user模块 | 能力 |
|---|---|
docs | 搜索文档、创建文档、读取文档、更新文档、分享文档 |
sheets | 读取表格、写入单元格、添加行/列 |
message | 发送文本消息、卡片消息、图片消息 |
calendar | 查询日程、创建日程 |
搜索邮件、读取邮件、发送邮件 | |
contact | 搜索用户、查询部门 |
wiki | 搜索知识库、读取知识库页面 |
meeting | 查询会议纪要 |
drive | 文件上传、下载、管理 |
bitable | 多维表格操作 |
approval | 审批流程查询/操作 |
okr | OKR 查询/创建 |
RequiresApproval: trueexternal_cli 的审计记录RedactionRulesTimeoutSeconds问题 | 排查方法 |
|---|---|
命令执行失败 | 检查 lark-cli doctor 输出,确认凭证和授权状态 |
权限不足 | 在飞书开放平台检查应用权限是否已开通并发布 |
审批指纹不匹配 | 命令参数或模板可能在审批后发生变化,重新预览获取新指纹 |
输出为空 | 检查 StructuredOutput 设置是否与 CLI 实际输出格式匹配 |
超时 | 增加 TimeoutSeconds 设置 |
OpenClaw.NET 的 External CLI Connectors 提供了一个安全、受控、可审计的框架,将各种官方平台 CLI 集成到 AI Agent 的工具调用体系中。通过命名命令白名单、参数模板、风险评分、预览-审批流程、密钥脱敏和审计日志等多重安全机制,实现了在保持平台深度的同时确保操作安全。
对于飞书/Feishu 集成,通过 lark-cli 外部 CLI 连接器,AI Agent 可以安全地读写飞书云文档、查询日历、发送消息等,所有变更操作都需要显式审批,确保企业数据安全。