
TypeSpec 打造 API-First MCP 服务器tool 装饰器、JS 发射器与 Emitter 框架实践【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespecMCPModel Context Protocol服务器正在快速进入各类智能体工作流。本文基于 TypeSpec 官方博客《API-first MCP servers with TypeSpec》2025-05-30 发布作者 Brian Terlson讲解如何用 TypeSpec 以API 优先的方式定义 MCP 服务器与工具通过tool、mcpServer等装饰器描述服务端点再用tsp compile配合typespec-mcp-server-js发射器生成 JavaScript 服务器骨架最终只需实现工具业务逻辑即可得到可运行的 MCP 服务器。读完本文你将理解规范 确定性代码生成 AI 编写业务逻辑这一组合为何比纯手写更可靠并能结合本仓库源码理解其背后的新 Emitter Framework 组合式架构。背景为什么选择 API-First 的 MCP 服务器官方 SDK 和社区框架都能构建 MCP 服务器但 TypeSpec 团队更关注从 API 描述生成 MCP 服务器这条路线。其动机在于MCP 服务器的协议处理工具请求的分发、输入输出校验、JSON 编组属于高度模式化、可确定性生成的部分而真正需要人工或智能体思考的只有工具自身的业务逻辑。TypeSpec 作为一门简洁、人类可读的 API 描述语言天然适合承担这份契约的角色。TypeSpec 团队当时正在预发布一组 MCP 项目以收集反馈包括四个包发布在独立的 typespec-mcp 项目中包名角色typespec-mcp用 TypeSpec 描述 MCP 服务器的词汇库decorators 内置类型 typekittypespec-mcp-server-jsTypeSpec 发射器从 TypeSpec 生成 JavaScript MCP 服务器typespec-http-mcp-server-jsTypeSpec 发射器为用 TypeSpec 编写的 REST API 生成 MCP 服务器mcp-server-typespec帮助智能体构建 TypeSpec 项目的 MCP 服务器快速上手从 TypeSpec 到可运行的 MCP 服务器官方示例定义了一个向量运算服务器。给定如下 TypeSpecimport typespec-mcp; using MCP; mcpServer(#{ name: VectorMCP }) namespace VectorMCP; model Vec3 { x: int32; y: int32; z: int32; } tool op addVector(v1: Vec3, v2: Vec3): Vec3; tool op subVector(v1: Vec3, v2: Vec3): Vec3;要点说明mcpServer装饰器属性绑定语法#{ name: VectorMCP }把命名空间标记为 MCP 服务器name即服务器名称每个需要对外暴露为 MCP 工具的操作前加tool参数与返回值使用普通 TypeSpec 模型如Vec3其结构即构成工具的 JSON Schema 契约。运行tsp compile并使用typespec-mcp-server-js发射器后生成的服务器骨架已处理完所有 MCP 协议细节你只需要实现工具处理器import { setToolHandler } from #mcp-server; setToolHandler({ async addVector(v1, v2) { return { x: v1.x v2.x, y: v1.y v2.y, z: v1.z v2.z, }; }, subVector(v1, v2) { return { x: v1.x - v2.x, y: v1.y - v2.y, z: v1.z - v2.z, }; }, });注意setToolHandler接收的对象形状与 TypeSpec 中操作签名一一对应——参数与返回类型已由生成的 TypeScript 接口和 Zod schema 约束业务代码完全不需要关心 MCP 协议本身。核心理念AI 时代代码生成与智能体是好朋友博客专门用一节回应了AI 时代为什么要写规范再走代码生成的疑问其论证链条值得完整保留代码生成为智能体提供了护栏guiderails。TypeSpec 规范以简洁、人类可读的形式描述到底要实现什么先迭代规范再让智能体写代码意图表达会更精确vibe coding 的生产率反而更高。生成的代码是确定性的。从规范到协议处理代码是完全确定的映射正确响应每个工具请求、按严格 schema 校验输入输出、完成 JSON 等格式的编组。这些代码智能体也能写但容易写错且复杂度越高越需要仔细验证而确定性生成天然规避了这类风险。业务逻辑实现成本更低。如上面的示例所有 MCP 协议细节都被抽象掉了——智能体不需要了解 MCP 协议、不需要研究 MCP SDK只需在完全有 TypeScript 文档约束的 API 契约上实现逻辑这是它非常擅长的事。简单的提示词往往能一次成功且上下文与 LLM 输出量更小token 消耗也更低。结论是TypeSpec 与代码生成在智能体写代码场景下组合起来特别有用——显式声明你要构建什么再生成让智能体更容易写对的护栏。预发布包详解typespec-mcpMCP 服务器词汇库该库提供定义 MCP 服务器与工具的装饰器tool把某个操作声明为 MCP 工具。如果给工具写了文档注释doc comment它会直接用作该工具的描述summary提供简短描述TypeSpec 内置装饰器readonly、nondestructive、idempotent、closedWorld一组工具注解用于向调用方智能体传达工具的副作用特征帮助智能体安全地决定何时调用工具内置常用类型覆盖 MCP 请求与结果的各类标准类型包括用于工具调用响应的TextResult、ImageResult、AudioResult、ResourceResult以及用于描述服务器可能抛出的错误的MCPErrortypekit 支持库为发射器作者提供了 typekit让第三方可以基于该词汇库构建自己的代码生成器。typespec-mcp-server-jsMCP 服务器发射器这是核心发射器输入使用typespec-mcp词汇库编写的 TypeSpec输出的 JavaScript 项目包含四个部分MCP 工具定义——每个tool操作对应的工具元数据MCP 工具处理器——负责请求/响应编组marshalling并把你调用的请求分发到你的实现所有数据类型的 Zod schema——覆盖请求与响应所有数据类型的 TypeScript 接口。使用上你只需要导入setToolHandler和serverZod schema 与 TS 接口也一并导出按需取用。该发射器还是可扩展的它开放了调度dispatch代码生成的钩子允许你以完全自定义的方式处理 MCP 工具调用。官方博客提到的typespec-http-mcp-server-js正是利用了这一能力把默认调度器替换为直接调用你的 REST 服务器 HTTP 端点的调度器。typespec-http-mcp-server-jsREST API 直通 MCP这个发射器生成一个完全可用的 MCP 服务器其职责是把工具调用代理proxy到 REST 服务器的端点上。使用方式极简在一个 HTTP 操作上加上tool其余工作全部由发射器完成——这意味着任何用 TypeSpec 描述的 REST API 都能顺带变成一个 MCP 服务器而不必重写任何业务端点。mcp-server-typespec为构建 TypeSpec 项目而生的 MCP 服务器团队用上述能力反过来构建了一个服务于 TypeSpec 自身的 MCP 服务器供智能体在开发 TypeSpec 项目时使用。它提供四个工具learnTypeSpec——向模型注入理解与编写 TypeSpec 的入门信息init——在当前工作目录脚手架出一个带示例工具实现的新项目compile——运行tsp compile生成发射器产物build——在当前项目中执行npm run build。这形成了一个有趣的闭环用 TypeSpec 生成 MCP 服务器再用这个 MCP 服务器加速 TypeSpec 项目的构建。纵深新 Emitter Framework 的组合式架构博客最后专门说明TypeSpec 1.0 之后团队一直在构建新的发射器框架而这次预发布的所有 MCP 发射器全部基于新框架实现。对本仓库的读者来说这正是可以落到本地源码验证的部分。框架核心位于 emitter-framework 包typespec/emitter-framework采用基于组件的构建方式入口结构核心模块由 src/core/index.ts 导出包括组件components、上下文context、SCC 集scc-set、传输名策略transport-name-policy、类型连接器type-connector与输出写入write-output上下文与 Typekit 的绑定在 src/core/context/tsp-context.ts 中TspContext通过createNamedContext建立useTsp()钩子从上下文中取出编译产物Program并在需要时惰性创建 Typekit 实例$(context.program)供下游组件查询类型信息。Typekit 是编译器侧的类型查询工具包也是typespec-mcp词汇库向第三方发射器开放的能力基础组件与覆盖机制src/core/components/index.tsx 导出output组件与overrides覆盖机制含component-overrides、config这正是博客所说的组合composition能力的落点——一个发射器可以暴露可复用组件让另一个发射器在自己的项目里复用其代码生成逻辑。比如typespec-mcp-server-js允许替换默认调度器的钩子、Zod 发射器既可以独立把类型转换为 Zod schema 也可以作为库嵌入其他发射器多语言模块框架按目标语言划分模块typescript、python、csharp等见 package.json 的exports字段MCP 的 JS 发射器即构建在 TypeScript 模块之上。从源码结构看这套上下文 组件 可覆盖override的设计与 React 类框架的组织方式一致TspContext.Provider提供全局编译上下文OverridesContext允许子发射器对父发射器的组件行为做定向替换——typespec-http-mcp-server-js替换调度器、typespec-mcp-server-js复用 Zod 组件都是这一机制的实际用例。路线图与限制博客明确交代了当时的状态与后续计划引用时应注意这些是预发布preview阶段的规划typespec-mcp词汇库与typespec-mcp-server-js发射器计划新增对 resources 与 prompts 的支持MCP 协议除 tools 外的另外两类原语编组marshalling工作仍在进行例如把日期时间字符串转换为 Temporal 对象typespec-http-mcp-server-js会继续迭代目标是让任何用 TypeSpec 定义的 REST API 都能顺带生成一个功能完整的 MCP 服务器博客原文发布于 2025-05-30文中所述 API 形态对应当时的预发布版本具体装饰器与包能力请以 typespec-mcp 项目当时的最新文档为准。小结这篇文章给出的核心方法是把 MCP 服务器当作一份 API 规范来写——mcpServer声明服务器、tool声明工具、模型与注解描述契约tsp compile确定性地生成工具定义、调度器、Zod schema 与 TS 接口智能体或人只在setToolHandler里实现纯业务逻辑。再叠加REST 操作加tool即代理成 MCP 工具的路线任何存量 API 规范都能低成本获得 MCP 形态。而支撑这一切可组合、可扩展发射器的是本仓库 emitter-framework 包 所实现的组件化新框架——这也是 TypeSpec 生态在 1.0 之后的重要演进方向。【免费下载链接】typespec项目地址: https://gitcode.com/GitHub_Trending/ty/typespec创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考