选择接入方式
Connector 只是数据接入方式之一,Mini App 不依赖它;没有对应的 Connector,也不代表无法获取数据。用户明确指定了方式且可以验证时,就采用该方式;否则根据可用能力、鉴权、运行环境和所需操作选择。
先验证,再开发
写包之前,对每个数据源用选定的方式做一次只读查询,确认授权、真实参数、返回字段和类型,取得一条有代表性的数据,或一个真实的空结果,再按观察到的结构编写解析逻辑。Agent 终端里查询成功,不代表 Mini App 运行时里也能成功。CLI、API、文件访问还要在 Node 服务里实际跑通一次。
统一工具入口
Node 服务可以用context.tool 列出和调用宿主已挂载的 MCP 工具及用户连接的 Connector。它不提供 Agent 内置的文件、Shell 或浏览器工具;Mini App 自己实现的托管 MCP 应直接复用本地业务函数。方法签名、清单与结果类型、取消和超时见 Node 工具 API 参考;页面提前申请授权见 tool.request 参考。miniapp/miniapp.json
context.capabilities?.has('tool') 检查宿主是否实现接口,不代表 manifest 已声明或用户允许调用。用户关闭工具权限后,context.tool 仍在,新调用会以 TOOL_NOT_PERMITTED 拒绝。- 从
list()的结果取name,按kind、server/provider和tool匹配,不拼接工具名。list()返回{ tools, partial };partial: true表示清单不完整,可能有来源不可用或部分工具因元数据问题被省略;已列出的工具仍按当前权限调用。 permission是当时的allow、ask或deny;每次调用都会重新判定。规则采用用户的全局工具权限和权限模式,不继承某个 Agent 或会话的规则;宿主内置工具沿用原有放行行为,这条调用链不会执行 Agent 的工具 Hook。- 需要确认时,由宿主弹框提供「允许一次」「始终允许」「拒绝」。只有用户在宿主框中选择「始终允许」才会写入全局规则,Mini App 不能代答。无人可确认时返回
TOOL_APPROVAL_REQUIRED。 - MCP 结果包含
kind: 'mcp'、isError和content;isError: true是工具报告业务失败,Promise 仍正常返回。Connector 结果包含kind: 'connector'和原始value。写操作遇到unknown_after_dispatch时,先核对业务状态,不要盲目重试。 - Node 的
context.tool.request(names)和页面的window.mcode.miniapp.tool.request(names)可提前请求授权;需探测tool.request能力。页面调用必须来自用户手势、每次最多 10 个工具,并要求 Node 服务正在运行。页面只请求授权,工具的列出和调用仍在 Node;把 Node 获取的运行时工具名通过业务接口传给页面。
Host Connector
Node 服务通过context.hostConnector 使用用户已授权的连接器。访问第三方服务时,用的是用户授权给 MiniMax Code 的账号,Mini App 自己不保存任何凭证。完整的 list、call、工具描述与错误结构见 Host Connector API 参考。miniapp/miniapp.json
- 只声明运行时真正需要、并且已经验证过的 provider。
list()随时可用,返回允许的工具清单和输入 schema。call()只在服务激活后、在请求处理里调用,不要在start里调。- 不要自己构造或保存
toolRef,也不要发给页面。进程重启或遇到过期引用时,重新list()。 - 用户退出登录时,工具清单和授权引用会被撤销;同一账号重新登录后再
list()即可恢复,不用重新发布。换成其他账号后,旧引用永久失效。
错误处理
按code 判断,不要依赖跨进程的 instanceof。disposition 说明请求有没有发出去:not_dispatched、provider_reported、unknown_after_dispatch。遇到 unknown_after_dispatch,先读业务状态核对,再决定写操作要不要重试。解析返回值
result.value 是第三方服务的原始结果,宿主不做归一化。Skill 提供的 host-connector-value.mjs 处理常见的「单个 text 块」包装,其他结构原样返回。解析出零条数据时,只有服务明确返回空结果才算成功;源数据存在却无法解析时,应按解析错误处理,不要显示为「暂无数据」。状态与持久化
- 运行时数据写在
context.dataDir,不要写进工作区或载荷。 - 页面、MCP 调用和 Agent 操作的所有写入都走同一个 Node 业务服务。先将状态写入磁盘,再推送 SSE 或 WebSocket 事件,这样每个打开的页面都能刷新到最新数据。
context.dataDir,不要只在 dispose() 中保存。服务重新启动后应读取已保存的数据继续工作。