Download docs/cloud-contract.md from hunian003/message: direct link, hf CLI and curl.
- Browser
- Download file 5.82 kB
-
https://huggingface.co/spaces/hunian003/message/resolve/main/docs/cloud-contract.md
- Command line
-
hf download hf://spaces/hunian003/message/docs/cloud-contract.md
-
curl -L -o cloud-contract.md https://huggingface.co/spaces/hunian003/message/resolve/main/docs/cloud-contract.md
云端原生市场 V1 契约
目标:单运营者自托管可信 DSH bundle 市场。所有核心操作均有 Web 入口;不包含计费、公共社区、多租户或不可信插件沙箱。旧 Python 市场单独启动,新部署默认不加载它。
运行与认证
入口为 app.cloud_main:app,独立于旧 app.main。MESSAGE_DATA_DIR 为仓库外可写根,保存 catalog 与 profiles;同一实例只运行一个 API worker,负责子进程。每个 profile 独立 Node 进程、安装状态和 MCP 会话。
管理API默认使用Supabase管理员账号与HttpOnly/Secure/SameSite cookie、精确Origin和CSRF。无项目配置时可启动锁定引导,不能注册首位管理员。MCP使用页面创建的profile scoped API key,每次请求查Supabase哈希/撤销/过期。详细Auth接口与SQL约束见 supabase-auth.md;不需要service_role。插件秘密仍只允许精确{$env:变量名}引用,值仅注入目标worker。
MESSAGE_ALLOWED_HOSTS 与 MESSAGE_ALLOWED_ORIGINS 明确配置,拒绝不匹配 Host/Origin;无 Origin 的原生客户端可用。反向代理终止 TLS,只有经过此鉴权网关才可远程访问;内部 DSH HTTP 仅 loopback。
API(统一 JSON;错误为 detail 文本)
- GET
/api/native/health:免认证仅{status:'healthy'} - GET
/api/native/catalog:{items:[{id,name,version,description,sha256,bytes}]};id 为 SHA256 - POST
/api/native/catalog:multipartfile上传独立 tgz;检查归档路径、元数据、bundle 声明、依赖来源和大小;重复相同内容幂等,同名同版本不同内容拒绝;返回 artifact - GET
/api/native/catalog/{id}/download:鉴权下载归档 - GET
/api/native/profiles:{items:[{id,status,generation,restart_required,last_error}]} - POST
/api/native/profiles:{id}创建空 profile,返回状态;id 仅小写字母/数字/短横线 - GET
/api/native/profiles/{id}:{id,status,generation,restart_required,last_error,bundles,plugins,configured_tools,active_tools} - POST
/api/native/profiles/{id}/install:{artifact_id};同名新版本是升级,返回{operation,profile},标记待重启 - POST
/api/native/profiles/{id}/enable、/disable:{name},返回{operation,profile},标记待重启 - POST
/api/native/profiles/{id}/restart、/stop:无body,返回状态;restart关闭旧worker和会话,启动新generation,失败可诊断/恢复 - POST
/api/native/profiles/{id}/call:{name,arguments:{}};只调用正在运行worker的真实MCP,不用临时CLI假装活跃工具 /mcp/{id}:鉴权Streamable HTTP代理,正确转发POST/GET/DELETE、MCP会话/协议头与SSE;隔离profile token和后端会话
Web登录会话使用HttpOnly cookie,刷新页面可恢复,不在localStorage保存token。默认页为原生市场,可选择profile、查看目录与安装版本、上传/下载、安装/升级/启停、看到待重启状态、重启/停止、调用工具、查看可复制的MCP配置。旧页面标记legacy并保持兼容路由。
交付验收
真实浏览器与真实SDK覆盖:未登录拒绝、上传/目录、profile创建、安装、待重启、重启后工具可用、调用、禁用与重启后拒绝、升级新值、两profile状态与令牌隔离、同profile多MCP会话、错误恢复、API进程关闭回收workers、冷启动持久状态恢复。消费者源码/lock哈希不因安装/升级变化。
部署包提供轻量Python依赖锁、Node lock、前端构建、非root容器、健康检查、数据卷和反向代理TLS示例;不执行实际发布。所有用户文档为Markdown。
操作与恢复补充
安装/升级/启停/配置/卸载/重启/停止为异步操作,接受 Idempotency-Key,返回 HTTP 202 {operation_id, status}。GET /api/native/operations?profile_id= 返回 {items:[{id,profile_id,kind,status,result,error,created_at,updated_at}]},GET /api/native/operations/{id} 读取单项;status 为 queued/running/succeeded/failed/cancelled。同 key 重复请求返回同一操作,不重复执行;不同payload同key拒绝。POST /api/native/operations/{id}/cancel 申请取消,终态可持续查询;已不可取消则409。页面刷新后可重新读取任务。启动时未完成操作标为 interrupted/failed,不能报告成功。
新增 POST /api/native/profiles/{id}/remove:{name}。卸载先停止使用该包的worker,再执行离线包移除,不假装全量事务;失败保留诊断与明确的实际状态。操作返回中区分期望安装/启用状态、正在运行的generation与待重启状态。
配置接口:POST /api/native/profiles/{id}/configure,body {entry_id, config:{}},同一异步操作契约。plugins条目提供entryId/entry_id、patchId/row_id、raw config和readOnlyReason;管理读取不挂载第三方apply。安装/升级前停止worker,完成后待人工重启;普通配置和启停可保留旧worker直到重启。
存活GET /api/native/health 与就绪GET /api/native/readiness 分开;后者在应运行profile未就绪时503。每次请求在读取body之前鉴权。
Auth接口
GET /api/native/auth/status 返回配置/登录/CSRF/存储状态;POST /auth/login 输入email/password;POST /auth/logout撤销当前Supabase会话;POST /auth/recover发默认PKCE邮件;GET /auth/recovery/callback消费一次code;POST /auth/password仅允许独立恢复cookie。以上路径省略共同 /api/native 前缀。
GET/POST /api/native/profiles/{id}/keys 列表/创建(name、expires_in_days),DELETE /{key_id}撤销,GET /api/native/auth/audit查固定事件。密钥只创建响应有明文,其他响应无哈希或secret。session绑定key ID,撤销中断本进程现有流。