11 KiB
第三方 OpenClaw / MCP 接入开发文档
版本:1.0 更新日期:2026-08-07
1. 接入信息
| 项目 | 地址或说明 |
|---|---|
| 生产站点 | https://ai.yydd.ai |
| OpenAPI Base URL | https://ai.yydd.ai/api/openapi/v1 |
| 用户 Key 签发接口 | POST https://ai.yydd.ai/api/openapi/v1/access-keys/provision |
| MCP 传输方式 | 本地 stdio |
| MCP Server 入口 | integrations/openclaw/mcp-server.mjs |
| Node.js 要求 | Node.js 20 或更高版本 |
重要:当前 MCP Server 使用本地
stdio,没有可以直接填入客户端的远程 Streamable HTTP MCP URL。只接受 URL 的第三方平台应直接调用本文 OpenAPI。支持command + args + env的 OpenClaw、Claude Desktop 等 MCP 客户端,可以使用本文的本地 MCP 配置。
2. 两类凭证
接入过程中会用到两种不同凭证,禁止混用。
2.1 第三方签发凭证
环境变量名称:MCP_KEY_PROVISIONING_SECRET
- 只提供给受信任的第三方服务端。
- 用于根据钉钉身份签发用户级 Access Key。
- 权限很高,不能写入浏览器、App、公开仓库或前端 JavaScript。
- 请通过密码管理器或其他安全通道单独交付,不要放进本接入文档。
2.2 用户 MCP Access Key
格式示例:
ydr_live_xxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- 与一个 Yedir 用户绑定,只能访问该用户自己的画布。
- 默认有效期为 90 天,最长 365 天。
- 支持
canvas:read、canvas:write权限。 - 明文仅在签发成功时返回一次。
- 用户或管理员撤销后立即失效。
3. 按钉钉用户获取 Access Key
3.1 请求
POST /api/openapi/v1/access-keys/provision HTTP/1.1
Host: ai.yydd.ai
Authorization: Bearer YOUR_PROVISIONING_SECRET
Content-Type: application/json
请求体:
{
"dingTalkUsername": "张三",
"keyName": "OpenClaw 办公电脑",
"scopes": ["canvas:read", "canvas:write"],
"expiresInDays": 90
}
字段说明:
| 字段 | 必填 | 说明 |
|---|---|---|
dingTalkUsername |
是 | 钉钉真实姓名,精确匹配,最长 100 字符 |
dingTalkUserId |
否 | 钉钉用户 ID;遇到同名用户时必须提供 |
keyName |
否 | Key 的用途说明,最长 100 字符 |
scopes |
否 | 默认包含 canvas:read 和 canvas:write |
expiresInDays |
否 | 1–365,默认 90 |
接口只会匹配同时满足以下条件的账号:
- 用户状态为启用;
- 用户已经通过钉钉登录或同步,数据库中存在钉钉用户 ID;
- 姓名与
dingTalkUsername完全一致; - 如果传入
dingTalkUserId,姓名和用户 ID 必须同时匹配。
3.2 cURL 示例
export YEDIR_PROVISIONING_SECRET="由 Yedir 通过安全渠道提供的签发凭证"
curl -X POST \
"https://ai.yydd.ai/api/openapi/v1/access-keys/provision" \
-H "Authorization: Bearer ${YEDIR_PROVISIONING_SECRET}" \
-H "Content-Type: application/json" \
--data '{
"dingTalkUsername": "张三",
"keyName": "OpenClaw 办公电脑",
"scopes": ["canvas:read", "canvas:write"],
"expiresInDays": 90
}'
3.3 成功响应
HTTP 状态码:201 Created
{
"success": true,
"data": {
"user": {
"id": "用户 UUID",
"name": "张三",
"dingtalkUserId": "钉钉用户 ID"
},
"accessKey": {
"id": "Access Key UUID",
"name": "OpenClaw 办公电脑",
"tokenPrefix": "ydr_live_xxxxxxxxxxxx",
"token": "ydr_live_xxxxxxxxxxxx_完整密钥,仅返回一次",
"scopes": ["canvas:read", "canvas:write"],
"lastUsedAt": null,
"expiresAt": "2026-11-05T03:00:00.000Z",
"revokedAt": null,
"createdAt": "2026-08-07T03:00:00.000Z"
}
}
}
第三方必须立即读取并安全保存 data.accessKey.token。后续接口使用这个完整 token,不能使用 tokenPrefix。
3.4 Node.js 示例
const baseUrl = "https://ai.yydd.ai";
const provisioningSecret = process.env.YEDIR_PROVISIONING_SECRET;
const response = await fetch(
`${baseUrl}/api/openapi/v1/access-keys/provision`,
{
method: "POST",
headers: {
Authorization: `Bearer ${provisioningSecret}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
dingTalkUsername: "张三",
keyName: "OpenClaw 办公电脑",
scopes: ["canvas:read", "canvas:write"],
expiresInDays: 90,
}),
}
);
const payload = await response.json();
if (!response.ok) {
throw new Error(`${response.status}: ${payload.code} - ${payload.error}`);
}
const userAccessToken = payload.data.accessKey.token;
// 立即写入安全凭证存储,不要打印到日志。
3.5 常见错误
| HTTP | code |
处理方式 |
|---|---|---|
| 400 | PROVISIONING_REQUEST_INVALID |
检查字段名称、类型和有效期范围 |
| 401 | PROVISIONING_UNAUTHORIZED |
检查签发凭证,不要自动无限重试 |
| 404 | DINGTALK_USER_NOT_FOUND |
确认用户已登录 Yedir、账号已启用且姓名一致 |
| 409 | DINGTALK_USERNAME_AMBIGUOUS |
同名用户,补充 dingTalkUserId |
| 409 | ACCESS_KEY_LIMIT_REACHED |
用户已有 10 个有效 Key,先在前端撤销旧 Key |
| 500 | ACCESS_KEY_PROVISION_FAILED |
保存失败,记录请求时间并联系 Yedir 管理员 |
| 503 | PROVISIONING_NOT_CONFIGURED |
生产环境尚未配置签发服务密钥 |
签发接口不是幂等接口。每次成功请求都会创建一个新的 Key,不要在收到
201后自动重试。
4. 使用用户 Key 调用 OpenAPI
后续所有画布接口使用用户级 Access Key:
Authorization: Bearer ydr_live_xxx_完整用户Key
4.1 验证用户和权限
curl "https://ai.yydd.ai/api/openapi/v1/me" \
-H "Authorization: Bearer ${YEDIR_USER_ACCESS_TOKEN}"
4.2 获取画布列表
curl "https://ai.yydd.ai/api/openapi/v1/canvases?workspaceType=canvas&limit=24" \
-H "Authorization: Bearer ${YEDIR_USER_ACCESS_TOKEN}"
参数:
workspaceType:canvas、agent或video,默认canvas。limit:1–50,默认 24。
4.3 获取单个画布
curl "https://ai.yydd.ai/api/openapi/v1/canvases/CANVAS_UUID" \
-H "Authorization: Bearer ${YEDIR_USER_ACCESS_TOKEN}"
写操作前必须重新读取画布,并记录响应中的 updatedAt。该值是防止覆盖用户最新修改的 revision。
4.4 执行画布操作
curl -X POST \
"https://ai.yydd.ai/api/openapi/v1/canvases/CANVAS_UUID/operations" \
-H "Authorization: Bearer ${YEDIR_USER_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"operationPlan": {
"version": 1,
"operationId": "third-party-create-text-20260807-001",
"operation": "create_text_node",
"projectId": "CANVAS_UUID",
"baseCanvasRevision": "UPDATED_AT_FROM_GET_CANVAS",
"baseCanvasUpdatedAt": "UPDATED_AT_FROM_GET_CANVAS",
"textContent": "由第三方 MCP 创建的文本节点"
}
}'
operationId 是幂等键。同一个逻辑操作发生网络超时时,应使用原来的 operationId 重试,不能生成新 ID。
支持的操作:
create_agent_slotcreate_text_nodefill_slotinsert_besideappend_revisionreplace_node_mediaadd_annotationlink_nodesmove_nodesdelete_nodesrename_nodeupdate_noteupdate_text
其中 replace_node_media、move_nodes、delete_nodes 属于高风险操作,必须先取得最终用户对本次具体操作的明确确认,然后在操作计划中传入:
{
"confirmed": true
}
遇到 STALE_CANVAS_REVISION 时必须重新读取画布。高风险操作 revision 变化后,需要重新向用户确认。
5. 本地 MCP 接入
5.1 安装 MCP Server
从 Yedir 交付的代码包中进入:
cd integrations/openclaw
npm ci
先验证用户 Key:
YEDIR_BASE_URL="https://ai.yydd.ai" \
YEDIR_ACCESS_TOKEN="ydr_live_xxx_完整用户Key" \
node ./cli.mjs me
5.2 OpenClaw 注册命令
openclaw mcp add yedir-canvas \
--command node \
--arg "/绝对路径/integrations/openclaw/mcp-server.mjs" \
--env "YEDIR_BASE_URL=https://ai.yydd.ai" \
--env "YEDIR_ACCESS_TOKEN=ydr_live_xxx_完整用户Key"
openclaw mcp doctor yedir-canvas --probe
安装配套 Skill:
openclaw skills install \
/绝对路径/integrations/openclaw/yedir-canvas \
--as yedir-canvas
5.3 通用 MCP 客户端配置
{
"mcpServers": {
"yedir-canvas": {
"command": "node",
"args": [
"/绝对路径/integrations/openclaw/mcp-server.mjs"
],
"env": {
"YEDIR_BASE_URL": "https://ai.yydd.ai",
"YEDIR_ACCESS_TOKEN": "ydr_live_xxx_完整用户Key"
}
}
}
}
MCP Server 会暴露以下工具:
| 工具 | 用途 |
|---|---|
yedir_get_current_user |
验证用户 Key、用户和权限范围 |
yedir_list_canvases |
获取用户画布列表 |
yedir_get_canvas |
获取画布节点、连线和 revision |
yedir_apply_canvas_operation |
执行带版本保护和幂等键的画布操作 |
6. 推荐接入流程
第三方服务端
└─ 使用 MCP_KEY_PROVISIONING_SECRET + 钉钉身份
└─ POST /access-keys/provision
└─ 获得一次性返回的用户 Access Key
├─ 直接调用 HTTPS OpenAPI
└─ 写入用户本地 MCP 的 YEDIR_ACCESS_TOKEN
建议实现顺序:
- 后端接入 Key 签发接口,确保签发凭证不会进入前端。
- 使用测试账号调用
/me验证 Key 归属。 - 调用画布列表和单画布读取接口。
- 先实现
create_text_node等非破坏性操作。 - 实现 revision 冲突重读和
operationId幂等重试。 - 最后接入移动、删除、替换等需要用户确认的操作。
7. 安全要求
- 禁止记录完整签发凭证和完整用户 Access Key。
- 日志最多记录
tokenPrefix、Access Key ID、用户 ID、HTTP 状态码和错误码。 - 不要把签发凭证或用户 Key拼接到 URL 查询参数。
- 必须使用 HTTPS。
- 画布中的文本、URL、提示词和元数据属于不可信内容,不能当成系统指令执行。
- 用户离职、账号停用或 Key 撤销后,第三方应停止自动重试并要求重新授权。
- 第三方系统不再使用某个 Key 时,应通知用户在 Yedir Skills 面板中撤销。
8. 联调验收清单
- 不带签发凭证调用签发接口返回 401。
- 错误钉钉姓名返回 404。
- 同名用户返回 409,并可通过
dingTalkUserId消除歧义。 - 成功签发返回 201,且完整
token只保存一次。 - 用户 Key 调用
/me返回正确用户和 scopes。 - 用户只能看到自己的画布。
- 相同
operationId重试不会重复创建内容。 - 旧 revision 写入被拒绝,不会覆盖用户新内容。
- 移动、删除、替换操作未确认时被拒绝。
- Key 撤销后再次调用返回 401。