实战指南:在 Elysia 应用中挂载 Agent、Workflow 与流式 API)
Mastra Elysia 服务器适配器mastra/elysia实战指南在 Elysia 应用中挂载 Agent、Workflow 与流式 API【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本篇指南围绕 Mastra 开源仓库中server-adapters/elysia包的变更记录与其配套源码系统讲解mastra/elysia适配器的设计初衷、安装接入方式、核心请求处理链路、SSE 流式输出、认证鉴权与 OpenAPI 集成方案。读完本文你将掌握如何在一个已有的 Elysia HTTP 应用中嵌入 Mastra 的 Agent、Workflow、Tool、Memory 与流式接口并理解该适配器在底层如何处理路由、请求体解析、参数映射与异常响应。一、什么是mastra/elysia为什么需要它Mastra 是一个 TypeScript 编写的 AI 应用框架核心能力包括 Agent、Workflow、Tool、Memory 等。要让这些能力以 HTTP API 的形式对外暴露Mastra 提供了mastra/server这一与框架无关的服务层以及一组面向具体 Web 框架的服务器适配器Express、Fastify、Hono、NestJS、Elysia 等。根据 server-adapters/elysia/README.md 的定位说明mastra/elysiamounts Mastras agent, workflow, tool, memory, and streaming APIs on an Elysia application. Use it when Elysia is already your HTTP server and you want Mastra endpoints in the same process.即当你的项目已经以 Elysia 作为 HTTP 服务框架时无需另起一个独立服务只需通过mastra/elysia把 Mastra 的 Agent、Workflow、Tool、Memory 以及流式streamingAPI 全部挂载到现有的 Elysia 应用实例上让两者共享同一个进程与端口。这在以下场景尤为合适已有 Elysia 业务 API需要新增 AI 能力而不引入第二个服务进程需要将 Mastra 端点与既有中间件CORS、日志、鉴权在同一管道中统一处理希望复用 Elysia 生态如elysiajs/cors、elysiajs/openapi对 Mastra 路由进行增强。该适配器在 CHANGELOG 的 0.1.0 版本对应 PR #22274中首次引入其发布说明写道Added an Elysia server adapter. Use the new mastra/elysia package to run a Mastra server inside an Elysia app.二、安装与快速开始2.1 安装依赖根据 server-adapters/elysia/package.json该包以mastra/core1.50.0-0 2.0.0-0与elysia^1.4.25为 peer 依赖运行环境要求 Node.js22.13.0npm install mastra/elysia # 确保同时安装 peer 依赖 npm install elysia^1.4.25 npm install mastra/core运行时依赖仅两个mastra/server提供底层的 MastraServer 抽象与路由定义与fetch-to-node用于将 Fetch 语义的请求转换为 Node 的req/res以支撑 MCP 传输。2.2 最小接入示例CHANGELOG 0.1.0 版本给出了官方的最小示例这也是该适配器的标准接线方式import { Elysia } from elysia; import { MastraServer } from mastra/elysia; import { mastra } from ./mastra; const app new Elysia(); const server new MastraServer({ app, mastra }); await server.init(); app.listen(4111);关键点MastraServer构造函数接收{ app, mastra }其中app是 Elysia 应用实例mastra是你通过new Mastra()组装好的实例包含 agents、workflows、storage 等必须先await server.init()再app.listen(...)——init()内部会完成所有 Mastra 路由Agent 执行、Workflow 执行、记忆、流式等向 Elysia 应用的注册端口由 Elysia 的listen()决定Mastra 端点与你的业务端点共享同一端口。从构造函数源码packages/server/src/server/server-adapter/index.ts可以看到MastraServer基类还支持以下可选配置项配置项类型默认值作用prefixstring/api所有 Mastra 路由统一挂载的前缀openapiPathstringOpenAPI 文档的 JSON 路径bodyLimitOptionsBodyLimitOptions无请求体大小限制与超限时的onError回调streamOptionsStreamOptions{ redact: true }流式响应选项敏感数据脱敏开关toolsToolsInput无注入给上下文的自定义工具集合taskStoreInMemoryTaskStore无Agent 后台任务的存储customRouteAuthConfigMapstring, boolean无自定义路由的鉴权开关映射customApiRoutesApiRoute[]无通过registerApiRoute注册的自定义 API 路由mcpOptionsMCPOptions无应用到所有 MCP HTTP/SSE 路由的传输选项2.3 完整可运行示例仓库中的 server-adapters/elysia/examples/index.ts 提供了一个真实可运行的完整示例它构建了一个带weatherTool的天气 Agent、一个基于 Workflow 的行程规划流程并演示了 CORS、OpenAPI 与 Swagger UI 的整合。其核心接线部分import { cors } from elysiajs/cors; import { openapi } from elysiajs/openapi; import { Mastra } from mastra/core; import Elysia from elysia; import { MastraServer, getMastraOpenAPIDoc } from ../src/index; const app new Elysia(); app.use(cors({ origin: * })); // 先创建并初始化 Mastra server const srv new MastraServer({ mastra, openapiPath: /openapi.json, app }); await srv.init(); // 从已初始化的 server 提取 OpenAPI 文档 const mastraOpenAPI getMastraOpenAPIDoc(srv, { title: Mastra API with Weather Agent, version: 1.0.0, }); app.use( openapi({ provider: swagger-ui, path: /swagger-ui, specPath: /openapi.json, documentation: { info: mastraOpenAPI.info, paths: mastraOpenAPI.paths, components: mastraOpenAPI.components, }, }), ); app.listen(3001);启动后即可访问/openapi.json与/swagger-uiMastra 生成的所有端点都会出现在 Swagger UI 中。三、核心实现剖析MastraServer 如何融入 Elysiamastra/elysia的入口文件 server-adapters/elysia/src/index.ts 中定义了MastraServer类它继承自mastra/server/server-adapter导出的抽象基类通过实现若干抽象方法完成与 Elysia 的对接。3.1 路由注册方法链式挂载registerRoute()方法将每条ServerRoute方法、路径、响应类型、处理器按 HTTP 方法映射为 Elysia 的链式调用const method route.method.toLowerCase() as get | post | put | delete | patch | all; appmethod;为了让 Elysia 能接收任意Elysia实例源码还定义了最小接口ElysiaApp只要求use、derive、get/post/put/delete/patch/all、onAfterHandle、onError等能力从而避免泛型严格匹配带来的类型摩擦。3.2 路由参数归一化解决 Elysia 路由冲突这是该适配器一个非常关键的实现细节。Elysia 的路由器要求同一路径段位的参数名一致否则可能冲突。Mastra 内部不同路由在同一段位可能使用不同参数名例如/stored/agents/:storedAgentId与/agents/:agentId。为此源码实现了normalizeRouteParams()将:xxx形式的参数统一改写为:p0、:p1等位置化名称同时记录原始参数名顺序remapParams()在请求进入时再把 Elysia 解析出的p0/p1映射回原始的agentId等参数名保证上层路由处理器拿到的参数名不变。这一层写入时归一化、读取时还原的设计保证了两套路由体系Elysia 的路由表与 Mastra 的ServerRoute可以共存而不冲突。3.3 请求上下文注入createContextMiddleware通过app.derive(createContextMiddleware())适配器为每个请求注入统一的 Elysia 上下文包含{ requestContext, // 合并后的 RequestContext来自 body 或 query mastra, // Mastra 实例 registeredTools, // 已注册工具 taskStore, // 任务存储 abortSignal, // 请求取消信号透传 Elysia 的 ctx.request.signal customRouteAuthConfig, }requestContext的解析策略对应源码createContextMiddleware()POST/PUT/PATCH若Content-Type为application/json尝试从请求体中的requestContext字段提取GET尝试从查询参数requestContext中读取优先按 JSON 解析失败则回退为base64(JSON)解析。随后通过mergeRequestContext与applyRequestMetadataToContext将用户信息、请求元数据如 Header合并进上下文供后续的鉴权、RBAC 与 FGA 检查使用。3.4 请求体与参数解析兼容 Elysia 的预解析Elysia 在进入路由处理器前通常已经解析了ctx.body、ctx.query、ctx.params。适配器对此做了双轨处理JSON body优先使用ctx.bodyElysia 预解析结果若未解析到且声明了 JSON则回退到request.clone().text()手动解析multipart/form-data调用parseFormData()同时兼容原生FormData与 Elysia 的预解析对象格式将File转换为Buffer并尝试把字符串值按 JSON 解析如options字段查询参数通过normalizeQueryParams()展平数组与嵌套对象来自mastra/server/server-adapter的公共工具。任何解析失败都会产生bodyParseError最终由 handler 统一返回结构化的 400 响应{ error: Invalid request body, issues: [...] }。3.5 Zod 校验与错误响应适配器在查询参数、请求体、路径参数三层分别调用基类的parseQueryParams/parseBody/parsePathParams进行 Zod schema 校验与类型强制转换如z.coerce.number()。若抛出 Zod 错误通过resolveValidationError()生成带正确 HTTP 状态码的校验错误响应其余错误则统一包装为 JSON 响应。此外基类导出的getCustomHTTPExceptionResponse被用来保留业务侧显式抛出的自定义 HTTP 异常响应。四、流式响应SSE 与增量序列化Agent 与 Workflow 的流式输出是 Mastra 服务的核心能力之一。MastraServer.stream()实现了从上游ReadableStream到 HTTP 响应的完整转码管道响应头策略按streamFormat区分sse格式Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive、X-Accel-Buffering: nostream格式Content-Type: text/plain数据块以 ASCII 记录分隔符\x1E分隔。关键行为均可在 server-adapters/elysia/src/index.ts 的stream()方法中对应找到连接即冲刷当路由声明sseFlushOnConnect: true时连接建立后立即发送: connected\n\n注释行用于穿透反向代理或触发客户端已连接事件测试见 elysia-adapter.test.ts 的 SSE stream handshake 用例SSE 注释透传以:开头的字符串按原样写入不包裹data:前缀对应测试 should pass SSE comment chunks through without data wrapping敏感数据脱敏默认开启streamOptions.redact true通过redactStreamChunk()移除系统提示词、工具定义、API Key 等敏感字段再下发客户端测试 should redact sensitive data from stream chunks by default 验证SECRET_SYSTEM_PROMPT、secret_tool均不出现在任何 chunk 中设置为{ redact: false }则原样透传不可序列化 chunk 容错对BigInt等JSON.stringify无法处理的值serializeStreamChunk()返回{ ok: false }时跳过该 chunk 并记录日志而不是中断整个流——这是针对 GitHub issue #17821 的回归修复测试见 Stream Chunk Serialization 一节a chunk that JSON.stringify cant handle used to throw inside the stream loop and silently close the HTTP stream结束标记SSE 流结束时追加data: [DONE]\n\n。对于datastream-response、mcp-http、mcp-sse等特殊响应类型sendResponse()还会通过fetch-to-node的toReqRes/toFetchResponse把 Fetch 语义请求转给 MCP 服务端并用createSafeReadableStream()包装上游流——即使上游中途报错也能保留已发送的 chunk 并正常关闭避免客户端挂起。五、认证、授权与自定义路由5.1 认证中间件server-adapters/elysia/src/auth-middleware.ts 导出了createAuthMiddleware用于在 Mastra 之外给 Elysia 路由加一层认证。它支持两种凭证来源Authorization: Bearer token请求头查询参数?apiKey...当缺少 Authorization 头时回退。中间件内部调用mastra/server/auth的coreAuthMiddleware并结合ctx.customRouteAuthConfig标记当前METHOD:path需要认证认证失败时返回结构化的 JSON 错误响应。import { createAuthMiddleware } from mastra/elysia; const app new Elysia(); app.derive(createAuthMiddleware({ mastra, requiresAuth: true }));5.2 路由级鉴权、RBAC 与 FGAregisterRoute()的 handler 在真正执行业务逻辑前依次完成三道检查对应源码注释顺序路由级认证checkRouteAuth()基于requiresAuth配置执行认证RBAC 权限若mastra.getServer()?.auth已配置通过动态加载mastra/core/auth/ee的hasPermission以requestContext.get(userPermissions)校验requiresPermission若版本过低会打印升级提示[mastra/elysia] Auth features require mastra/core 1.6.0FGA关系型访问控制checkRouteFGA()用 URL 参数、查询参数与请求体的合并结果按路由声明的fga规则做细粒度授权。这三层检查同样应用于registerCustomApiRoutes()注册的自定义 API 路由。仓库中 rbac-permissions.test.ts 与 auth-middleware.test.ts 分别覆盖了这两类场景。5.3 自定义 API 路由与错误处理通过registerApiRoute来自mastra/core/server注册的自定义路由会被统一注册到 Elysia并支持鉴权、FGA 与 OpenAPI 元数据测试见 Custom API Routes 一节若自定义路由路径以 serverprefix开头init()会直接拒绝/must not start with \/mastra/避免与内置路由冲突框架内部路由除外registerAuthMiddleware()注册了全局onError钩子把 Elysia 自身的请求体解析/校验错误400 段状态码统一转换为结构化的 JSON 响应而不是 Elysia 默认的纯文本Bad RequestregisterHttpLoggingMiddleware()在启用httpLoggingConfig时通过deriveonAfterHandle记录METHOD path status duration并支持includeQueryParams、includeHeaders与redactHeaders敏感头替换为[REDACTED]。六、OpenAPI 集成让 Mastra 路由进入 Swagger UI这是 0.1.0 版本随适配器一并引入的能力。CHANGELOG 记录Added theconvertCustomRoutesToOpenAPIPathsexport tomastra/server/server-adapterso server adapters can include custom API routes in generated OpenAPI documents.server-adapters/elysia/src/helper.ts 提供两个配套函数getMastraOpenAPIDoc(server, options)从已初始化init()之后的MastraServer提取 OpenAPI 3.1.0 文档。内部流程为基于SERVER_ROUTES调用generateOpenAPIDocument()→ 若有自定义路由则用convertCustomRoutesToOpenAPIPaths()合并进paths→ 若配置了prefix且非/则统一改写所有路径前缀并防双斜杠→ 用WeakMap缓存结果避免重复生成options.clearCache: true可强制重新生成clearMastraOpenAPICache(server?)在路由动态新增后手动失效缓存WeakMap 无法全量清空只能按实例删除。两者的搭配用法已在 2.3 节的示例中展示把getMastraOpenAPIDoc返回的info、paths、components喂给elysiajs/openapi插件即可在/swagger-ui获得完整的 Mastra API 文档包括所有 Zod schema 对应的类型定义。对应的集成测试见 elysia-adapter.test.ts 的 OpenAPI Spec 一节验证openapi: 3.1.0、前缀为/api时的servers覆盖、自定义路由的逐路径servers覆盖等。七、版本演进梳理来自 CHANGELOG从 server-adapters/elysia/CHANGELOG.md 可以清晰看到该适配器的演进脉络版本关键变更0.1.0首个版本新增 Elysia server adapter可在 Elysia 应用内运行 Mastra server同时为mastra/server/server-adapter新增convertCustomRoutesToOpenAPIPaths导出0.1.2 / 0.1.3跟随mastra/core、mastra/server版本升级1.63.x 系列0.1.4更新 README 为准确的最新信息PR #22858从 npm 分发包中移除CHANGELOG.md减小包体积PR #227370.1.5修复路由级超大请求在 handler 执行前被拒绝的问题并保留显式附加的 HTTP 异常响应当宿主解析器已在无Content-Length时消费了请求体路由级限制降级为解析后的安全兜底PR #227280.1.6 / 0.1.7-alpha.x跟随mastra/core、mastra/server1.641.67 系列持续升级其中 0.1.5 的修复说明与本包源码中registerRoute()的体积检查逻辑一一对应当content-length存在且超过route.maxBodySize ?? bodyLimitOptions.maxSize时直接返回 413当请求体已被 Elysia 预解析ctx.body ! undefined、无Content-Length且序列化后字节数超限时同样触发 413 兜底并可调用bodyLimitOptions.onError定制错误响应。依赖关系上该包始终与mastra/core、mastra/server保持同频发布如 0.1.7-alpha.3 依赖mastra/core1.67.0-alpha.3与mastra/server1.67.0-alpha.3升级适配器时需同步关注这两个核心包的版本兼容性。八、测试覆盖与质量保障server-adapters/elysia拥有相当完整的测试矩阵全部位于 server-adapters/elysia/src/tests目录elysia-adapter.test.ts通过共享的createRouteAdapterTestSuite跑通通用路由适配器测试套件并额外覆盖 SSE 握手、流脱敏、不可序列化 chunk、AbortSignal 透传、multipart、OpenAPI、自定义路由等场景auth-middleware.test.ts认证中间件的 Bearer Token / apiKey 场景rbac-permissions.test.tsRBAC 与 FGA 授权链路malformed-json.test.ts、validation-error-hook.test.ts畸形 JSON 与 Zod 校验错误的响应一致性datastream-error-handling.test.ts数据流中途出错的容错行为http-logging.test.tsHTTP 访问日志含脱敏头mcp-routes.test.ts、mcp-transport.test.tsMCP HTTP / SSE 传输的端到端验证server-app-access.test.ts对 Elysia app 实例访问方式的约束。测试通过app.fetch(new Request(...))直接在进程内模拟 HTTP 请求无需真实监听端口即可验证行为部分用例使用startElysiaServer辅助函数启动真实服务。九、小结mastra/elysia是一个设计紧凑、与框架深度集成的服务器适配器它把 Mastra 的 Agent、Workflow、Tool、Memory 与流式能力以标准 HTTP 路由的形式挂载到 Elysia 应用上同时解决了 Elysia 路由参数命名冲突、请求体预解析兼容、Zod 校验错误结构化、SSE 流式输出、敏感数据脱敏、RBAC/FGA 鉴权以及 OpenAPI 文档生成等一系列实际问题。若你的项目已经使用 Elysia接入方式非常直接new MastraServer({ app, mastra })→await server.init()→app.listen(port)。结合 examples/index.ts 中的完整示例与 index.ts 的源码你可以快速把 AI 能力注入既有服务并通过 Swagger UI 即刻获得一份完整的 API 文档。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考