Mastra Express 服务端适配器(@mastra/express)实战指南:将 AI Agent 无缝接入 Express 框架
2026/9/15 17:12:02 网站建设 项目流程

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中抽象基类MastraServer<TApp, TRequest, TResponse>实现(定义见 packages/server/src/server/server-adapter/index.ts#L382),用 Express 原生的ApplicationRequestResponse类型补齐框架特定的路由注册、中间件与流式响应逻辑。因此,使用它不需要引入额外运行时,你手中现成的 Express 中间件生态(express.json()corsswagger-ui-express等)可以继续原样工作。

从 server-adapters/express/package.json 可以看到其依赖关系与运行前提:

  • 运行时依赖:@mastra/server(workspace 包,承载核心服务器逻辑)、@fastify/busboy(用于 multipart/form-data 解析);
  • peer 依赖:@mastra/core >= 1.50.0-0 < 2.0.0-0express ^5.1.0@types/express ^5.0.5,即面向 Express 5;
  • 运行环境:Node.js>= 22.13.0
  • 模块格式:ESM(type: "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.ts

import 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'); });

三段式启动流程:

  1. 创建 Expressapp
  2. new MastraServer({ app, mastra })把 Mastra 实例"挂"到 Express 上;
  3. 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规范化
openapiPathstring''OpenAPI 文档暴露路径,例如'/openapi.json'
bodyLimitOptionsBodyLimitOptions请求体大小限制,{ maxSize, onError }
toolsToolsInput注册到 handler 的工具集合
taskStoreInMemoryTaskStore后台任务存储
customRouteAuthConfigMap<string, 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)。

关于 bodyLimitOptions

BodyLimitOptions定义于 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 /agentsGET /agents/:agentId:列出/查询 Agent;
  • POST /agents/:agentId/stream:SSE 流式执行 Agent(handlers/agents.ts#L1815 定义,responseType: 'stream'streamFormat: 'sse');
  • POST /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 的RequestContext

  • POST/PUT:从application/json请求体中的requestContext字段提取;
  • GET:从 query 参数requestContext提取,先按 JSON 解析,失败则回退 base64(JSON) 解析;
  • 解析结果与mastraregisteredToolstaskStoreabortSignal一起写入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 参数解析(getParams)

Express 版getParams()(server-adapters/express/src/index.ts#L208)统一收集三类入参:

  • 路径参数:直接取req.params
  • 查询参数:经normalizeQueryParams规范化——支持重复参数(?tag=a&tag=b→ 数组)、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。

解析完成后,urlParamsqueryParamsbody会分别经过路由上的pathParamSchema/queryParamSchema/bodySchemazod 运行时校验(如z.coerce.number()类型强转),校验失败返回 400 与结构化错误信息;body 解析失败(如畸形 multipart)同样返回 400(见 index.ts#L484 起的处理分支)。

七、流式响应:SSE、数据脱敏与健壮性

Agent 生成式响应普遍是流式的,Express 适配器在stream()(server-adapters/express/src/index.ts#L147)中做了三件关键事:

  1. 按格式设置响应头streamFormat === 'sse'时设置Content-Type: text/event-streamCache-Control: no-cacheConnection: keep-aliveX-Accel-Buffering: no(防止 nginx 等反向代理缓冲);普通 stream 保持text/plain,并统一以Transfer-Encoding: chunked输出。SSE 头相关行为有专门测试覆盖(express-adapter.test.ts 的 "SSE Headers" 用例组)。

  2. 敏感数据脱敏:默认调用redactStreamChunk(value)剔除流块中的系统提示、工具定义、API Key 等;streamOptions.redact: false可关闭(index.ts#L180)。测试验证默认情况下流中不出现SECRET_SYSTEM_PROMPTsecret_tool等敏感内容。

  3. 序列化容错serializeStreamChunk对每个块做可序列化检查——若某块因包含BigIntJSON.stringify无法处理的值,则记录错误并跳过该块,而不是中断整个 HTTP 流。这正是对 issue #17821(不可序列化块导致流静默中断)的修复(index.ts#L182 与 express-adapter.test.ts 的 "Stream Chunk Serialization" 用例)。

此外,route.sseFlushOnConnecttrue时,连接建立即先写入: 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 /agentsagents:read);权限数组按逻辑或判定;未配置 RBAC 时跳过权限检查(仅认证模式)。FGA(Fine-Grained Authorization)通过checkRouteFGA执行(index.ts#L581)。

需要说明的是:RBAC/FGA 属于 EE(企业版)能力,init()中的validateEELicense()会在生产环境未配置有效许可时抛错并提示设置MASTRA_EE_LICENSE环境变量;本地开发/测试环境不受影响(index.ts#L857)。

8.3 自定义路由认证中间件

@mastra/express额外导出createAuthMiddleware(server-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/servercoreAuthMiddleware,认证失败时按result.statusresult.body直接写回响应;requiresAuth: false时直接放行。

九、自定义 API 路由与 OpenAPI / Swagger

9.1 registerApiRoute 自定义路由

通过@mastra/core/serverregisterApiRoute(Hono 风格)或createRoute(schema 感知风格)声明的路由,可通过customApiRoutes构造参数传入,或配置在mastraserver.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.json'init()后即可访问 OpenAPI 文档;配合swagger-ui-express可以一键获得交互式调试界面。完整写法见下方示例。

十、HTTP 请求日志

registerHttpLoggingMiddleware()(index.ts#L742)在请求finish时输出结构化日志:方法、路径、状态码、耗时(duration: "Xms");可选includeQueryParams记录 query、includeHeaders记录请求头,并对redactHeaders列表中的头(默认包含authorizationcookie)打码为[REDACTED]

该功能由 Mastra 服务器配置server.build.apiReqLogs驱动:true表示启用默认配置;对象形式可进一步定制levelexcludePathsincludeHeadersincludeQueryParamsredactHeaders(配置解析见 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) 组装 Mastra:agents / 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'); });

示例中还演示了带记忆的天气 Agent(Memory+lastMessages: 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.ts:MCP 注册表路由的集成测试;
  • auth-middleware.test.ts:createAuthMiddleware行为测试;
  • rbac-permissions.test.ts:RBAC 权限判定测试。

测试采用真实 HTTP 服务器(随机端口 +fetch)执行请求断言,保证适配器行为与线上一致。

十三、常见问题与注意事项

  • Express 版本:适配器面向 Express 5(peer 依赖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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询