
深入解析 modelcontextprotocol/fastify用 Fastify 承载 MCP 服务器的官方适配器【免费下载链接】typescript-sdkThe official TypeScript SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/GitHub_Trending/ty/typescript-sdk导读modelcontextprotocol/fastify是官方 TypeScript SDKtypescript-sdk中面向 Fastify 框架的 MCP 服务器适配层用于将 modelcontextprotocol/server 的能力以 Fastify 应用的形式对外提供。阅读本文后你将掌握如何用createMcpFastifyApp()一键创建带安全默认值的 MCP Fastify 应用、如何挂载 Streamable HTTP 端点、如何通过 Host 与 Origin 头部校验防御 DNS rebinding 攻击以及该包在 SDK v2 演进中引入的 ESM/CJS 双构建与 2026-07-28 规范支持等关键变更。包定位薄集成层而非 MCP 实现从 README.md 的定位描述与 package.json 的依赖声明可以看出该包自身不实现任何 MCP 协议逻辑dependencies为空核心能力来自两个peerDependenciesmodelcontextprotocol/server与fastify它只做两件事创建带 MCP 合理默认值的 Fastify 应用、为 localhost 服务器提供 DNS rebinding 防护与 Express 适配器、Hono 适配器 遵循完全相同的适配模式按变更记录2.0.0-alpha.1所述该包即是在参考二者后新增的 Fastify 版本。包的公开导出非常精简全部来自 src/index.tsexport * from ./fastify; export * from ./middleware/hostHeaderValidation; export * from ./middleware/originValidation;实际对外 API 共 6 个createMcpFastifyApp、hostHeaderValidation、localhostHostValidation、originValidation、localhostOriginValidation。安装与前置条件npm install modelcontextprotocol/server modelcontextprotocol/fastify fastify # 若需要基于 Node.js (IncomingMessage/ServerResponse) 的 MCP Streamable HTTP npm install modelcontextprotocol/node安装前提以当前仓库为准包要求 Node.js20见 package.json 的engines字段模块系统为type: module同时通过exports的import/require双条件支持 ESM 与 CommonJS 两种消费方式详见下文“构建与发布”。createMcpFastifyApp带安全默认值的应用工厂核心入口是 src/fastify.ts 中的createMcpFastifyApp(options?)。它的设计哲学是“默认安全”只要绑定在 localhost 类地址上就自动挂载 DNS rebinding 防护钩子。选项参数说明选项类型默认值行为hoststring127.0.0.1绑定主机名。为127.0.0.1、localhost或::1时自动启用 DNS rebinding 保护allowedHostsstring[]无显式提供 Host 校验白名单端口无关仅主机名。IPv6 需带方括号如[::1]。常用于绑定0.0.0.0/::但仍想限制合法主机名时allowedOriginsstring[]无显式提供 Origin 校验白名单端口无关仅主机名约定与allowedHosts一致。省略时对 localhost 类绑定自动启用 Origin 校验安全默认值的武装逻辑从 src/fastify.ts 的实现可以归纳出以下决策阶梯Host 校验若显式传入allowedHosts则用hostHeaderValidation(allowedHosts)挂载onRequest钩子否则若host属于[127.0.0.1, localhost, ::1]自动挂载localhostHostValidation()否则若host为0.0.0.0或::绑定所有网卡打印一条警告日志提示应使用allowedHosts限制主机或改用认证保护服务器。Origin 校验2.0.0-alpha.4起若显式传入allowedOrigins挂载originValidation(allowedOrigins)否则对 localhost 类绑定自动挂载localhostOriginValidation()——没有Origin头的请求放行非浏览器 MCP 客户端不受影响带Origin但主机名不在白名单或无法解析包括不透明的nullorigin的请求以403拒绝。典型用法示例import { createMcpFastifyApp } from modelcontextprotocol/fastify; // 默认绑定 127.0.0.1自动启用 Host Origin 校验 const app createMcpFastifyApp(); // 自定义 host绑定 0.0.0.0 时不自动启用 DNS rebinding 保护 const appOpen createMcpFastifyApp({ host: 0.0.0.0 }); // 绑定 localhost 时保护仍然生效 const appLocal createMcpFastifyApp({ host: localhost }); // 非 localhost 绑定 显式白名单 const app createMcpFastifyApp({ host: 0.0.0.0, allowedHosts: [myapp.local, localhost], });注意createMcpFastifyApp内部直接调用Fastify()创建实例Fastify 默认就会解析 JSON 请求体因此 MCP Streamable HTTP 端点无需额外 body 解析中间件见 src/fastify.ts 的注释。Streamable HTTP 端点挂载将 MCP 服务器挂到 Fastify 路由上的完整示例来自 README.mdimport { createMcpFastifyApp } from modelcontextprotocol/fastify; import { NodeStreamableHTTPServerTransport } from modelcontextprotocol/node; import { McpServer } from modelcontextprotocol/server; const app createMcpFastifyApp(); const mcpServer new McpServer({ name: my-server, version: 1.0.0 }); app.post(/mcp, async (request, reply) { // 无状态示例每个请求新建 transport。 // 有状态模式sessions下应保留并复用 transport 实例。 const transport new NodeStreamableHTTPServerTransport({ sessionIdGenerator: undefined }); await mcpServer.connect(transport); // 客户端关闭连接如 SSE 流式传输期间时清理 transport reply.raw.on(close, () { transport.close(); }); await transport.handleRequest(request.raw, reply.raw, request.body); });实战注意事项README 明确给出无状态模式下若每个请求都新建McpServer也应在close处理器中调用mcpServer.close()若希望以405 Method Not Allowed拒绝非 POST 请求可为 GET/DELETE 添加返回 JSON-RPC 错误响应的路由更完整的 Fastify 托管方案可参考 serving/fastify.md 与可运行的 examples/fastify 示例。Host 头部校验DNS rebinding 防护原理与动机DNS rebinding 攻击通过操控 DNS 让一个域名解析到127.0.0.1使恶意网页能够绕过同源策略访问本机服务。对没有认证、没有 HTTPS 的 localhost/开发服务器而言这是需要重点防御的攻击面——这正是 src/middleware/hostHeaderValidation.ts 中注释强调的适用场景。两个 Hookimport { hostHeaderValidation, localhostHostValidation } from modelcontextprotocol/fastify; // 自定义白名单端口无关IPv6 带方括号 app.addHook(onRequest, hostHeaderValidation([localhost, 127.0.0.1, [::1]])); // 便捷钩子只允许 localhost / 127.0.0.1 / [::1] app.addHook(onRequest, localhostHostValidation());实现上见 src/middleware/hostHeaderValidation.ts钩子将request.headers.host交给服务器包导出的validateHostHeader来自modelcontextprotocol/server导出见 packages/server/src/index.ts校验失败时以403返回 JSON-RPC 格式错误{ jsonrpc: 2.0, error: { code: -32000, message: 校验失败原因 }, id: null }localhostHostValidation()则直接复用服务器包提供的localhostAllowedHostnames()作为白名单。测试用例印证test/fastify.test.ts 覆盖了完整行为矩阵仅允许localhost时host: evil.com:3000的请求返回403响应体为 JSON-RPC 错误且code -32_000host: localhost:3000正常放行200多白名单场景下127.0.0.1:8080与myapp.local均放行localhostHostValidation()分别允许localhost:3000、127.0.0.1、[::1]:3000拒绝evil.com:3000。Origin 头部校验面向浏览器的跨站防护2.0.0-alpha.4引入的 Origin 校验PR #2286是 Host 校验的补充浏览器在跨域请求中会携带Origin头校验它可以进一步防御 DNS rebinding 与跨站请求伪造CSRF。核心实现位于 src/middleware/originValidation.ts同样提供两个钩子import { originValidation, localhostOriginValidation } from modelcontextprotocol/fastify; // 自定义 origin 白名单无 scheme、无端口IPv6 带方括号 app.addHook(onRequest, originValidation([localhost, 127.0.0.1, [::1]])); // 便捷钩子仅允许 localhost / 127.0.0.1 / [::1] 的 origin app.addHook(onRequest, localhostOriginValidation());行为约定与 src/fastify.ts 注释及 CHANGELOG 一致无Origin头 → 放行非浏览器的 MCP 客户端如 CLI、SDK 直连通常不发送该头不受影响Origin存在但主机名不在白名单、或无法解析含不透明的nullorigin→ 403 拒绝校验同样委托给服务器包提供的validateOriginHeader与localhostAllowedOrigins导出见 packages/server/src/index.ts底层是框架无关的辅助函数validateOriginHeader/originValidationResponse。这套 Origin 校验并非 Fastify 独有——同一 PR 同时为 Express、Hono 适配器增加了对应中间件与allowedOrigins选项并为node:http裸服务器适配器modelcontextprotocol/node补齐了hostHeaderValidation/originValidation请求守卫。构建与发布ESM 与 CommonJS 双构建2.0.0-beta.2起PR #2405所有包改为同时发布 ESM 与 CommonJS 两种产物通过 tsdown 的format: [esm, cjs]同时产出.mjs/.d.mts与.cjs/.d.cts见 tsdown.config.tsexportsmap 增加require条件使require(modelcontextprotocol/fastify)在 CommonJS 消费方也能正常工作输出扩展名在各包间统一规范化公开导入路径不变。从 package.json 可以看到完整的条件导出结构exports: { .: { import: { types: ./dist/index.d.mts, default: ./dist/index.mjs }, require: { types: ./dist/index.d.cts, default: ./dist/index.cjs } } }, main: ./dist/index.cjs, types: ./dist/index.d.mts此外2.0.0-alpha.3PR #1898为包增加了顶层types字段client/server 上另有typesVersions使采用旧式moduleResolution: node的消费方也能解析类型声明exportsmap 对nodenext/bundler解析仍是权威来源。2.0.0-alpha.2则修复了 tsdown 的 exports 解析问题。版本演进时间线从 alpha 到 2.0.0结合 CHANGELOG.md该包的演进脉络如下版本关键变更2.0.0-alpha.1首次引入 Fastify 中间件适配器PR #1536遵循 Express/Hono 适配器模式2.0.0-alpha.2修复 tsdown exports 解析PR #18402.0.0-alpha.3增加顶层types字段与typesVersions兼容旧式moduleResolution: nodePR #18982.0.0-alpha.4新增 Origin 头部校验originValidation/localhostOriginValidation中间件与allowedOrigins选项PR #22862.0.0-beta.2ESM 与 CommonJS 双构建PR #24052.0.0-beta.1/2.0.0首个支持MCP 2026-07-28 规范修订的 SDK v2 正式版PR #2402各版本均与modelcontextprotocol/server对应版本同步发布CHANGELOG 中每个版本都带有对该依赖的Updated dependencies条目。向 v2 与 2026-07-28 规范迁移2.0.0是 SDK v2 的首个正式版本核心是支持 MCP 2026-07-28 规范修订。CHANGELOG 明确指引读者参考两份迁移文档docs/migration/upgrade-to-v2.md从 v1 升级到 v2 的完整指南docs/migration/support-2026-07-28.md采用 2026-07-28 规范修订的指南。对于使用本适配器的开发者升级到 v2 后 API 表面保持稳定createMcpFastifyApp与各校验钩子签名不变新增的allowedOrigins选项与默认启用的 Origin 校验属于行为层面的增强只要绑定在 localhost 类地址应用就会自动获得 Host Origin 双重防护而对非浏览器客户端不发送Origin头透明无感。小结modelcontextprotocol/fastify用极薄的 API 表面一个工厂函数加四个校验钩子为 Fastify 用户补齐了 MCP 服务器托管的三件关键能力合理的默认绑定与防护、Streamable HTTP 端点挂载、以及面向 localhost/开发场景的 Host Origin 双重校验。其实现完全依赖modelcontextprotocol/server的框架无关校验辅助函数保持了一致的适配模式与安全语义配合 v2 的 ESM/CJS 双构建可以无缝接入 ESM 或 CommonJS 的 Fastify 项目。【免费下载链接】typescript-sdkThe official TypeScript SDK for Model Context Protocol servers and clients项目地址: https://gitcode.com/GitHub_Trending/ty/typescript-sdk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考