交出密钥与在手机上做选择
两件事同源:AI 需要你输入点什么,而聊天框是最糟的输入位置 —— 密码会留在对话记录里, 选择题会变成一屏读不完的文字。
前置条件
- 已装好
mp,mp doctor四项全ok - 手机能打开
trycloudflare.com的链接
flowchart LR
A[AI 需要密钥] -->|mp secret ask| B[手机上的表单]
B -->|你填写| C["值只在守护进程内存里"]
C -->|mp secret run| D["命令带着值执行<br/>输出回来时已脱敏"]
C -.->|AI 读不到| E["mp secret status<br/>只给字段名与指纹"]
把密钥交给 AI 用的步骤
起点:终端在项目目录,AI 已经告诉你它要跑哪条命令。
- 开一个表单:
mp secret ask --purpose "部署需要云厂商 AccessKey" --field AK --field SK --use "npm run deploy"。 - 把打印出来的链接发到手机,填好提交。每条
--use声明的命令都要你在手机上逐条勾选批准。 - 执行
mp secret wait,等手机提交。 - 执行
mp secret run -- npm run deploy,值以环境变量注入,输出回来时已脱敏。 - 用完执行
mp secret forget --all。- 预期:打印
forgot 1 secret slot(s),值从内存中消失(证据 E011)。
- 预期:打印
mp secret status 任何时候都只列字段名、已批准的用途与剩余时间,不打印值。
值默认在内存里保留 120 分钟,表单链接默认开放 30 分钟。
把选择题变成页面的步骤
起点:有一个需要你拍板的选择,且选项多于两个或需要对比。
- 写一个自包含的 HTML 文件:单文件、不引任何外部资源、不写
<form action>。 - 给每个控件加
name,给提交按钮加data-mp-submit;再加一个带data-mp-disposition="needs_clarification"的按钮,好让你能回答”问题本身不对”。 - 执行
mp interaction ask --purpose "部署环境二选一" --html ask-env.html。 - 把链接发到手机,做完选择提交。
- 执行
mp interaction wait取答案,它以 JSON 打印。- 预期:手机还没提交时打印
i-xxxxxx: still waiting — the link is open for 30 more min.并以退出码 0 结束,超时不算失败(证据 E011)。
- 预期:手机还没提交时打印
页面在发链接之前会被检查,不合规直接拒绝出链接:
$ mp interaction ask --purpose "部署环境二选一" --html ask-env.html
ask-env.html does not meet the interaction page contract:
- nothing carries `data-mp-submit`, so the page has no way to submit
这条拒绝是真实输出(证据 E011)。完整的页面合同见
docs/superpowers/specs/2026-09-16-interaction-page-contract.md。
手机上提交不成功时
隧道会断。cloudflared 掉一次线、二十多秒后才重新注册,正好落在这段空窗里的提交就到不了 这台机器:回来的不是这台机器的 JSON,而是 Cloudflare 自己的一页错误。页面从前只会说一句 “没有提交成功,再试一次”,而那一页答案还在手机屏幕上,人却只剩”重新要一条链接、再填一遍” 这一条路。
现在有两道兜底,都在页面里,你和手机那头都不用多做什么:
- 页面自己重试。 没送到的提交会在半分钟内自动重发五次(1.2s、2.5s、5s、10s、18s)。 一次作答按提交编号去重,重连之后送达的那一次拿回的是同一张回执,不会变成第二个答案; 答完的链接也会多留一会儿,专门等这种迟到的重试。掉线二十秒这种情况,手机上只会先看到 “正在自动重试”,再看到回执。
-
改用文字回传。 重试完还是送不出去,或者这台机器明确说不收,页面会把答案变成一段 文字,配一个复制按钮:
【mp interaction 回传 · i-20387a · 第 1 版】 手机上没能把答案交回你的机器。下面就是我的回答,按它继续,不用再发新链接。 - 文档形态:整套镜像(mirror) - 备注:先做中文 mp-answer: {"id":"i-20387a","revision":1,"disposition":"answered","reason":null,"answers":{"doc":"mirror","note":"先做中文"}} 收到后收个尾:mp interaction close --id i-20387a把这段贴回和 AI 的对话里发出去,就等于在这一页上答过了。前几行给人读,
mp-answer:那一行给 agent 读。Agent 收到后照它继续,并执行mp interaction close --id <id>收尾, 不该再发一条新链接让人重填一遍。
页面也可以自己给这段话加个入口:MP.handoff() 返回这段文本,MP.rescue() 直接把面板
打开。
同时开着多个时
secret 与 interaction 都按随机 id 占槽位。只剩一个未关闭时,wait / forget /
close 不必带 --id;有多个时它们同样拒绝猜测,打印
several interactions are open (i-2b944d, i-f1ed0b); pass --id.。
验证
mp secret status 列出槽位、字段名与剩余时间,且不含任何值;
mp interaction status 列出未关闭的问题、阶段与已填写进度。两个列表在你执行
forget --all / close --all 之后都应为空。
失败时
链接发不出来,多半卡在隧道而不是命令本身,处置与预览相同,见排错。
页面被拒绝时,命令会把不合规的条目逐条列出来,照着改再跑一次即可 —— 页面不上线, 不会有半成品链接流出去。