Skip to main content

入口契约

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

context 字段

最小入口

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 任何时候只有一个进程,不要自己再起第二个入口。

多语言与子进程

入口后面用什么实现都可以。需要 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 样本,日志里不要放凭据和业务内容,也不要指望它完整保留。