@yi-bi/app-sdk
v0.2.2
Published
YI-BI server-side OAuth and MCP SDK for AI-generated applications
Downloads
581
Readme
YI-BI 应用 SDK 0.2.2
0.2.2 授权过期恢复
待确认的 OAuth 请求有效期为 10 分钟。超过有效期后,应返回应用重新点击“连接 BI”,不能继续使用原授权页地址。这个时限与已连接账号的授权期限不同。
本版浏览器 login() 每次主动连接前刷新会话与 CSRF,合并重复点击;服务端从本次连接开始重新创建完整的 10 分钟匿名会话。网络失败会继续向调用方抛出异常,应用必须显示错误并恢复按钮状态。已连接用户的授权权限和撤销检查不变。
已有应用需要升级 SDK 并重新部署;只发布 npm 包或更新 MCP 网关不会更新客户应用。BI 授权页同时需要部署前端修复,才能显示过期错误。部署与回归说明见 AUTH-EXPIRY.md。
供 AI 生成独立部署的实时 BI 应用。Node 后端 SDK 管理每位访问者的 OAuth;浏览器 SDK 只调用同源应用接口,不持有 BI/MCP access 或 refresh token。无需上传 BI 平台。
要求 Node 24.9.0 或以上,当前 MCP 主入口需启用 OAuth 和 bi-direct。不支持旧固定 BI_TOKEN、STDIO 取数或 OSS 下载模式。正式通过 npm registry 分发,MCP 只提供包名、指定版本和用法,不托管安装包。当前包名为 @yi-bi/app-sdk,尚未发布,发布前需确认 scope 归属和公共/私有 registry;本地 tgz 用于测试。
给 AI 的步骤
- 调用
get_integration_guide,确认 OAuth 和 SDK 下载均可用。不要搜索或读取 WorkBuddy 配置或宿主凭据。 - 当指南声明已发布时,在独立项目按 packageSpec 安装指定 npm 版本;未发布时仅使用运维提供的 tgz 和 SHA-256。不要假设未发布的包名可直接安装。
- 运行模板生成命令,保留 SDK 会话和数据访问层,在
public/app.js中增加客户业务界面。 - 用 SDK 查询 V1/V2 目录及报表,保留字符串代码和 ID;不要把所有数字字符串转换为数字。
- 新增自定义后端 API 时使用
bi.query(req, args)、bi.call(req, tool, args)。第一版不跨请求缓存 BI 业务结果,不做开发者共享缓存,不自动用个人授权运行无人值守任务。connectionId 用于隔离应用自己的状态,不代表行列权限没有变化。 - 验证匿名401、两个访问者隔离、退出及撤销、超限、无凭据输出后再分享部署地址。
安装与模板
mkdir my-dashboard
cd my-dashboard
npm init -y
# 发布后:npm install @yi-bi/[email protected]
# 发布前:安装本地测试包(通过 releases/manifest.json 校验 SHA-256)
npm install /path/to/yi-bi-app-sdk-0.2.2.tgz
npx --no-install yi-bi-create-app .
node server.mjs模板生成器不覆盖已有文件,安装目录中已有 package.json/node_modules 不受影响。模板是登录、列报表和查询的最小应用,不是客户看板的自动迁移器。
启动前配置运行环境(模板 app.env.example 仅包含占位值):
| 变量 | 说明 |
|---|---|
| BI_MCP_URL | https://mcp.example.com/mcp,公开主入口 |
| BI_APP_ORIGIN | https://dashboard.example.com,固定应用源,不能包含子路径 |
| BI_APP_STORAGE_PATH | /var/lib/yi-bi-app/session.sqlite,位于静态目录之外 |
| BI_APP_STORAGE_KEY | 独立生成的32字节随机数,编码为64位十六进制;不是 BI/MCP Token |
| BI_APP_NAME | 授权页上的应用名称 |
| BI_APP_ALLOW_LOCALHOST | 本地 loopback HTTP 调试时设为 true;生产默认 false |
| PORT | Node 监听端口,默认8770,只监听127.0.0.1 |
在 PowerShell 当前进程树中生成存储密钥,不输出密钥:
$env:BI_APP_STORAGE_KEY = node -e "process.stdout.write(require('node:crypto').randomBytes(32).toString('hex'))"生产将环境配置置于受保护的服务环境文件,通过 systemd 注入;备份加密密钥和 SQLite(包含活跃 WAL 的一致备份),不要把真实环境文件、SQLite、客户数据或打包缓存附在交付包里。丢失密钥无法恢复会话;不可直接修改已有数据库绑定的应用/MCP地址,请先断开连接、换新数据库并重新授权。
在 MCP 主入口的 oauth.redirectUris 中添加精确地址 https://dashboard.example.com/bi/callback,然后重启主入口。SDK 使用此应用自己的动态注册,不复制 WorkBuddy client_id。BI 的 mcp.oauth.callback-url 仍指向 MCP 主入口,不改为应用地址。本地 http://127.0.0.1:<端口>/bi/callback 已由主入口支持。
服务端接口
import { createBiApp } from '@yi-bi/app-sdk';
const bi = createBiApp({ mcpUrl, appOrigin, storagePath, storageKey });
// 放在静态文件处理之前,拦截固定的 /bi/* 路由。
if (await bi.handle(req, res)) return;
// 自定义业务 API:req 必须是当前访问者的请求,不能人为构造开发者凭据。
const result = await bi.query(req, { mode: 'report', reportId: '123', definitionVersion: 2 });
// 可用于保护应用自己的状态 API;不能作为旧 BI 数据缓存仍有权限的证明。
const { connectionId } = await bi.authorize(req);bi.handle 管理 GET /bi/session、POST /bi/login、GET /bi/callback、POST /bi/logout、POST /bi/query、POST /bi/call,以及公开的 /bi/client.js。写请求要求固定 Origin 和会话 CSRF nonce。/bi/call 仅允许既有六个只读查询工具。不要自己添加接受 token、corpId 或任意上游 URL 的旁路接口。
浏览器接口
import { session, login, logout, query, listReports } from '/bi/client.js';
const current = await session();
// 在用户点击按钮时调用 login();它会跳转真实 OAuth 授权页。
const reports = current.connected ? await listReports({ definitionVersion: 2 }) : [];
// query(...) 返回 columns/rows/summaries 等直连结果,不需要下载文件。浏览器仅持有 HttpOnly 会话 Cookie,JS 可读的是 CSRF nonce(不是 OAuth 凭据)和应用本地 connectionId。SDK 不返回企业名称或用户姓名,因为当前 MCP 未提供安全的身份查询契约;用户在 BI 授权页确认企业。退出后重新连接即可选择其他企业,切换不会复用旧连接ID。
后端必须为自定义 dashboard/latest/export/status 等业务 API 增加同等鉴权,SDK 不会自动保护未交给它的路由。模板没有数据缓存和后台预热,避免未经授权的共享结果;客户已有 Node 聚合逻辑可迁移到受鉴权的后端 API。当前接口未提供可复核的数据权限版本,因此每次获取 BI 数据必须重新 query/call,不能只检查 session/authorize 就复用旧数据。登录有效不等于旧报表的行列权限未变。
自定义 JSON 聚合接口可由浏览器 appRequest('/api/dashboard', args) 调用,它自动携带会话和 CSRF nonce;后端处理该请求时调用 bi.query(req, ...)。非 GET/HEAD 的 SDK 服务端调用也会校验 Origin/CSRF,不能用不带会话的定时器或伪造请求替代访问者。
生命周期和运行边界
授权码一次性 state/PKCE;登录后轮换会话 ID;匿名会话10分钟,授权会话最多8小时,超时需重新登录。每次 SDK 查询和 authorize() 都通过 MCP 验证当前授权,不使用认证成功的长期本地缓存。每次调用创建独立 MCP 客户端,优先保证隔离;暂未做连接池优化。
access 即将到期时按会话串行刷新,旋转结果原子写入加密记录;刷新响应丢失时断开而不重用旧 refresh。退出先失效本地会话,再由加密队列重试远端撤销;重启保留队列,每30秒检查一次。关闭应用后重试暂停,恢复运行后继续。维护任务同时回收过期会话,最多保留1万个会话。
第一版仅支持一个 Node 进程管理一份 SQLite,不使用 PM2 cluster/多副本共享库。禁止两个不同应用共用同源 Cookie、库或密钥。负载均衡、多进程锁、共享会话存储及后台任务授权需后续专门实现。反向代理保持同源 HTTPS,不开放 CORS;为 /bi/session、/bi/login 加请求频率限制,业务请求读取超时至少130秒,应用日志不记录 Cookie、请求授权头或 OAuth 回调查询串。
SDK 规范不能代替运行环境控制,也不能阻止恶意应用后端主动读取自己环境中的秘密;它提供安全默认路径,必须审查生成应用是否真的通过 SDK 访问数据。
仓库验证与打包
个人账号 yi-bi 的完整发布步骤见仓库内 services/bi-app-sdk/PUBLISHING.md(该运维文档不随 npm 包分发)。
cd services/bi-app-sdk
npm ci
npm test
npm run pack:previewnpm test 会先打包,再在临时目录离线安装该 tgz 并验证模板。产物在 releases/,其中 manifest.json 含 SHA-256。测试依赖同仓库已有 MCP/计算服务及其已安装依赖,采用本地模拟 BI,不连接客户数据。发布包只包含 SDK、模板和此文档,不含测试、真实环境文件或数据库。
正式发布前确认 npm scope 和 registry,按团队方式登录/配置发布身份,再执行 npm publish(公共 scoped 包需显式 --access public,私有 registry 按团队配置)。本次没有执行发布或操作 npm 账号。发布完成后将网关 sdk.published 改为 true,私有源可设置公开的 sdk.registry URL;不要把 registry 访问 Token 放进网关接入指南。后续发布升级版本,同时更新 MCP src/sdk-contract.mjs 的指定版本;不要覆盖已发布版本。
动态回调登记(0.2.2)
先让 AI 调用 manage_app_callbacks begin,获取部署验证 id 与 proof。配置 BI_APP_DEPLOYMENT_PROOF=: 后部署,在10分钟内调用 verify。SDK 自动提供公开验证路径,再按原协议注册独立客户端。无需运维添加回调白名单;每位访问者仍需独立授权。停用后重新验证应使用新的proof重启SDK,SDK会清除旧客户端登记,下次登录注册新客户端。
0.2.1 查询诊断与等待预算
单次 SDK 查询默认预算300000ms,包含获取凭据、连接与工具执行;可通过 createBiApp 的 queryTimeoutMs 或 BI_APP_QUERY_TIMEOUT_MS 配置(1000~600000ms)。代理建议 proxy_read_timeout 330s;平台硬超时需单独确认。Node requestTimeout 仅控制接收请求,不是业务响应预算。
服务器输出 bi_sdk_request,含 requestId、tool、stages(access/connect/tool/delivery)、elapsedMs、outcome。SDK将同一requestId传到MCP网关及BI请求日志,不记录凭据、查询参数或数据。错误保留BI_SERVER_ERROR、UPSTREAM_TIMEOUT、MCP_TIMEOUT、RESULT_TOO_LARGE等分类,error.diagnostic提供requestId、stage、elapsedMs及可用的businessCode/httpStatus;不要向用户展示未经处理的上游原始响应。
看板按需查询当前标签页,每个图表独立显示加载与错误;Promise.allSettled可保留本轮成功结果。刷新不叠加,bi.query/bi.call前不用重复session/authorize。不能跨访问者共享业务结果或用开发者Token预热。单次最终结果仍最多10000行、约2MB。
