Mastra Express 服务端适配器(@mastra/express)实战指南:将 AI Agent 无缝接入 Express 框架
Mastra Express 服务端适配器mastra/express实战指南将 AI Agent 无缝接入 Express 框架【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本篇指南系统讲解 Mastra 官方 Express 服务端适配器mastra/express的安装、初始化与深度配置。它面向希望在既有 Express 应用中托管 Mastra Agent、Workflow、Memory 与 MCP 服务的开发者帮助你将一个普通的express()应用升级为完整的 AI 服务端通过MastraServer自动注册一套基于 OpenAPI 的 REST/SSE 路由并集成认证Auth、RBAC 权限、FGA 授权、流式响应脱敏、multipart 上传与 HTTP 日志等能力。读完本文你将掌握MastraServer的构造参数、init()生命周期、请求参数解析链路与流式输出原理并能直接复制文中示例投入实战。一、mastra/express 是什么mastra/express是 Mastra 为 Express 中写得很明确Express server adapter for Mastra, enabling you to run Mastra with the Express framework。与 Hono、Fastify 等适配器一样它通过继承mastra/server中抽象基类MastraServerTApp, TRequest, TResponse实现定义见 packages/server/src/server/server-adapter/index.ts#L382用 Express 原生的Application、Request、Response类型补齐框架特定的路由注册、中间件与流式响应逻辑。因此使用它不需要引入额外运行时你手中现成的 Express 中间件生态express.json()、cors、swagger-ui-express等可以继续原样工作。从 server-adapters/express/package.json 可以看到其依赖关系与运行前提运行时依赖mastra/serverworkspace 包承载核心服务器逻辑、fastify/busboy用于 multipart/form-data 解析peer 依赖mastra/core 1.50.0-0 2.0.0-0、express ^5.1.0、types/express ^5.0.5即面向 Express 5运行环境Node.js 22.13.0模块格式ESMtype: module同时通过dist/index.cjs提供 CJS 入口。二、安装在项目根目录执行npm install mastra/express安装完成后建议同步确认express、types/express与mastra/core满足上面列出的版本范围Express 5 与 Node 22避免运行时类型不匹配。三、最小可用示例沿用官方 README 给出的最小用法server-adapters/express/README.md创建一个server.tsimport express from express; import { MastraServer } from mastra/express; import { mastra } from ./mastra; // 你的 Mastra 实例包含 agents / workflows / tools 等 const app express(); const server new MastraServer({ app, mastra }); await server.init(); app.listen(3000, () { console.log(Server running on http://localhost:3000); });三段式启动流程创建 Expressapp用new MastraServer({ app, mastra })把 Mastra 实例挂到 Express 上await server.init()完成全部路由与中间件注册之后照常app.listen(port)。init()内部按固定顺序执行见 packages/server/src/server/server-adapter/index.ts#L840注册上下文中间件 → 注册认证中间件 → 校验 auth 资源作用域 → 注册用户中间件 → 注册 HTTP 日志中间件 → 校验 EE 许可RBAC/FGA 场景→ 注册自定义 API 路由 → 注册内置路由。这也解释了为什么必须在init()之后才能接收请求。四、MastraServer 构造参数详解MastraServer的构造函数支持以下选项完整定义见 packages/server/src/server/server-adapter/index.ts#L411参数类型默认值说明appApplication必填Express 应用实例mastraMastra必填Mastra 核心实例prefixstring/api所有内置路由的路径前缀经normalizeRoutePath规范化openapiPathstringOpenAPI 文档暴露路径例如/openapi.jsonbodyLimitOptionsBodyLimitOptions无请求体大小限制{ maxSize, onError }toolsToolsInput无注册到 handler 的工具集合taskStoreInMemoryTaskStore无后台任务存储customRouteAuthConfigMapstring, boolean无自定义路由的认证开关method:path→ 是否需要认证streamOptionsStreamOptions{ redact: true }流式响应选项默认开启敏感数据脱敏customApiRoutesApiRoute[]无registerApiRoute/createRoute定义的自定义路由mcpOptionsMCPOptions无应用到所有 MCP HTTP/SSE 传输的选项其中两个值得展开的参数prefix决定内置路由挂在哪个路径下。默认/api于是 Agent 相关接口形如POST /api/agents/:agentId/stream。若设为/mastra则所有内置路由整体前移。streamOptions.redact默认为true表示流出前会脱敏流式块中的系统提示词、工具定义、API Key 等敏感信息调试或内部服务需要原始请求数据时可显式设为falseStreamOptions定义见 packages/server/src/server/server-adapter/index.ts#L94。关于 bodyLimitOptionsBodyLimitOptions定义于 packages/server/src/server/server-adapter/index.ts#L89结构为interface BodyLimitOptions { maxSize: number; // 字节数上限 onError: (error: unknown) unknown; // 超限时的自定义错误响应 }在 Express 适配器中该限制通过注册在路由前的专用中间件实现见 server-adapters/express/src/index.ts#L429优先读取Content-Length头比对当无该头如 chunked 编码时会在express.json()已解析 body 之后回退为Buffer.byteLength(JSON.stringify(req.body))重新度量。超限统一返回413 Request body too large并允许通过onError定制响应体。route.maxBodySize可以按路由覆盖全局配置。五、init() 后自动获得的内置路由能力init()中最终执行的registerRoutes()会注册SERVER_ROUTES——这是mastra/server预定义的全套 REST 路由汇总见 packages/server/src/server/server-adapter/routes/index.ts#L165按领域划分为Agents、Auth、Workflows、Tools、Processors、Responses、Conversations、Memory、Scores、Observability、Logs、Vectors、A2A、Workspace、MCP、Schedules、Channels 等。以 Agent 领域为例packages/server/src/server/server-adapter/routes/agents.ts核心路由包括GET /agents与GET /agents/:agentId列出/查询 AgentPOST /agents/:agentId/streamSSE 流式执行 Agenthandlers/agents.ts#L1815 定义responseType: stream、streamFormat: ssePOST /agents/:agentId/send-message向活跃运行发送消息或开启带 memory 的线程运行handlers/agents.ts#L2160。也就是说一旦完成init()你的 Express 应用就自动获得了运行 Agent、管理线程记忆、执行工作流、查询可观测数据、接入 MCP等完整 HTTP 能力面无需手写任何 handler。六、请求上下文与参数解析链路Express 实现细节6.1 RequestContext 中间件Express 适配器在createContextMiddleware()中server-adapters/express/src/index.ts#L79负责把 HTTP 请求翻译成 Mastra 的RequestContextPOST/PUT从application/json请求体中的requestContext字段提取GET从 query 参数requestContext提取先按 JSON 解析失败则回退 base64(JSON) 解析解析结果与mastra、registeredTools、taskStore、abortSignal一起写入res.locals供后续 handler 使用。值得一提的是AbortController 的挂载点代码注释明确指出应监听res.on(close)而非req.on(close)——请求对象的close事件会在请求体被express.json()消费完毕后立即触发并不代表客户端断开响应对象的close才对应底层连接真正关闭。仅在响应未完成写入时controller.abort()从而把客户端中途取消正确传递给 Agent/工作流执行相关测试见 express-adapter.test.ts 的 Abort Signal 用例组。6.2 参数解析getParamsExpress 版getParams()server-adapters/express/src/index.ts#L208统一收集三类入参路径参数直接取req.params查询参数经normalizeQueryParams规范化——支持重复参数?tagatagb→ 数组、orderBy[field]createdAt括号记法重构成 JSON 字符串便于z.preprocess(JSON.parse)校验实现见 packages/server/src/server/server-adapter/index.ts#L327请求体对POST/PUT/PATCH/DELETE生效。multipart/form-data走fastify/busboy专用解析见 index.ts#L249文件字段转为Buffer普通字段若可被JSON.parse则自动对象化例如options字段文件大小超限抛出File size limit exceeded并交由上层转成 413。解析完成后urlParams、queryParams、body会分别经过路由上的pathParamSchema/queryParamSchema/bodySchema做zod 运行时校验如z.coerce.number()类型强转校验失败返回 400 与结构化错误信息body 解析失败如畸形 multipart同样返回 400见 index.ts#L484 起的处理分支。七、流式响应SSE、数据脱敏与健壮性Agent 生成式响应普遍是流式的Express 适配器在stream()server-adapters/express/src/index.ts#L147中做了三件关键事按格式设置响应头streamFormat sse时设置Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive、X-Accel-Buffering: no防止 nginx 等反向代理缓冲普通 stream 保持text/plain并统一以Transfer-Encoding: chunked输出。SSE 头相关行为有专门测试覆盖express-adapter.test.ts 的 SSE Headers 用例组。敏感数据脱敏默认调用redactStreamChunk(value)剔除流块中的系统提示、工具定义、API Key 等streamOptions.redact: false可关闭index.ts#L180。测试验证默认情况下流中不出现SECRET_SYSTEM_PROMPT、secret_tool等敏感内容。序列化容错serializeStreamChunk对每个块做可序列化检查——若某块因包含BigInt等JSON.stringify无法处理的值则记录错误并跳过该块而不是中断整个 HTTP 流。这正是对 issue #17821不可序列化块导致流静默中断的修复index.ts#L182 与 express-adapter.test.ts 的 Stream Chunk Serialization 用例。此外route.sseFlushOnConnect为true时连接建立即先写入: connected\n\n注释帧以尽早刷出响应便于负载均衡与客户端感知连接成功。除流式外sendResponse()index.ts#L301还支持四种响应类型jsonres.json(result)stream上述流式处理datastream-response把 AI SDK 的Response对象头、状态码与 body 原样管道到 Express 响应中途出错会取消 reader 并记录日志mcp-http/mcp-sse将请求委托给 MCP 服务器的 Streamable HTTP 或 SSE 传输支持类级mcpOptions与路由级选项合并。八、认证、权限与授权8.1 路由级认证Express 适配器不在全局挂认证中间件而是在registerRoute()内对每个路由调用checkRouteAuth()index.ts#L459其核心逻辑位于基类的 checkRouteAuth依据x-mastra-client-type: studio头在 studio auth 与 server auth 之间路由有 studio auth 时绝不停回退到 server auth防止伪造头越权支持route.requiresAuth false的路由级放行Token 提取顺序Authorization: Bearer ...→?apiKey认证结果若携带刷新头如 token 刷新后的Set-Cookie会先写回响应再决定是否拒绝。8.2 权限RBAC与 FGA当配置了 RBAC provider 时checkRoutePermission()会按约定式权限推导执行检查路由未显式声明requiresPermission时从路径与方法推导如GET /agents→agents:read权限数组按逻辑或判定未配置 RBAC 时跳过权限检查仅认证模式。FGAFine-Grained Authorization通过checkRouteFGA执行index.ts#L581。需要说明的是RBAC/FGA 属于 EE企业版能力init()中的validateEELicense()会在生产环境未配置有效许可时抛错并提示设置MASTRA_EE_LICENSE环境变量本地开发/测试环境不受影响index.ts#L857。8.3 自定义路由认证中间件mastra/express额外导出createAuthMiddlewareserver-adapters/express/src/auth-middleware.ts用于给你自己定义的 Express 路由接入同一套 Mastra 认证import { createAuthMiddleware } from mastra/express; app.use( /my-private-route, createAuthMiddleware({ mastra, requiresAuth: true }), (req, res) res.json({ secret: true }), );它从Authorization: Bearer或?apiKey提取令牌调用mastra/server的coreAuthMiddleware认证失败时按result.status与result.body直接写回响应requiresAuth: false时直接放行。九、自定义 API 路由与 OpenAPI / Swagger9.1 registerApiRoute 自定义路由通过mastra/core/server的registerApiRouteHono 风格或createRouteschema 感知风格声明的路由可通过customApiRoutes构造参数传入或配置在mastra的server.apiRoutes中。Express 适配器在registerCustomApiRoutes()index.ts#L635中用 Express 中间件承接请求命中受保护自定义路由时先跑认证/权限/FGA 检查然后经handleCustomRouteRequest桥接到自定义 handler测试见 express-adapter.test.ts 的 Custom API Routes 用例组。createRoute风格的路由自带bodySchema等 zod 校验——测试用例验证了{ name: 42 }发送到要求name: z.string()的路由会返回 400这一行为。9.2 OpenAPI 与 Swagger UI构造时传入openapiPath: /openapi.jsoninit()后即可访问 OpenAPI 文档配合swagger-ui-express可以一键获得交互式调试界面。完整写法见下方示例。十、HTTP 请求日志registerHttpLoggingMiddleware()index.ts#L742在请求finish时输出结构化日志方法、路径、状态码、耗时duration: Xms可选includeQueryParams记录 query、includeHeaders记录请求头并对redactHeaders列表中的头默认包含authorization、cookie打码为[REDACTED]。该功能由 Mastra 服务器配置server.build.apiReqLogs驱动true表示启用默认配置对象形式可进一步定制level、excludePaths、includeHeaders、includeQueryParams、redactHeaders配置解析见 packages/server/src/server/server-adapter/index.ts#L465。excludePaths采用段感知匹配/health排除/health与/health/deep但保留/healthcheck。十一、端到端完整示例来自仓库 examples仓库自带的 server-adapters/express/examples/index.ts 是一个可直接运行的完整演示整合了本适配器的全部核心能力。其关键组装逻辑如下import { Mastra } from mastra/core; import { Agent } from mastra/core/agent; import { createTool } from mastra/core/tools; import { createStep, createWorkflow } from mastra/core/workflows; import { LibSQLStore } from mastra/libsql; import { Memory } from mastra/memory; import { Observability } from mastra/observability; import cors from cors; import express from express; import swaggerUi from swagger-ui-express; import { MastraServer } from ../src/index; // 1) 存储与记忆 const storage new LibSQLStore({ id: express-storage, url: file:./mastra.db }); // 2) 组装 Mastraagents / workflows / tools / storage / observability const mastra new Mastra({ agents: { weatherAgent, planningAgent /* ... */ }, workflows: { weatherWorkflow, travelAgentWorkflow }, tools: { weatherTool }, storage, observability: new Observability({ default: { enabled: true } }), }); // 3) 创建 Express 应用并挂载适配器 const app express(); app.use(express.json()); app.use(cors()); const expressServerAdapter new MastraServer({ mastra, app, openapiPath: /openapi.json }); await expressServerAdapter.init(); // 4) 追加 Swagger UI指向自动生成的 OpenAPI 文档 app.use(/swagger-ui, swaggerUi.serve, swaggerUi.setup(undefined, { swaggerUrl: /openapi.json })); // 5) 启动 app.listen(3001, () { console.info(Server is running on port 3001); console.info(OpenAPI spec: http://localhost:3001/openapi.json); console.info(Swagger UI: http://localhost:3001/swagger-ui); });示例中还演示了带记忆的天气 AgentMemorylastMessages: 10、带 suspend/resume 的人工介入工作流humanInputStep、以及基于createScorer的 Agent 评估打分器展示了一个生产级 Agent 服务可以叠加的完整能力栈。十二、测试与质量保障mastra/express的测试集中在 server-adapters/express/src/tests目录是理解适配器行为边界的绝佳参考express-adapter.test.ts复用internal/server-adapter-test-utils的统一适配器测试套件覆盖路由注册、SSE 响应头、流数据脱敏、不可序列化块容错、AbortSignal 生命周期、multipart 上传、body 大小限制、自定义路由认证等mcp-routes.test.tsMCP 注册表路由的集成测试auth-middleware.test.tscreateAuthMiddleware行为测试rbac-permissions.test.tsRBAC 权限判定测试。测试采用真实 HTTP 服务器随机端口 fetch执行请求断言保证适配器行为与线上一致。十三、常见问题与注意事项Express 版本适配器面向 Express 5peer 依赖express ^5.1.0、types/express ^5.0.5使用 Express 4 时需先升级Node 版本要求 Node 22.13.0不要忘记await server.init()所有内置路由、认证与日志中间件都在这一步注册跳过会导致路由 404默认路由前缀为/api通过prefix可整体调整自定义路由路径若与内置前缀冲突init()会校验并抛出 must not start with /api 之类的错误有专门测试覆盖SSE 流经代理部署到 nginx 等反向代理后务必保留X-Accel-Buffering: no语义避免代理缓冲导致流式延迟敏感信息脱敏默认开启调试内部服务时如需完整请求数据可显式设置streamOptions: { redact: false }但生产环境不建议关闭。十四、小结mastra/express以极小的接入成本把 Mastra 的整套 AI 服务能力注入 Express 应用一次init()自动注册涵盖 Agent、Workflow、Memory、MCP、可观测性等领域的 REST 路由并提供 SSE 流式输出、敏感数据脱敏、zod 运行时校验、multipart 上传、认证/RBAC/FGA、HTTP 日志与 OpenAPI 文档。其 Express 专属实现res.on(close)驱动的中断传播、fastify/busboy表单解析、SSE 反代理缓冲头等充分照顾了 Express 生态的实际运行细节。若你需要将 Mastra 托管到 Fastify、Hono、NestJS 等其他框架仓库中的 server-adapters 目录提供了同等能力的兄弟适配器可供参考。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考