
如何用MCP Apps SDK编写类型安全的工具处理器Zod Schema实战【免费下载链接】ext-appsOfficial repo for spec SDK of MCP Apps protocol - standard for UIs embedded AI chatbots, served by MCP servers项目地址: https://gitcode.com/GitHub_Trending/ex/ext-appsMCP Apps SDKmodelcontextprotocol/ext-apps是 MCP Apps 协议的官方规范与 SDK它让 MCP 服务器为 AI 聊天客户端提供图表、表单、仪表盘等交互式 UI。本文带你用 Zod Schema 编写类型安全的工具处理器tool handler——从定义inputSchema到z.infer推导类型让你告别any和手写校验让模型、服务器与 UI 三方共享同一份数据契约。为什么需要类型安全的工具处理器传统的 MCP 工具只能返回文本和结构化数据。MCP Apps 扩展了协议工具可以声明一个ui://资源宿主Host把它渲染成嵌在对话里的交互界面。而整个体系的地基就是工具的输入/输出契约。没有类型约束时你会遇到三类典型问题痛点后果模型传错参数运行时才炸排查困难UI 与服务器各自定义类型字段名拼写不一致改动一处漏一处手写校验逻辑冗长、易错、无法自动生成 JSON SchemaMCP Apps SDK 的解法是用 Zod Schema 作为单一事实来源它同时驱动三件事——运行时校验非法参数直接被拒绝并返回格式化的错误信息JSON Schema 生成自动转成模型可读的参数说明draft-2020-12TypeScript 类型推导z.infer让处理函数参数获得完整类型提示这套机制的核心源码在 src/standard-schema.ts它基于Standard Schema协议因此除了 Zod v4也兼容 ArkType、Valibot 等库。注册带 UI 的工具registerAppTool 一步到位服务器端不需要手动处理 UI 元数据SDK 的 registerAppTool 帮你把工具 界面资源关联起来。以 quickstart 示例 为起点最简形式只有几行registerAppTool( server, get-time, { description: Returns the current server time., inputSchema: z.object({}), _meta: { ui: { resourceUri } }, // 把工具关联到它的 UI 资源 }, async () { const time new Date().toISOString(); return { content: [{ type: text, text: time }] }; }, );关键在于inputSchema: z.object({...})——只要你传入了 Zod 对象SDK 就会自动完成校验并且回调函数的参数类型直接从 Schema 推导无需任何额外声明。完整参数说明见 src/server/index.examples.ts。实战三招给工具参数加上约束第一招用 .describe() 教模型怎么传参.describe()不只是注释它会被序列化进 JSON Schema成为模型生成参数时的说明文字。map-server 示例 是一个好范本inputSchema: z.object({ west: z.number().optional().default(-0.5) .describe(Western longitude (-180 to 180)), south: z.number().optional().default(51.3) .describe(Southern latitude (-90 to 90)), // ... }),注意三个细节的组合拳z.number().optional()—— 字段可省略.default(-0.5)—— 省略时自动补默认值模型甚至不需要传.describe(...)—— 取值范围写清楚模型命中率显著提升第二招z.enum / z.union 收窄取值空间customer-segmentation 示例 展示了输入 输出双 Schema 的完整模式const GetCustomerDataInputSchema z.object({ segment: z.enum([All, ...SEGMENTS]).optional() .describe(Filter by segment (default: All)), }); const CustomerSchema z.object({ id: z.string(), annualRevenue: z.number(), // ... }); const GetCustomerDataOutputSchema z.object({ customers: z.array(CustomerSchema), segments: z.array(SegmentSummarySchema), });z.enum把segment锁定在有限集合内模型不可能传出一个不存在的客群名z.array 内嵌对象 Schema 则让嵌套结构照样有完整类型。第三招z.infer 让类型跟着 Schema 走Schema 定义好后类型就免费了——customer-segmentation-server 里的标准写法// 类型直接从 Schema 推导改 Schema 时类型自动同步 type Customer z.infertypeof CustomerSchema; type CustomerDataOutput z.infertypeof GetCustomerDataOutputSchema;从此处理函数里args.segment自动获得All | Enterprise | ...的字面量类型structuredContent的返回也被outputSchema约束——任何字段名写错TypeScript 编译期就会报错。进阶outputSchema 与 structuredContent只约束输入还不够。给工具声明outputSchema后SDK 会反向校验你返回的结构化数据见 budget-allocator 示例registerAppTool( server, get-budget-data, { inputSchema: z.object({}), outputSchema: BudgetDataResponseSchema, // 约束结构化输出 _meta: { ui: { resourceUri } }, }, async (): PromiseCallToolResult ({ content: [{ type: text, text: formatBudgetSummary(response) }], structuredContent: response, // 自动按 Schema 校验 }), );outputSchema同时会随tools/list下发给宿主UI 端拿到structuredContent时同样享有类型提示。这一进一出输入输出都被同一套 Zod 语法锁死。幕后原理SDK 如何完成校验与序列化理解底层机制能帮你写出更稳的 Schema。调用链路是这样的序列化tools/list时standardSchemaToJsonSchema 调用 Schema 的~standard.jsonSchema方法输出 draft-2020-12 的 JSON Schema 给模型校验模型发起调用时validateStandardSchema 执行~standard.validate失败时抛出带路径的格式化错误如segment: Invalid enum value推导App.registerToolsrc/app.ts中的AppToolCallbackInputArgs, OutputArgs泛型用StandardSchemaV1.InferOutput完成参数与返回值的类型推导这套设计基于 Standard Schema V1 开放协议src/standard-schema.ts所以 Zod 只是选项之一——Valibot、ArkType 都能无缝替换。仓库还提供了构建时生成的 schema.json可用于对照协议的完整类型定义。新手避坑清单常见错误正确姿势字段忘写.optional()模型偶尔不传就报错可缺省的字段一律.optional()配.default()更佳参数无.describe()模型频繁传错每个字段都写清楚含义与取值范围UI 里手写一份类型与服务器脱节只维护 Zod Schema用z.infer派生所有类型忘了zod要装 v4安装zod^4.2.0与 SDK 的 peer 依赖保持一致输出不声明outputSchema有结构化返回时必加UI 端才有类型保障安装依赖时保持 MCP SDK 各包同一 beta 版本见 README 的 Getting Started 一节npm install -S modelcontextprotocol/ext-apps \ modelcontextprotocol/server2.0.0-beta.5 \ modelcontextprotocol/core2.0.0-beta.5 \ zod^4.2.0下一步从示例出发仓库的 examples/ 目录是最好的老师按难度递进quickstart/ —— 最小完整示例5 分钟跑通basic-server-react/ —— React 版起步模板另有 Vue、Svelte、Preact、Solid、Vanilla JS 版本map-server/ —— 参数默认值 .describe()实战customer-segmentation-server/ —— 输入/输出双 Schema 完整范式pdf-server/ —— 复杂嵌套 Schema 与命令模式的大型参考想本地运行全部示例git clone https://gitcode.com/GitHub_Trending/ex/ext-apps cd ext-apps npm install npm start更多协议细节请查阅 docs/ 目录下的官方文档如 quickstart.md、patterns.md。掌握 Zod Schema 这一招之后你的 MCP 工具将同时获得模型友好、UI 友好与编译期安全——这才是类型安全的完整闭环。【免费下载链接】ext-appsOfficial repo for spec SDK of MCP Apps protocol - standard for UIs embedded AI chatbots, served by MCP servers项目地址: https://gitcode.com/GitHub_Trending/ex/ext-apps创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考