Skip to content

CLI 使用指南 ​

dc3-cli 是 IoT DC3 的命令行客户端:一个独立的 TypeScript 包(Node ≥ 22),把平台的全部能力封装成 dc3 命令,全程经网关 /api/v3/* 通信。读完这页你能装好它、配好网关、登录拿到 token,并用真实命令读设备、读位号值、下发命令。

你在这里:已经能用前端或 curl 跑通 第一个设备,现在想用命令行或在 AI Agent 里驱动平台。需要让 AI 工具直连平台时,转向 AI Agent / MCP 集成。

它是什么、给谁用 ​

dc3-cli 不是另一套后端,它只是一个 HTTP 客户端:所有请求都打到你配置的网关地址,路径前缀统一为 /api/v3/* (网关再聚合到鉴权、管理、数据、Agentic 各中心)。它没有任何 Java 或构建上的耦合,装一个 Node 包即可独立运行。

它面向三类人:在终端里快速查设备、读值、下发命令的运维/接入工程师;把平台操作写进脚本与流水线的自动化作者;以及让 AI 编码工具(Claude Code、Codex、Gemini CLI 等)通过 shell 直接调用平台的 Agent 集成方——每个命令都支持 --format json ,输出可被程序稳定解析。

bash
# dc3-cli 未发布到 npm registry——从主仓库源码安装(pnpm 项目)
cd <iot-dc3 检出目录>/dc3-cli
pnpm install && pnpm build
pnpm link   # 全局可用 dc3 命令

三步即可开始:配网关、登录、然后用。

bash
dc3 config set gateway http://localhost:8000   # 网关地址(示例:本地默认端口 8000)
dc3 auth login                                 # 交互式登录
dc3 device list                                # 列出设备
dc3 device import-template --driver-id 1 --profile-id 1   # 下载 XLSX 导入模板
dc3 device import devices.xlsx --driver-id 1 --profile-id 1   # 批量导入(默认轮询到终态)

鉴权:三段式 token 如何拿到与保鲜 ​

dc3 auth login 背后是一条三段式的 token 链路,与平台 黄金路径 里 curl 登录用的是同一对端点,只是 CLI 帮你串好了。先 POST /api/v3/auth/token/salt 用租户名 + 用户名换一个盐(salt);再把明文密码连同盐 POST /api/v3/auth/token/generate,换回一个 JWT。拿到 JWT 后,CLI 解出其中的 iat / exp,把 { token, salt, tenant, username, issuedAt, expiresAt } 写入 ~/.dc3/tokens.json(文件权限 0600,每个 profile 一条)。

① 配置与登录(首次)② 调用前 token 检查与静默续期③ 携带鉴权头调用网关④ 401 兜底 · 输出与退出码写 tokens.json (0600) · 密码入凭据存储解析 --profile · --format剩余有效期 < renewal_threshold_hours(profile 配置 · 默认 1 小时) ?续期 (重走 salt → generate)自动重试一次原请求dc3 auth login (首次)登录编排POST salt → POST generateJWT (12h)dc3 point read 456789 --format json调用前检查 exp取密码 (keychain → encrypted → env → prompt)密码静默重登 salt → generatePOST /api/v3/data/point_value/latestX-Auth-Tenant · X-Auth-Login · X-Auth-Token路由到数据中心R<T>R<T>401 (时钟漂移 / 服务重启)结果 (json / table / yaml)stdout · exit 0任何错误: stderr · process.exit(1)终端shell / 脚本 / AI Agentdc3 命令模块device / point / command…核心层TokenManager · HttpApiClientCredentialStore四级解析链dc3-gateway:8000 · /api/v3/*中心服务auth / manager / data / agentic每个命令都支持 --format json:Agent 先看退出码 (0/1) 判定成败,再读 stderr 的错误信息决定是否重新登录或重试终端 / 命令模块核心层 / 网关 / 中心凭据 / 错误路径调用 / 消息返回 / 兜底

后续每次调用 API 前,CLI 会做两件事保证你几乎不会撞到 401:

  • 主动续期:若当前 token 在续期阈值内即将过期,调用前先静默重登换新 token。阈值由设置项 renewal_threshold_hours 控制 (dc3 config set renewal_threshold_hours <n>,可配 0–12 小时),默认 1 小时(即剩余有效期不足 1h 就提前续)。
  • 401 兜底:万一仍收到 401(时钟漂移、服务重启等),续期后自动重试一次该请求。

发往受保护端点的请求头沿用平台约定的三件套——X-Auth-Tenant、X-Auth-Login、X-Auth-Token,其中 X-Auth-Token 携带 { salt, token }。

续期依赖密码可取

主动续期和 401 重试都需要 CLI 能重新拿到密码去走一遍 salt→generate。如果你用 --no-save 或 --store prompt(不落盘),token 过期后没有可用密码,CLI 无法静默续期,需要你手动 dc3 auth login 重新登录。

不要打印真实密码或 token

本页所有密码、token 均为示例占位。请勿在脚本、日志、issue 中明文粘贴真实密码或 JWT;dc3 auth token 仅用于本机排障,输出的令牌等同于一次有效登录凭证。

凭据存哪儿:存储后端与解析链 ​

密码本身不进 tokens.json,而是交给凭据存储后端保管。续期需要密码时,CLI 按固定解析链查找:先查 profile 配置的后端 (dc3 config set auth.store <type> 选定的那个),未命中再按 keychain → encrypted → env(DC3_PASSWORD)固定顺序兜底; 第一个返回非空密码的后端胜出,不可用的后端跳过、不报错。解析链上没有 prompt 兜底——查不到密码就放弃本次静默续期,等 401 兜底把错误暴露出来。所以 --no-save / --store prompt(不落盘)下 token 过期后没有可用密码,只能手动重登。

登录 · 三段式 token 链路续期 / 401 重登 · 密码四级解析链(可用且命中即采用)① 取盐② 换 token③ 保存携带token 临期或 401 —— 需重新走 salt → generate,取回密码是否 · 下一级是否 · 下一级是否 · 兜底dc3 auth login--tenant · --usernamePOST token/salt租户 + 用户名 → saltPOST token/generate明文密码 + salt → JWT~/.dc3/tokens.json权限 0600 · token/salt/iat/exp后续 API 调用X-Auth-Tenant · Login · Token密码不入 tokens.json交凭据存储后端保管OS 钥匙串Keychain / Secret Service / CredManencrypted 加密文件~/.dc3/credentials.enc · AES-256-GCM + scrypt环境变量DC3_PASSWORD (CI/CD)可用?可用?可用?交互 prompt不落盘 · 无法静默续期dc3 config set auth.store <type> 选择当前 profile 的后端--no-save / --store prompt 时 token 过期后必须手动 dc3 auth loginkeychain 日常默认 · encrypted 钥匙串不可用时回落env 供 CI/脚本 · prompt 最安全但不可自动续期登录命令与调用HTTP 端点 / 钥匙串token / 加密文件解析链 / 环境变量兜底与风险判定

四种后端各自的定位:

存储落点适用场景
keychainOS 钥匙串(macOS Keychain / Linux Secret Service / Windows Credential Manager)日常使用(默认)
encrypted~/.dc3/credentials.enc,AES-256-GCM 加密钥匙串不可用时的回落
env读取 DC3_PASSWORD 环境变量CI/CD、脚本
prompt不落盘,仅登录时交互输入安全性最高,无法自动续期

加密文件后端用 aes-256-gcm:密文在 ~/.dc3/credentials.enc,解密密钥是首次写入时随机生成的 256-bit 密钥,单独存放于 ~/.dc3/credentials.key(两个文件均为 0600/受限 ACL)。密钥随机、独立于机器标识——只拿到密文文件无法离线解密;旧版"机器 标识经 scrypt 派生密钥"的文件格式只保留读取迁移用,新写入一律走随机密钥。密码以 identifier → password (username@tenant)形式存储,不写明文。备份或迁移 ~/.dc3 目录时,credentials.enc 与 credentials.key 必须一起带走, 缺了 key 文件密码就不可恢复。

bash
# 登录时一并选择凭据后端
dc3 auth login --store keychain        # 存入 OS 钥匙串(适合日常)
dc3 auth login --store env             # 从 DC3_PASSWORD 读取(适合 CI)
dc3 auth login --no-save               # 不保存密码,过期需手动重登

# 非交互登录(示例值,请勿用真实密码明文)
dc3 auth login --tenant default --username dc3 --password '<示例密码>'

# CI/脚本推荐形态:设置 DC3_PASSWORD 后只传身份参数(stdin 非终端时绝不弹交互)
export DC3_PASSWORD='<示例密码>'
dc3 auth login --tenant default --username dc3

dc3 auth status                        # 查看登录态与剩余有效期
dc3 auth token --header                # 以 JSON 打印完整鉴权头(排障用)

命令模块概览 ​

CLI 共 21 个顶层命令组,按对象与场景划分。配置与鉴权是入口;元数据类(device/driver/point/profile/group/label)对应管理中心的 增删改查;事件/命令/告警/仪表盘/主题对应数据与运行态;其余八组(chat/tools/analytics/session/action/provider/model/attachment) 面向 Agentic 中心——对话、MCP 工具目录、时序分析、会话与高危审批、模型提供方与模型配置、对话附件。

模块命令前缀用途
配置dc3 config网关地址、租户、凭据后端、profile 切换与整体重置
鉴权dc3 auth登录(含 --oauth 客户端凭证模式)/登出、登录态与 token
设备dc3 device设备增删改查、计数、在线状态、XLSX 批量导入
驱动dc3 driver驱动增删改查、运行状态
位号dc3 point位号增删改查、读最新值、游标分页历史、写值
模板dc3 profile设备/位号模板增删改查
分组dc3 group设备分组管理
标签dc3 label标签管理
事件dc3 event事件定义增删改查、事件历史
命令dc3 command命令定义增删改查、调用、执行历史
告警dc3 alert告警概览、确认/批量确认、趋势、Top 来源与深度分析
仪表盘dc3 dashboard统计、时序、拓扑、健康、实时流
主题dc3 topicMQTT 主题列表(只读)
对话dc3 chat与 Agentic 中心对话(流式、续聊、指定模型)
工具目录dc3 toolsMCP 工具目录:list/call 直调平台工具(需 OAuth 登录)
分析dc3 analytics位号时序的 9 个粗粒度分析操作
会话dc3 sessionAgentic 会话生命周期(列表、消息、重命名、删除)
审批dc3 action高危工具调用的待审列表与确认/驳回
提供方dc3 provider模型提供方管理与连通性检查
模型dc3 model模型配置管理与连通性检查
附件dc3 attachment对话附件上传/列表/删除

结构上,dc3 入口把命令行解析到 21 个命令组,所有模块再共用同一组核心组件:HTTP 客户端、配置管理、token 管理与凭据存储。命令模块只描述"做什么",真正的网关请求、profile 解析、续期与密码读取都收敛在核心层。

入口与配置元数据 · 管理中心运行态 · 数据中心AI · Agentic核心层 · 所有模块共用(模块只描述"做什么")入口解析为 14 个命令模块全部模块 → 共用核心层:网关请求 · profile 解析 · token 续期 · 密码读取dc3TypeScript CLI · Node ≥ 20 · pnpm linkdc3 configgateway · 租户 · store · profiledc3 authlogin / logout / status / tokendc3 deviceCRUD · 计数 · 在线态dc3 driver列表 · 详情 · 运行态dc3 pointCRUD · 读值 · 历史 · 写值dc3 profile模板 CRUDdc3 group设备分组dc3 label标签管理dc3 event事件定义 · 事件历史dc3 command命令列表 · 调用 · 回执dc3 alert概览 · 确认 · 趋势 · Topdc3 dashboard统计 · 拓扑 · 健康 · 实时流dc3 topic主题列表dc3 chat与 Agentic 对话可选流式 · 指定模型HttpApiClient/api/v3/* · X-Auth-* 头 · --format jsonProfileConfig~/.dc3 · 多 profile 互不干扰TokenManager续期阈值 1h · 401 兜底重试一次CredentialStorekeychain / encrypted / env / prompt全局选项: --profile · --format json|table|yaml · --verbose · --ci (无色 · json · 严格退出码)退出码: 0 成功 · 1 任何错误(顶层捕获后 process.exit(1),不细分错误类别)入口 / 配置命令模块 / 核心服务凭据安全约定说明共用依赖

全局选项只有两个,且只能出现在第一个子命令之前:--profile <name> 为本次调用切换配置档(配置档不存在则报错退出); --format json|table|yaml 设定全局输出格式。放在子命令之后会被当作未知选项拒绝(退出码 1),这样叶子命令自己的选项(如 device update <id> --version <n>)不会被全局选项劫持。每个命令还带自己的 --format,最终格式按「命令 --format → 全局 --format → 持久化设置 settings.output_format(默认未设)→ TTY 默认(终端 table、管道 json)」解析。裸 dc3 打印完整 帮助并退出 0;dc3 <组> --help 与 dc3 help <组> <子命令> 输出对应命令的帮助。

多 profile 并存(开发 / 生产切换)

每个 profile 各自保存网关、租户、凭据后端与 token,互不干扰:

bash
dc3 config profile use prod
dc3 config set gateway https://iot.example.com   # 示例生产地址
dc3 auth login

dc3 config profile use default                    # 切回本地
dc3 device list

Agentic 能力:对话、工具目录与审批 ​

CLI 里有一组命令直连 Agentic 中心:chat 发起对话;tools 把平台的 MCP 工具目录带到终端;analytics 做位号时序的粗粒度 分析;session/action 管理会话与高危工具调用审批;provider/model 管理模型提供方与模型配置;attachment 处理对话附件。

tools 走 MCP 传输,只接受 OAuth 票据:先用 dc3 auth login --oauth 走 client_credentials 登录(客户端需先在控制台的 MCP 设置里注册),普通账号密码登录换到的票据不能用于 /mcp。

bash
# OAuth 客户端凭证登录(示例值)
dc3 auth login --oauth --client-id '<client-id>' --client-secret '<client-secret>'

# 列出当前 OAuth 票据可见的 MCP 工具,并从 CLI 直接调用一个
dc3 tools list
dc3 tools call read_device --args '{"deviceId":456789}'

# 与 Agentic 中心对话(可流式、可续聊、可指定模型)
dc3 chat "设备 123456 的温度最近正常吗?"
dc3 chat --model gpt-4o --stream "分析设备数据"
dc3 chat --conversation-id 9a1f2c3d-0000-0000-0000-000000000000 "继续刚才的话题"

# 会话管理与高危工具调用审批(删除/确认/驳回有交互确认,脚本里加 --yes 跳过)
dc3 session list
dc3 action pending --conversation-id 9a1f2c3d-0000-0000-0000-000000000000
dc3 action confirm 3e5f7a9b-0000-0000-0000-000000000000 --yes

# 位号时序分析:9 个操作(query_latest、query_history、compute_stats、compare_periods、
# rank_entities、trend_analysis、threshold_report、correlate、data_quality_report)
dc3 analytics list
dc3 analytics run trend_analysis --args '{"pointId":456789}'
dc3 analytics run query_history --args '{"pointId":456789,"days":7}'

# 模型提供方与模型配置
dc3 provider list
dc3 provider check --id 123
dc3 model list

# 对话附件
dc3 attachment upload report.xlsx --conversation-id 9a1f2c3d-0000-0000-0000-000000000000

超出 argv 大小限制的超长 JSON 参数用 --args-file <path>(- 读 stdin)代替 --args,tools call 与 analytics run 都支持这一形态。

实操:读值、读历史、下发命令 ​

下面用真实命令演示常见操作,所有 ID、值均为示例占位。读最新值对应数据中心 POST /api/v3/data/point_value/latest,写位号对应 POST /api/v3/data/point_command/write,命令回执对应 GET /api/v3/data/command_history/get_by_record_id?record_id=<id>。

bash
# 读位号最新值
dc3 point read 456789 --format json

# 读位号历史:--limit 是页大小(默认 100),--cursor 翻下一页
dc3 point history 456789 --device-id 123456 --limit 100 --format json
dc3 point history 456789 --device-id 123456 --limit 100 --cursor '<上一页返回的 cursor>' --format json

# 给可写位号下发写命令(位号须为 WRITE_ONLY 或 READ_WRITE)
dc3 point write 456789 --device-id 123456 --value 25.5

# 调用设备命令
dc3 command call --device-id 123456 --command-id 789 --params '{"speed":1500}'

# 查命令执行回执(用 call 返回的 recordId,示例值)
dc3 command history 9a1f2c3d-0000-0000-0000-000000000000

# 设备与系统健康
dc3 device status 123456 --format json
dc3 dashboard health --format json
bash
# 等价的写命令直连网关(示例值)
curl -X POST http://localhost:8000/api/v3/data/point_command/write \
  -H 'Content-Type: application/json' \
  -H 'X-Auth-Tenant: default' \
  -H 'X-Auth-Login: dc3' \
  -H 'X-Auth-Token: {"salt":"<示例盐>","token":"<示例JWT>"}' \
  -d '{"deviceId":123456,"pointId":456789,"value":"25.5"}'

历史查询是游标分页:每页响应带下一页的 opaque cursor,把它作为 --cursor 传入即可继续翻页;--limit 控制页大小(默认 100)。另外注意平台上有两个"命令历史"资源:dc3 command history <recordId> 按执行记录 ID查 dc3 command call 的回执 (command_history/get_by_record_id);写命令侧另有按 command_id 查询的 point_command_history/get_by_command_id,CLI 未封装该端点,两者不要混淆。

dc3 point write 与 dc3 command call 的最终落点是命令链路。写命令是异步下发:网关/数据中心受理后立即返回一个命令 ID,真正的执行结果要用该 ID 去查命令历史。

写失败不回显、两条链路各有有效期

位号能否写取决于它的 rwFlag,对 READ_ONLY 位号写会被拒绝。写命令若执行失败,回执的 responseValue 为 null ,不会把失败值回显成成功。两条链路的有效期不同:dc3 point write 的写命令 PointCommandDTO.expireAt 默认 now + 10s,超时 未被驱动消费即作废;dc3 command call 的超时由命令定义的 timeout 字段决定(dc3 command add --timeout,默认 30 秒)。 这些语义在 CLI 与直连 curl 下完全一致。

退出码与错误信封:脚本里如何判定结果 ​

dc3 用四档退出码区分失败类别。任何失败都经单一收口报告:stderr 恒定一行 Error: <message>;当生效输出格式为 json 或 yaml 时,stdout 还会输出一份机器可读信封(table 格式下 stdout 保持干净,人读 stderr 即可):

json
{"ok":false,"error":{"kind":"network","code":"NETWORK","message":"Network request failed (...)"}}
退出码含义
0成功
1业务错误:参数/校验失败、网关 API 报错(含 404/409/5xx)、超时
2网络错误:请求未到达网关(DNS、socket、TLS)
3鉴权错误:401/403,需要重新登录

需要更细的失败原因时按信封的 error.kind 判别,不要去解析 stderr 文本:

error.kind含义退出码
usage命令行本身非法(未知选项/命令、参数值无效、多余参数)1
validation业务校验失败(网关往返前后)1
auth网关拒绝鉴权(HTTP 401/403)3
network请求未到达网关2
api网关非 2xx 响应,code 形如 API_<状态码>1
timeout长任务超过截止时间1
bash
# CI 中按退出码分流:3 重新登录、2 网络问题、1 其他错误
dc3 device list --format json >/dev/null 2>err.log
code=$?
if [ "$code" -eq 3 ]; then
  echo "登录已过期,需要 dc3 auth login"
elif [ "$code" -eq 2 ]; then
  echo "网关不可达"
elif [ "$code" -ne 0 ]; then
  echo "其他错误"; cat err.log
fi

# json/yaml 输出下从 stdout 信封读 error.kind(比解析 stderr 文本稳)
dc3 point read 456789 --format json 2>/dev/null | grep -o '"kind":"[a-z]*"'

给 AI Agent 用时优先 --format json

让 AI 编码工具通过 shell 调用平台时,统一加 --format json,输出字段稳定、可解析;失败时先看退出码(2 网络不可达、3 需要重新登录),再读 stdout 信封的 error.kind 决定重试还是重登。若希望 AI 工具直接发现并调用平台全部 API,参见 AI Agent / MCP 集成 的网关 MCP 端点接法。

延伸阅读 ​

  • 自动化 — CLI、脚本与 MCP 在整体自动化中的位置
  • AI Agent / MCP 集成 — 让 AI 工具经网关 /mcp 自动发现并调用平台工具
  • 第一个设备 — 黄金路径:从建驱动到读值的端到端流程

基于 AGPL-3.0 协议发布