从「只能查」到「自动做」:给华为云成长中心 MCP 扩展加上自动完成任务能力
背景:一个能签到但不能干活的工具
华为云开发者成长中心(developer.huaweicloud.com/grow)是开发者的积分成长平台,每日签到、做任务、攒积分、换奖品。社区里已经有一个开源的 Chrome 扩展项目 [developer-grow-mcp-extension],它能把签到、积分查询、任务列表这些操作封装成 MCP 工具,让 AI Agent 通过标准协议调用。
但它有个明显的短板:只能查,不能做。
hwc_get_tasks能列出所有任务和状态,但看到"未完成"的任务,你还得手动去网页上点- 没有领取奖励的工具——后端已经检测到你完成了动作,但"领取积分"这一步还是得手动
agent命令只做签到,签到完就 return 了,不管任务
用户的一句话需求很直接:“能把它改成可以自动完成成长任务吗?”
项目架构:三层中继
动手之前先搞清楚现有项目怎么跑的。这个项目不是普通的 Web 应用,而是一个 Chrome 扩展 + Node.js Bridge 的三层中继架构:
CLI / AI Agent ──stdio──▶ Node.js Bridge ──WebSocket──▶ Chrome Extension ──HTTP──▶ 华为云 API
(hwc-grow) (端口 9876) (background.js) (devdata.huaweicloud.com)
为什么要这么绕?因为华为云成长中心的 API 需要 IAM 认证和 CSRF Token,这些信息只在你登录了开发者中心的 Chrome 浏览器里才有。所以工具的执行路径是:
- CLI 或 AI Agent 发出 MCP 请求(JSON-RPC over stdio)
- Node.js Bridge 把 stdio 转成 WebSocket,转发给 Chrome 扩展
- Chrome 扩展的 Service Worker 在已登录的页面上下文中发 HTTP 请求,带上认证信息
- 响应原路返回
关键洞察:工具代码运行在 Chrome 扩展的 Service Worker 上下文中,这意味着 chrome.tabs.create 等 Chrome Extension API 是可用的。这为"自动打开任务页面"提供了可能。
改造方案:两个新工具
分析任务列表 API 返回的数据,发现成长任务分两类:
- 领取奖励型:后端已检测到你做了某个动作(比如连续签到 7 天),你只需要点"领取"按钮就能拿积分。这种纯 API 调用就能搞定。
- 真实动作型:需要你实际去做某件事(比如"开通 CodeArts 服务"),光调 API 不够,得真的去访问那个页面。
针对这两类,设计了两个新工具:
hwc_receive_task:领取任务奖励
问题在于:领取 API 的端点没有文档。现有代码只实现了"查任务列表"(query-mission-list-by-condition),领取端点是什么全靠猜。
解决方案是穷举策略:
4 个候选端点 × 3 种字段名组合 = 12 次尝试
候选端点(按命名规律猜测):
/growth/mission/receive-mission/growth/mission/claim-mission/growth/mission/get-mission-reward/growth/mission/finish-mission
每种端点再尝试三种 body 字段名:task_id、mission_id、id。
首个成功响应即返回;全部失败则返回所有 12 次尝试的详情(HTTP 状态码 + 响应体),方便调试定位正确端点。
这个设计是诚实的——我不假装知道正确端点,而是把探索过程自动化,并把失败信息完整暴露给用户。
hwc_complete_tasks:批量自动完成
这个工具做三件事:
- 查询所有 pending 任务
- 对有
jumpUrl的任务,用chrome.tabs.create在后台自动打开对应页面(触发后端检测"你做了这个动作") - 等待 5 秒后逐个尝试领取奖励
// 核心逻辑简化版
for (const task of pendingTasks) {
if (task.jumpUrl) {
const tab = await chrome.tabs.create({ url: task.jumpUrl, active: false });
await sleep(delay); // 等后端注册动作
await chrome.tabs.remove(tab.id);
}
await receiveTask(task.id); // 尝试领取
}
无法自动完成的任务标记为"需手动",但至少帮你打开了链接。
实现细节
改动清单
9 个文件,439 行新增,107 行删除:
| 文件 | 改动 | 说明 |
|---|---|---|
tools/task-receive.js |
新增 101 行 | 领取任务奖励工具 |
tools/task-complete.js |
新增 165 行 | 批量完成任务工具 |
tools/tasks.js |
+22 行 | 返回完整 raw 字段,暴露 jumpUrl/receiveUrl/missionCode |
tools/index.js |
+6 行 | 注册两个新工具 |
manifest.json |
+7 行 | 增加 tabs 权限,版本升至 1.1.0 |
agent.mjs |
+97/-30 行 | 签到后增加"自动完成任务"阶段 |
cli.mjs |
+130/-40 行 | 新增 complete 子命令 |
README.md |
+16 行 | 更新能力边界与文档 |
package.json |
+2/-1 行 | 版本号更新 |
tasks.js:暴露原始字段
原来的 hwc_get_tasks 只返回精简字段,丢掉了 jump_url、receive_url 等关键信息。改造后在每个任务对象中增加 raw 字段,保留 API 返回的完整数据,并尝试提取几个可能存在的 URL 字段:
task.raw = taskItem; // 保留原始完整数据
task.jumpUrl = taskItem.jump_url || taskItem.jumpUrl || taskItem.url || '';
task.receiveUrl = taskItem.receive_url || taskItem.receiveUrl || '';
task.missionCode = taskItem.mission_code || taskItem.missionCode || '';
agent.mjs:不再签到完就 return
原来的流程是:检查签到状态 → 已签到就 return,未签到就签到 → return。改造后,签到完不 return,继续往下走任务完成阶段:
检查签到 → 签到 → 自动完成任务 → 汇总结果
cli.mjs:新增 complete 子命令
hwc-grow complete # 单独执行任务完成
hwc-grow complete --delay=10 # 自定义等待秒数
hwc-grow agent # 一键完整流程(签到 + 任务完成)
踩坑记录
坑 1:简介字数计算方式不一致
本地的 CJK 计数脚本说 43 个中文字符、合格。但 API 返回 400,说总长度 58 超限。API 计的是总字符数(中文 + 英文 + 标点 + 空格),不是中文字符数。 改成 46 总字符后通过。
教训:本地校验规则要和 API 一致,否则白跑一趟。
坑 2:GitCode 推送权限
git push 报 403:You are not allowed to push code to this project。当前登录账号不是仓库所有者。需要 fork 后推送。但 gitcode-oauth 工具只支持 get 不支持 post,得用 curl 直接调 API。
教训:fork 是处理没有推送权限的标准方案,但要准备好绕过工具限制直接调 API。
坑 3:领取 API 端点未知
这是设计层面的问题。没有文档,不知道领取任务奖励的正确端点。选择了穷举策略——4 端点 × 3 字段名 = 12 次尝试。诚实地说,这个方案能不能成功取决于猜测的端点里有没有正确的那个。如果都不对,工具会返回所有 12 次尝试的详情,用户可以从中分析出正确端点。
教训:面对未知 API,与其假装知道,不如把探索过程自动化并暴露失败信息。
反思
做得好的
- 先分析后动手:没有上来就写代码,先读懂三层架构,确认
chrome.tabs.create可用,再设计方案 - 诚实标注不确定性:领取 API 端点是猜的,代码注释和 README 都明确标注了这一点
- 渐进式改造:在现有架构上增加新工具,不重构不重写,改动最小化
可以更好的
- 领取端点的穷举策略有点暴力。更优的做法是抓包看前端实际调了哪个端点,但当前环境没有浏览器开发者工具
task-complete.js的等待时间(5 秒)是硬编码的。某些任务可能需要更长时间让后端注册动作- 没有写测试。MCP 工具的测试需要 mock Chrome 扩展环境,成本不低,但至少应该有单元测试
关于 AI 辅助开发的感受
整个过程中,AI 扮演了一个"能读代码、能写代码、能调 API、能生成图片、能发布作品"的全栈角色。但它最重要的品质不是"什么都会",而是知道边界在哪里:
- 不知道 API 端点就说不知道,用穷举策略并暴露失败信息
- 不假装知道某个端点能工作
- 发布前过门禁,不跳过
这种诚实比"看起来什么都会"有价值得多。
- 点赞
- 收藏
- 关注作者
评论(0)