@bpos/mcp-contract (1.1.0)
Installation
@bpos:registry=https://gitea.akhr-ai.com/api/packages/ChaiHao/npm/npm install @bpos/mcp-contract@1.1.0"@bpos/mcp-contract": "1.1.0"About this package
@bpos/mcp-contract —— MCP 契约
BPOS 作为 MCP 服务器,对 host 那条线上的全部形状。(系统设计 §10.8)
仓里有四份契约,各有各的两头。这一份的读者是 host(执行人自己的桌面 AI 助手):
| 契约 | 两头 | 凭据 | 面 |
|---|---|---|---|
web/api/contracts |
人 ⇄ 系统 | 会话令牌 | /api/v1 |
contract/activity-contract |
活动 ⇄ 系统 | 能力令牌 | /activity-api/v1 |
contract/data-contract |
数仓 ⇄ 系统 | 库角色 | 没有 HTTP |
| 本包 | host ⇄ 系统 | 接入令牌 | /mcp/v1/<服务> |
四份互不引用(tests/boundary.test.ts 与 server 的 tests/boundaries.test.ts R8b 两头钉)。
同一件事(一张工单)在四份里可以有四种摆法,因为读者不同:屏要渲色渲章,活动要事件与名词,
数仓要列与语义,host 里的模型要的是「我该填哪几格、交付物放哪儿」。
里面有什么
| 名字 | 是什么 |
|---|---|
MCP_CONTRACT_VERSION |
本包的版本(与 package.json 同一个数,用例钉) |
MCP_PROTOCOL_VERSION |
MCP 规范的修订版(此刻 2026-07-28)——服务端、桥、契约套件都读这一格,别处不抄 |
MCP_SERVER_NAME |
serverInfo.name(bpos);版本那一格由服务端现填 |
MCP_SERVICES · mcpServiceSchema |
服务名的事实源。一期只有 desk(协同办单) |
SERVICES · toolCountOf · toolOf |
每一种服务的工具表与那一句 instructions;条数现算 |
DESK_TOOLS |
desk.* 工具的名、标题、给模型的一句、入参 / 出参 zod(条数现算,本文不抄一个数) |
hostBriefSchema 等 |
取单答复的 host 段:提示词、步骤、标准、判据、参照与模版、交付物那一格的规格与草稿 |
RESOURCE_TEMPLATES · orderIdOfUri · fileShaOfUri |
两个只读投影的 URI 模版与解析 |
MCP_ERROR_CODES |
这张面独有的几个码(stale-baseline · rate-limited · truncated) |
fileRefSchema 等 |
工具入参 / 出参里反复用到的几样小形状 |
工具表从这里扫出去:服务端按 SERVICES 注册(键不在这里的 handler 拒绝启动,出站按同一份
zod 自校验),系统模块服务卡上「工具几个」、连接说明抽屉那张表、《MCP 接入手册》那张表,
全部现算。抄一个数的那天它不会报错,只会静默地少一件。
工具表(desk,协同办单)
次序就是 tools/list 的次序,也是人办一张单的次序:
desk.list_orders → desk.get_order → desk.get_task_context → desk.save_order →
desk.upload_file → desk.deliver_artifact → desk.release_order → desk.say →
desk.answer_card → desk.lookup
全部落在执行人面:没有管理面的写、没有审批签批。要人定的事(起单、挑执行人、加额度、签批) 回工作台——那是另一个人在另一张面上的事。
办一张协同单的那条主路是四步:取单读 host 段 → 在 host 里做 → deliver_artifact 交上去
(再交即覆盖)→ release_order 提交。件上别的格用 save_order 填,别的文件用 upload_file 传。
什么改动要升大版本
判据与脚手架契约那一条同构,问的是「已经配好的 host 会不会因此办不成事」:
- 破(大版本):撤一件工具 · 给入参加一格必填 · 收窄取值集 · 换
MCP_PROTOCOL_VERSION(那是换了一套话在说)。 - 不破(小版本):加一件工具 · 给出参加一格 · 给入参加一格可选的——老 host 不知道它, 也永远不会收到它。
升版的同一次提交把外层 AI-Native/CLAUDE.md 的「契约版本」表那一格改到。
1.1.0:协同工单 = 制品卡的替代(系统设计 §10.8、附录 B 43)。两样,都不破:
- 加第十件工具
desk.deliver_artifact:入参{ orderId, fileName, mediaType?, contentBase64 }, 一步把交付物写进deliverable指的那一格——进文件库 → 覆盖槽里旧的那一份 → 推进基线 → 工作日志留一行「交付物已替换」。出参{ file, replaced?, baseline }。它不放行(放行仍是desk.release_order),也不带基线(它只动这一格),但会推进基线:手上攥着旧基线的 保存会撞stale-baseline。拒绝各说各的:不是协同单 · 单不在待处理 · 超上限(写明多大、 上限多大)· 格式不在允许集(写明允许哪几种)。 从前这条路是两步(upload_file拿回fileRef,再由模型原样搬进一个它并不认识的格, 整份data送回save_order)——少搬一格的症状是「传上去了,交付物那一格还是空的」。 desk.get_order的出参加一段host:{ brief, prompt?, steps, standard?, criteria?, references[], deliverable{ field, label, documentType, spec{ formats, maxBytes } }, draft? }——系统按定义拼,没写的缺席;拼不出交付物那一格的规格时整段缺席,不摆半份。 只有协同单有它。
server/discover 的 instructions 与 desk.upload_file 的说明同一次改到新路。mcp-bridge 不动
(它不引本包,工具表从远端现问)。
跑
npm install
npm run typecheck && npm test
发到 Gitea 私有 npm 的步骤与另外两个包同一条,见 contract/README.md。
Dependencies
Dependencies
| ID | Version |
|---|---|
| zod | 4.4.3 |
Development Dependencies
| ID | Version |
|---|---|
| @types/node | ^24.0.0 |
| tsx | ^4.19.0 |
| typescript | ^5.6.0 |