入口契约
- 入口是一个导出
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: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 样本,日志里不要放凭据和业务内容,也不要指望它完整保留。