Files
dingMCP/distribution/agent-compat-install.template.md

280 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 钉钉审批兼容客户端安装任务
仅当当前 Agent 明确不支持远程 Streamable HTTP MCP、标准 OAuth,或用户无法在宿主本机 OAuth 回调所在设备打开授权页面时,才使用本兼容安装。即使宿主支持远程 MCP,只要它使用 `127.0.0.1`/`localhost` 回调,而用户通过 SSH、无头环境或 Messenger 在另一台设备操作,就应使用本地 Bridge 的可跨设备 device-code 登录;同机回调可以完成时才返回主安装页直接连接 `{{GATEWAY_URL}}`。
用户把本文件或本文件的链接交给你,即表示授权你为当前用户安装或更新“钉钉审批”兼容客户端、Skill 和名为 `dingtalk-approval` 的 MCP。该授权不包含同意、拒绝、退回、撤回或发起任何审批。
请从“步骤 1”开始逐项执行并验收,不要跳步,不要让用户手工填写企业凭证,也不要根据经验自行改写安装器返回的路径或 MCP 配置。Windows 是完整支持的平台,必须优先使用下面的 PowerShell 步骤。
## 固定发布入口
- 版本:`{{VERSION}}`
- 安装器:`{{INSTALLER_URL}}`
- 安装器 SHA-256:`{{INSTALLER_SHA256}}`
- 发布公钥:`{{PUBLIC_KEY_URL}}`
- 公钥 SHA-256:`{{PUBLIC_KEY_SHA256}}`
- 公钥编号:`{{RELEASE_KEY_ID}}`
- 签名清单:`{{MANIFEST_URL}}`
- 清单签名:`{{MANIFEST_SIGNATURE_URL}}`
- 备用发布源:
{{DOWNLOAD_MIRROR_BASE_URLS_MARKDOWN}}
- 统一网关:`{{GATEWAY_URL}}`
- Windows 安装引导:`{{BOOTSTRAP_WINDOWS_URL}}`
- Windows 安装引导备用地址:
{{BOOTSTRAP_WINDOWS_MIRROR_URLS_MARKDOWN}}
- Windows 安装引导 SHA-256:`{{BOOTSTRAP_WINDOWS_SHA256}}`
- Linux/macOS 安装引导:`{{BOOTSTRAP_POSIX_URL}}`
- Linux/macOS 安装引导备用地址:
{{BOOTSTRAP_POSIX_MIRROR_URLS_MARKDOWN}}
- Linux/macOS 安装引导 SHA-256:`{{BOOTSTRAP_POSIX_SHA256}}`
- 私有 Node.js:`{{NODE_VERSION}}`(最低兼容版本 `{{NODE_MINIMUM_VERSION}}`)
首次安装通过上述 HTTPS 地址和固定 SHA-256 建立信任;安装器随后必须使用固定公钥验证 Ed25519 清单签名和全部发布物哈希。URL、TLS、签名或哈希任一不匹配都必须停止。不得索取 AppKey、AppSecret、AuthoritySecret、CorpId、userId、员工号、Cookie 或 Token。
## 完成标准
只有以下条件全部成立,才能告诉用户“安装完成,可以使用”:
1. 对应平台安装引导的 SHA-256 正确,并已选用兼容的系统 Node 或经过官方哈希校验的私有 Node;
2. 安装器 JSON 返回 `ok: true`;
3. 已按当前 Agent 的官方方式安装返回的 `skillPath`;
4. 已原样使用返回的 `mcpConfig` 注册并信任本地 stdio MCP;
5. `approval_login` 确认已登录;
6. `approval_list_todos` 的双来源验证中,钉钉 OA 与薪福通都为 `ok`;
7. 未执行任何审批写操作。
## 步骤 1:确认操作系统与架构
支持以下当前用户环境:
- Windows 10/11:x64 或 ARM64;
- Linux:x64 或 ARM64;
- macOS:Intel x64 或 Apple Silicon ARM64。
系统无需预装 Node.js。安装引导会优先复用版本不低于 `{{NODE_MINIMUM_VERSION}}` 且 npm 可用的系统 Node;否则自动准备只属于本插件的 Node `{{NODE_VERSION}}`。不要让用户安装全局 Node,不要使用管理员权限、`sudo`、全局 npm 安装、DWS 或浏览器自动化。
## 步骤 2:下载、校验并执行平台安装引导
不要在浏览器中复制脚本内容,不要对 URL 解码、重新编码或手工拼接。必须先校验安装引导 SHA-256,再执行它。
为执行平台安装引导的 Agent 工具调用设置合理超时。引导的单个下载会在连接失败、长时间无数据或 90 秒总时限到达时明确失败并换用下一固定来源,不会静默等待 300 秒;安装器会把 `[dingtalk-approval]` 开头的阶段进度写入 stderr,把唯一的最终结果 JSON 写入 stdout。进度文本不是失败,也不能混入 JSON 解析。进程仍在运行时不得并发启动第二次安装。
安装器和后续更新优先使用系统 `curl` 下载签名清单与发布物;`curl` 会直接使用 `HTTPS_PROXY`、`HTTP_PROXY`、`ALL_PROXY` 和 `NO_PROXY`,Node `fetch` 仅在系统没有 `curl` 时兜底。登录和 Bridge 仍会按 Node 能力启用环境代理。不要设置全局 `NODE_OPTIONS=--use-env-proxy`,也不要手工预装 `node_modules`;这会让 npm 与 Node 的代理机制叠加,并破坏安装器的原子安装与故障恢复。
### Windows(PowerShell)
无论当前 Agent 默认使用 PowerShell、CMD 还是 Git Bash,Windows 都必须调用普通 PowerShell 执行下面的完整流程。不得从 Git Bash 直接运行内部的 `node dingtalk-approval-installer.mjs ...` 命令;内部安装器不是用户安装入口。
在普通 PowerShell 中逐行运行:
```powershell
$dingUtf8 = New-Object System.Text.UTF8Encoding($false)
[Console]::InputEncoding = $dingUtf8
[Console]::OutputEncoding = $dingUtf8
$OutputEncoding = $dingUtf8
$dingBootstrapDir = Join-Path ([System.IO.Path]::GetTempPath()) ("dingmcp-bootstrap-" + [guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Path $dingBootstrapDir -Force | Out-Null
$dingBootstrap = Join-Path $dingBootstrapDir "dingtalk-approval-bootstrap.ps1"
$dingBootstrapUrls = @({{BOOTSTRAP_WINDOWS_URLS_POWERSHELL}})
$dingBootstrapDownloaded = $false
$dingCurl = Get-Command curl.exe -ErrorAction SilentlyContinue
foreach ($dingBootstrapUrl in $dingBootstrapUrls) {
try {
if ($dingCurl) {
& $dingCurl.Source --fail --location --silent --show-error --connect-timeout 10 --max-time 90 --speed-time 20 --speed-limit 1024 --output $dingBootstrap $dingBootstrapUrl
if ($LASTEXITCODE -ne 0) { throw "curl.exe 退出码 $LASTEXITCODE" }
} else {
Invoke-WebRequest -UseBasicParsing -Uri $dingBootstrapUrl -OutFile $dingBootstrap -TimeoutSec 90
}
} catch {
continue
}
$dingBootstrapHash = (Get-FileHash -Algorithm SHA256 $dingBootstrap).Hash.ToLowerInvariant()
if ($dingBootstrapHash -ne "{{BOOTSTRAP_WINDOWS_SHA256}}") { throw "Windows 安装引导 SHA-256 不匹配,停止安装:$dingBootstrapUrl" }
$dingBootstrapDownloaded = $true
break
}
if (-not $dingBootstrapDownloaded) { throw "所有 Windows 安装引导下载源均不可用" }
$dingInstallJson = & powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File $dingBootstrap
if ($LASTEXITCODE -ne 0) { throw "钉钉审批安装引导执行失败:$dingInstallJson" }
$dingInstall = $dingInstallJson | ConvertFrom-Json
if ($dingInstall.ok -ne $true) { throw "钉钉审批安装失败:$($dingInstall.error)" }
$dingInstall | ConvertTo-Json -Depth 20
```
完成后可删除 `$dingBootstrapDir`。任一下载或哈希检查失败都不能忽略。
### Linux / macOS(POSIX shell)
```bash
ding_bootstrap_dir="$(mktemp -d)"
ding_bootstrap="$ding_bootstrap_dir/dingtalk-approval-bootstrap.sh"
ding_bootstrap_downloaded=0
for ding_bootstrap_url in {{BOOTSTRAP_POSIX_URLS_POSIX}}; do
rm -f "$ding_bootstrap"
if command -v curl >/dev/null 2>&1; then
curl --fail --location --connect-timeout 10 --max-time 90 --speed-time 20 --speed-limit 1024 --output "$ding_bootstrap" "$ding_bootstrap_url" || continue
elif command -v wget >/dev/null 2>&1; then
wget --https-only --timeout=90 --output-document="$ding_bootstrap" "$ding_bootstrap_url" || continue
else
echo '缺少 curl 或 wget,无法下载安装引导' >&2
exit 1
fi
if command -v sha256sum >/dev/null 2>&1; then
ding_bootstrap_hash="$(sha256sum "$ding_bootstrap" | awk '{print $1}')"
else
ding_bootstrap_hash="$(shasum -a 256 "$ding_bootstrap" | awk '{print $1}')"
fi
if [ "$ding_bootstrap_hash" != '{{BOOTSTRAP_POSIX_SHA256}}' ]; then
echo "Linux/macOS 安装引导 SHA-256 不匹配,停止安装:$ding_bootstrap_url" >&2
exit 1
fi
ding_bootstrap_downloaded=1
break
done
if [ "$ding_bootstrap_downloaded" -ne 1 ]; then
echo '所有 Linux/macOS 安装引导下载源均不可用' >&2
exit 1
fi
ding_install_json="$(sh "$ding_bootstrap")"
printf '%s\n' "$ding_install_json"
```
完成后可删除 `$ding_bootstrap_dir`。如果 `sha256sum` 与 `shasum` 都不存在,必须停止,不能跳过校验。
## 步骤 3:验收安装结果
步骤 2 的平台引导是唯一通用安装入口。它会:
1. 检查系统 Node;缺失或版本不兼容时,根据当前操作系统和 CPU 架构选择私有 Node;
2. 按“阿里云精确版本 → npmmirror 精确版本 → Node 官方精确版本”的顺序下载 Node;项目安装引导和发布物则优先使用国内 Gitea 静态发布源,再回退到自建 HTTPS 下载源和其他已配置镜像。网络或 HTTP 下载失败才切换来源,任一已下载文件的签名或 SHA-256 不匹配都会立即终止;
3. 把私有 Node 放在插件自己的当前用户数据目录,不修改系统 PATH,不要求管理员权限;
4. 下载并校验首次安装器和发布公钥,再由安装器验证 Ed25519 清单签名与全部客户端发布物;下载源不是信任根,备用源不能绕过签名或哈希;
5. 返回一份 JSON 安装结果。
安装器会在稳定的当前用户数据目录安装客户端与 Skill,不会全局安装 npm 包,也不会修改 Agent 私有配置。保留完整 JSON 结果,后续只使用其中的真实字段,不要猜路径。
安装结果至少必须包含:
- `ok: true`、`status: "installed"` 和 `version`;
- `cliPath`、`bridgePath`、`skillPath`;
- `loginCommand`;
- `mcpConfig.mcpServers.dingtalk-approval`;
- `postInstall`。
- `nodeRuntime`,其中 `managed: true` 表示正在使用插件私有 Node。
Windows 的 `bridgePath` 和 `mcpConfig...command` 正常应以 `dingtalk-approval-bridge.cmd` 结尾。路径中可能包含空格;保留完整字符串,不要拆分,不要去掉 `.cmd`,不要改为 `node`、`npx` 或远程 URL。
## 步骤 4:安装 Skill 并注册 MCP
1. 按当前 Agent 的官方方式安装 `skillPath` 指向的整个目录,而不是只复制 `SKILL.md`。确认目录中同时存在 `SKILL.md`、`references/create-approval.md` 和 `references/local-drafts.md`。
2. 使用 `mcpConfig` 只新增或替换名称精确为 `dingtalk-approval` 的连接器。安装器本身不会猜测或修改 Agent 的私有配置。
3. 如果 Agent 接受完整 MCP JSON,原样使用整个 `mcpConfig`;如果界面只接受单个服务器配置,原样使用 `mcpConfig.mcpServers.dingtalk-approval`。
4. 该连接器必须是本地 `stdio`,`command` 必须是返回的本地 `bridgePath`,`args` 必须为空数组。Windows 中必须保留 JSON 已正确转义的反斜杠。
5. 不要把 `{{GATEWAY_URL}}` 或 `https://approval.justconn.top/mcp` 作为 MCP URL、command 或参数;Bridge 会从已签名安装状态取得网关地址。
6. 不要添加 `--url`、企业凭证、用户 ID、额外环境变量或 shell 包装器。
正确配置的形态由安装器返回,语义如下;示例路径不能代替真实返回值:
```json
{
"mcpServers": {
"dingtalk-approval": {
"type": "stdio",
"command": "<安装器返回的本地 bridgePath;Windows 为 .cmd>",
"args": []
}
}
}
```
## 步骤 5:处理首次登录状态
安装器已经主动尝试准备登录。读取返回的 `postInstall` 及其 `status`,不得等到用户第一次查询审批:
- `authorization_required`:在完成本地 Skill/MCP 配置的同一轮回复中,把 `postInstall.authChallenge.directUrl` 作为完整、可点击的 URL 原样发给用户;不得只说“已生成”或“已推送”。同时说明链接有有效期,需由用户本人核对授权页面并确认。
- `authenticated`:已有登录可复用,不需要再次让用户授权,继续步骤 6 和步骤 7。
- `unavailable`:客户端安装仍然有效。先完成步骤 4;连接器加载后调用 `approval_login` 重试。不要删除会话、不要重装。
保存 `loginCommand.command` 和 `loginCommand.args`。如果首次链接过期且 MCP 尚未加载,按该对象原样执行命令;Windows PowerShell 的通用执行方式是:
```powershell
$dingLoginJson = & $dingInstall.loginCommand.command @($dingInstall.loginCommand.args)
$dingLogin = $dingLoginJson | ConvertFrom-Json
$dingLogin | ConvertTo-Json -Depth 20
```
把新结果中的 `authChallenge.directUrl` 原样展示。该命令只检查登录或生成新链接,不下载发布物、不修改 Agent 配置。MCP 已加载时则直接重新调用 `approval_login`。登录链接过期时绝不能重新安装。
## 步骤 6:信任并加载连接器
1. 如果当前 Agent 要求信任本地连接器,按其官方界面或命令确认名称为 `dingtalk-approval` 的连接器。
2. 如果不能热加载,完整退出并重新启动 Agent,或新建一个确定会重新读取 MCP 配置的会话;只刷新聊天内容通常不够。
3. 重启后确认能发现 `approval_login`、`approval_list_todos` 等钉钉审批工具。当前版本应发现 13 个工具。
4. 若连接器进程退出、显示 302 或无法启动,先执行步骤 9 的故障排查,不要把连接器改成远程 HTTP MCP。
## 步骤 7:确认登录并验证两个审批来源
用户完成网页授权后:
1. 调用 `approval_login`。工具不会通过其他消息通道自动推送链接;如果响应仍给出 URL,必须把 `content.text` 中的完整登录 URL 原样写入当前回复。
2. 登录成功后,按 `postInstall.verifyTool` 调用一次只读的 `approval_list_todos`,即 `source="all"`、空搜索、`limit=1`。
3. 检查结果中的 `sourceStatus`:`dingtalk.status` 和 `xft.status` 都必须是 `ok`。`disabled`、`auth_required`、`unavailable` 或缺少任一来源都不算安装验证完成。
4. 验证期间只读取最多一条待办,不调用任何写工具。
5. 成功响应包含 `onboarding.firstRun=true` 时,把其中的简短示例和安全提示向用户展示一次,不要自动执行示例。
## 步骤 8:向用户报告结果
最终只需清楚报告:已安装的版本、Skill 与 MCP 已加载、登录是否成功、钉钉 OA 与薪福通是否都通过只读验证。可以给出一次性使用示例。不要向用户倾倒安装 JSON、内部路径、Token、审批引用或诊断细节,除非用户正在排障。
安装阶段不得处理审批,也不得在登录和双来源验证完成前声称“已可使用”。
## 步骤 9:常见故障排查
按顺序排查,不要跳到重装:
1. **显示 302 或启动后立即退出**:检查连接器是否被错误配置成 `{{GATEWAY_URL}}` 或其他 HTTP URL。正确配置必须是 `type: "stdio"`,`command` 为本机 `dingtalk-approval-bridge.cmd`,`args: []`。重新复制安装结果中的 `mcpConfig`。
2. **路径不存在或 Node 升级后失效**:不要引用 Node/NVM 的版本目录。执行安装结果中的 `cliPath`,或运行 `dingtalk-approval print-config --format mcp-json` 重新取得稳定配置。
3. **Bridge 仍无法启动**:执行 `<cliPath> doctor --json`。只有所有 `checks` 都为 `ok: true` 才继续;把失败检查和错误原文报告给维护者,不要提供 Token 或会话文件。
4. **提示找不到 npm-cli.js 或 Node 运行时损坏**:重新执行步骤 2 中已经过哈希校验的平台引导,让它修复插件私有 Node;不要安装全局 npm。
5. **路径包含空格**:不要手写命令行字符串。把安装器返回的整个 `mcpConfig` 作为 JSON 对象交给 Agent;在 PowerShell 中执行 CLI 时用调用运算符 `&` 和独立参数。
6. **连接器一直未出现**:确认已信任本地连接器并完整重启 Agent。不要通过反复重装刷新连接器。
7. **授权链接过期**:MCP 已加载就再次调用 `approval_login`;否则执行保存的 `loginCommand`。不要重装。
8. **Linux/macOS 缺少下载或校验命令**:必须先具备 `curl` 或 `wget`,以及 `sha256sum` 或 `shasum`;不能绕过 SHA-256 校验。系统 `tar` 必须支持 gzip 归档。
9. **安装长时间无最终 JSON或被宿主终止**:查看 stderr 中最后一条 `[dingtalk-approval]` 阶段信息。单个下载超过 90 秒或连续 20 秒低速应自动失败,而不是继续等待;不要改用内部安装器,也不要并发重试。原进程确认已经退出后,可重新执行同一平台引导;它会识别已经死亡的安装进程、清理残留 staging 并安全续装。若明确提示另一个安装仍在运行,应等待该进程结束。
## 更新
更新不需要重新下载首次安装器。使用上次安装结果中的 `cliPath`:
Windows PowerShell:
```powershell
$dingUpdateJson = & $dingInstall.cliPath update --json
$dingUpdate = $dingUpdateJson | ConvertFrom-Json
$dingUpdate | ConvertTo-Json -Depth 20
```
Linux / macOS:
```text
<cliPath> update --json
```
更新会复用已固定的签名清单地址和公钥并保留 OAuth 会话。更新成功后,重新使用返回的 `mcpConfig` 核对同名连接器,并重新连接 MCP;必要时完整重启 Agent。然后重复步骤 7 的登录确认和双来源只读验证。
## 卸载
1. 按当前 Agent 的官方方式删除名称精确为 `dingtalk-approval` 的 MCP/连接器条目。
2. 执行安装结果中的 `cliPath uninstall --yes --json`;Windows PowerShell 可运行:
```powershell
& $dingInstall.cliPath uninstall --yes --json
```
3. 确认返回 `uninstalled` 或 `cleanup_scheduled`。后者表示当前 CLI 退出后完成自清理。
卸载默认清除客户端运行时、Skill、安装记录和 OAuth 会话。不要手工递归删除未知目录。
授权页面会展示请求客户端、回调域名、权限范围或设备授权码。必须由用户本人核对并确认,不得替用户自动提交 consent。网关短暂不可用时保留现有登录状态并稍后重试,不要删除会话文件或主动要求用户重新授权。