Skip to main content
入口、context、Connector 与工具的完整契约见 Node API 参考,会话方法见 Agent API 参考。

入口契约

  • 入口是一个导出 start(context) 的 ES 模块。HTTP 监听开始接受连接、所有声明的路由都安装好之后,再让 start 返回。这就是就绪信号,不需要自己写健康检查接口。
  • start 里只做路由注册和启动监听,不要同步拉业务数据,业务数据在请求里按需加载。
  • 返回 { dispose }。dispose 关闭监听、SSE / WebSocket 连接、子进程、定时器、订阅和持久化句柄。它不是每次请求结束时的回调。
  • 入口进程由宿主直接管理,Mini App 可用期间必须持续运行,并监听分配的端口。
  • 运行时不需要安装任何 Mini App SDK。Skill 提供的 miniapp-api.ts 只用于类型检查。

context 字段

hostConnector、agent 和 tool 是否注入由 manifest 决定。用户在权限面板关闭权限后,对象仍在,但对应调用会被拒绝;不要只靠对象存在来判断是否获准使用。capabilities.has(name) 只说明宿主实现了接口,也不代表当前插件获得授权。兼容旧版时使用可选链,例如 context.capabilities?.has('tool')。

最小入口

miniapp/node/server.mjs

什么时候运行

  • 按需启动:@ 选中 Mini App、打开页面、publish 或 restart 时启动。启用插件不会启动它。
  • 共享服务:同一个 Mini App 只有一个 Node 进程,多个会话共用,每个会话有自己的页面,见 Mini App 与会话。
  • 容量:同时最多运行 3 个不同的 Mini App 服务。第 4 个会返回 BUSY;更新已在运行的 Mini App 不额外占名额。
  • 停止:stop 只停服务,插件和同包能力都保留。关闭运行中 Mini App 的标签并确认后,会停止它的共享服务,并关闭所有会话里这个插件的页面。
  • 更新和重启:先停旧进程,再起新进程。同一个 Mini App 任何时候都只有一个进程,不要自行启动第二个入口。
市场更新仍提供兼容当前宿主的 Mini App 定义、且需要新进程时,宿主先保留运行中的版本,直到你从工具栏或插件详情确认更新,或服务停止后采用新版定义。如果新版删除了定义,或宿主因最低版本要求而屏蔽该定义,旧服务会被退役。详见市场更新。

多语言与子进程

Node 入口后的服务可自行选择实现方式。需要 Python、Go 等后端时,由 Node 入口拉起它,让它监听自己的内部端口,再由入口在分配的端口上做反向代理。
宿主只管理入口这一个 Node 进程。插件需在 dispose 中自行关闭拉起的子进程;宿主不保证能找到并结束它们。

端口鉴权

宿主在加载入口之前,为进程内的 node:http 服务安装鉴权守卫。只有 Mini App 页面和托管 MCP 客户端带着本次运行的凭据,其他请求在进入插件代码之前就会收到 401。插件不需要写鉴权逻辑,也看不到凭据。原理见端口与凭据。
  • 分配的端口必须用 node:http 监听,可以是 createServer,也可以是基于它的框架。用 https、http2、裸 net 或子进程直接监听,不受守卫保护,服务无法就绪,启动以 READINESS_TIMEOUT 失败。
  • /__mavis/ 路径前缀归宿主所有,不要声明或处理这个前缀下的路由。
  • 页面请求用相对路径或同源 URL。Service Worker、弹窗、外部浏览器和普通浏览器标签不带凭据,会收到 401。
  • 守卫覆盖进程内所有 node:http 服务。需要接收第三方回调(比如 OAuth 跳转)时,走分配端口自己的路由,不要在进程里另开一个 HTTP 服务。
  • 进程重启后凭据会更换。已经打开的标签在用户点刷新或重新打开之前会收到 401,这是预期行为。

日志

用 context.logger 记录诊断信息。宿主只采集有限的 stdout / stderr 样本,日志里不要放凭据和业务内容,也不能依赖日志完整保留。当前日志桥会截断消息,并仅传递 fields 的键名,不保留字段值;方法与限制见 logger 参考。