细则展开见 designer-chat 仓
docs/agent-mcp-skill-rules.md(同源,本项目实测版)。 本篇是可复用标准。
任何 MCP 必须有一个稳定契约模块,对外只暴露固定方法:
start(opts) → { ok, tools?, error? } // 幂等
listTools() → ToolSpec[] // MCP JSON Schema
callTool(name, args) → { ok, result?, error? }
state → signal('idle'|'starting'|'ready'|'error')
transport → 'worker'|'iframe'|'http'|'inproc'
state 可订阅,UI 靠它显示连接状态。| 关注点 | 规则 |
|---|---|
| 注册表 | Map<mcpId, McpHandle>,每个 MCP 有稳定 id |
| 命名空间 | 全名 = ${mcpId}.${toolName},避免跨 MCP 同名冲突 |
| 生命周期 | 各自独立 start/stop,一个挂了不拖垮其它 |
| 聚合视图 | Agent 只对「所有就绪 MCP 的工具并集」编程 |
| 隔离 | 凭据/状态互不可见 |
冲突优先级:显式注册 > 内置 > 后启动,且启动时告警,不静默覆盖。
zod/v4、@page-agent/core)会直接加载失败。assertSpecParity() 断言参数键一致,防漂移。async function doThing(params, { token, signal }) → result
status),由上层翻译成人话。server.register({
name, title, description,
inputSchema, // MCP JSON Schema
annotations, // readOnlyHint / destructiveHint / openWorldHint
defaultMode, // (ctx) => 默认值
buildBrief, // (args) => 人类可读描述(纯函数)
handler, // async (args, ctx) => MCP result
});
buildBrief 必须纯(Worker 内可用,无 DOM/网络)。skills.manifest.json(启用项 + 版本 + 对应 MCP);可懒加载。skill-<capability>;工具 <verb>_<object>;全名 <mcpId>.<toolName>。isError,不抛穿到 Agent。isError 而非抛穿?