@mastra/server 1.58.0-alpha.12 → 1.58.0-alpha.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/{a2a-B9X-RdWt.js → a2a-CUkzkdTZ.js} +2 -2
  3. package/dist/{a2a-B9X-RdWt.js.map → a2a-CUkzkdTZ.js.map} +1 -1
  4. package/dist/{a2a-D1t2fS2L.cjs → a2a-DzZHH3OH.cjs} +2 -2
  5. package/dist/{a2a-D1t2fS2L.cjs.map → a2a-DzZHH3OH.cjs.map} +1 -1
  6. package/dist/{api-schema-manifest-CFLB0MBA.cjs → api-schema-manifest-BPk3u4B-.cjs} +3 -3
  7. package/dist/{api-schema-manifest-CFLB0MBA.cjs.map → api-schema-manifest-BPk3u4B-.cjs.map} +1 -1
  8. package/dist/{api-schema-manifest-BLv_Z-sd.js → api-schema-manifest-DSelT9XK.js} +3 -3
  9. package/dist/{api-schema-manifest-BLv_Z-sd.js.map → api-schema-manifest-DSelT9XK.js.map} +1 -1
  10. package/dist/{background-tasks-Bzl2tNJq.js → background-tasks-BtWM0sZs.js} +2 -2
  11. package/dist/{background-tasks-Bzl2tNJq.js.map → background-tasks-BtWM0sZs.js.map} +1 -1
  12. package/dist/{background-tasks-DXns62Go.cjs → background-tasks-C5G2jJax.cjs} +2 -2
  13. package/dist/{background-tasks-DXns62Go.cjs.map → background-tasks-C5G2jJax.cjs.map} +1 -1
  14. package/dist/{builder-registry-QAeqpQKB.js → builder-registry-B8KyPAOP.js} +2 -2
  15. package/dist/{builder-registry-QAeqpQKB.js.map → builder-registry-B8KyPAOP.js.map} +1 -1
  16. package/dist/{builder-registry-CTQyg5l5.cjs → builder-registry-Dcou-kzd.cjs} +2 -2
  17. package/dist/{builder-registry-CTQyg5l5.cjs.map → builder-registry-Dcou-kzd.cjs.map} +1 -1
  18. package/dist/{channels-CPTIswT2.js → channels-B9yt3a2P.js} +2 -2
  19. package/dist/{channels-CPTIswT2.js.map → channels-B9yt3a2P.js.map} +1 -1
  20. package/dist/{channels-FoIf30Hv.cjs → channels-BRoq3VKR.cjs} +2 -2
  21. package/dist/{channels-FoIf30Hv.cjs.map → channels-BRoq3VKR.cjs.map} +1 -1
  22. package/dist/docs/SKILL.md +2 -1
  23. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  24. package/dist/docs/references/docs-server-custom-api-routes.md +375 -0
  25. package/dist/docs/references/reference-server-create-route.md +27 -1
  26. package/dist/{dynamic-workflows-CQs6_anZ.js → dynamic-workflows-B0TE8mjA.js} +2 -2
  27. package/dist/{dynamic-workflows-CQs6_anZ.js.map → dynamic-workflows-B0TE8mjA.js.map} +1 -1
  28. package/dist/{dynamic-workflows-CrvwGZj8.cjs → dynamic-workflows-C-6vmau5.cjs} +2 -2
  29. package/dist/{dynamic-workflows-CrvwGZj8.cjs.map → dynamic-workflows-C-6vmau5.cjs.map} +1 -1
  30. package/dist/{editor-builder-D5lhXbvj.js → editor-builder-Byg6wbi6.js} +2 -2
  31. package/dist/{editor-builder-D5lhXbvj.js.map → editor-builder-Byg6wbi6.js.map} +1 -1
  32. package/dist/{editor-builder-DG5-7x6V.cjs → editor-builder-DT7ypWfa.cjs} +2 -2
  33. package/dist/{editor-builder-DG5-7x6V.cjs.map → editor-builder-DT7ypWfa.cjs.map} +1 -1
  34. package/dist/{observability-new-endpoints-D4AWoyDe.cjs → observability-new-endpoints-BC-dasRY.cjs} +2 -2
  35. package/dist/{observability-new-endpoints-D4AWoyDe.cjs.map → observability-new-endpoints-BC-dasRY.cjs.map} +1 -1
  36. package/dist/{observability-new-endpoints-6HLxLS-H.js → observability-new-endpoints-Drx0C8uc.js} +2 -2
  37. package/dist/{observability-new-endpoints-6HLxLS-H.js.map → observability-new-endpoints-Drx0C8uc.js.map} +1 -1
  38. package/dist/{route-builder-BBovb2TE.cjs → route-builder-BAAedfru.cjs} +10 -1
  39. package/dist/{route-builder-BBovb2TE.cjs.map → route-builder-BAAedfru.cjs.map} +1 -1
  40. package/dist/{route-builder-CQkb7tQY.js → route-builder-YQ_gLIvW.js} +10 -1
  41. package/dist/{route-builder-CQkb7tQY.js.map → route-builder-YQ_gLIvW.js.map} +1 -1
  42. package/dist/{routes-CzvDlbRt.cjs → routes-0BEh3stO.cjs} +10 -10
  43. package/dist/{routes-CzvDlbRt.cjs.map → routes-0BEh3stO.cjs.map} +1 -1
  44. package/dist/{routes-D_-O6SS5.js → routes-BsMPy5bu.js} +10 -10
  45. package/dist/{routes-D_-O6SS5.js.map → routes-BsMPy5bu.js.map} +1 -1
  46. package/dist/{schedules-CfNABln2.cjs → schedules-DOK225ZZ.cjs} +2 -2
  47. package/dist/{schedules-CfNABln2.cjs.map → schedules-DOK225ZZ.cjs.map} +1 -1
  48. package/dist/{schedules-DSkYO_Nl.js → schedules-RjPcNOmY.js} +2 -2
  49. package/dist/{schedules-DSkYO_Nl.js.map → schedules-RjPcNOmY.js.map} +1 -1
  50. package/dist/server/handlers/a2a.cjs +1 -1
  51. package/dist/server/handlers/a2a.d.ts +545 -505
  52. package/dist/server/handlers/a2a.d.ts.map +1 -1
  53. package/dist/server/handlers/a2a.js +1 -1
  54. package/dist/server/handlers/agent-builder.cjs +1 -1
  55. package/dist/server/handlers/agent-builder.d.ts +1069 -764
  56. package/dist/server/handlers/agent-builder.d.ts.map +1 -1
  57. package/dist/server/handlers/agent-builder.js +1 -1
  58. package/dist/server/handlers/agent-controller.cjs +1 -1
  59. package/dist/server/handlers/agent-controller.d.ts +1547 -893
  60. package/dist/server/handlers/agent-controller.d.ts.map +1 -1
  61. package/dist/server/handlers/agent-controller.js +1 -1
  62. package/dist/server/handlers/agent-versions.cjs +1 -1
  63. package/dist/server/handlers/agent-versions.d.ts +8476 -8356
  64. package/dist/server/handlers/agent-versions.d.ts.map +1 -1
  65. package/dist/server/handlers/agent-versions.js +1 -1
  66. package/dist/server/handlers/agents.cjs +1 -1
  67. package/dist/server/handlers/agents.d.ts +9502 -9386
  68. package/dist/server/handlers/agents.d.ts.map +1 -1
  69. package/dist/server/handlers/agents.js +1 -1
  70. package/dist/server/handlers/auth.cjs +1 -1
  71. package/dist/server/handlers/auth.d.ts +693 -297
  72. package/dist/server/handlers/auth.d.ts.map +1 -1
  73. package/dist/server/handlers/auth.js +1 -1
  74. package/dist/server/handlers/background-tasks.cjs +1 -1
  75. package/dist/server/handlers/background-tasks.d.ts +190 -130
  76. package/dist/server/handlers/background-tasks.d.ts.map +1 -1
  77. package/dist/server/handlers/background-tasks.js +1 -1
  78. package/dist/server/handlers/builder-registry.cjs +1 -1
  79. package/dist/server/handlers/builder-registry.d.ts +218 -121
  80. package/dist/server/handlers/builder-registry.d.ts.map +1 -1
  81. package/dist/server/handlers/builder-registry.js +1 -1
  82. package/dist/server/handlers/channels.cjs +1 -1
  83. package/dist/server/handlers/channels.d.ts +157 -77
  84. package/dist/server/handlers/channels.d.ts.map +1 -1
  85. package/dist/server/handlers/channels.js +1 -1
  86. package/dist/server/handlers/conversations.cjs +1 -1
  87. package/dist/server/handlers/conversations.d.ts +221 -141
  88. package/dist/server/handlers/conversations.d.ts.map +1 -1
  89. package/dist/server/handlers/conversations.js +1 -1
  90. package/dist/server/handlers/datasets.cjs +1 -1
  91. package/dist/server/handlers/datasets.d.ts +2669 -2234
  92. package/dist/server/handlers/datasets.d.ts.map +1 -1
  93. package/dist/server/handlers/datasets.js +1 -1
  94. package/dist/server/handlers/dynamic-workflows.cjs +1 -1
  95. package/dist/server/handlers/dynamic-workflows.d.ts +506 -426
  96. package/dist/server/handlers/dynamic-workflows.d.ts.map +1 -1
  97. package/dist/server/handlers/dynamic-workflows.js +1 -1
  98. package/dist/server/handlers/editor-builder.cjs +1 -1
  99. package/dist/server/handlers/editor-builder.d.ts +305 -245
  100. package/dist/server/handlers/editor-builder.d.ts.map +1 -1
  101. package/dist/server/handlers/editor-builder.js +1 -1
  102. package/dist/server/handlers/favorites-enrichment.cjs +1 -1
  103. package/dist/server/handlers/favorites-enrichment.js +1 -1
  104. package/dist/server/handlers/logs.cjs +1 -1
  105. package/dist/server/handlers/logs.d.ts +245 -185
  106. package/dist/server/handlers/logs.d.ts.map +1 -1
  107. package/dist/server/handlers/logs.js +1 -1
  108. package/dist/server/handlers/mcp-client-versions.cjs +1 -1
  109. package/dist/server/handlers/mcp-client-versions.d.ts +447 -307
  110. package/dist/server/handlers/mcp-client-versions.d.ts.map +1 -1
  111. package/dist/server/handlers/mcp-client-versions.js +1 -1
  112. package/dist/server/handlers/mcp.cjs +1 -1
  113. package/dist/server/handlers/mcp.d.ts +357 -156
  114. package/dist/server/handlers/mcp.d.ts.map +1 -1
  115. package/dist/server/handlers/mcp.js +1 -1
  116. package/dist/server/handlers/memory.cjs +1 -1
  117. package/dist/server/handlers/memory.d.ts +1723 -1223
  118. package/dist/server/handlers/memory.d.ts.map +1 -1
  119. package/dist/server/handlers/memory.js +1 -1
  120. package/dist/server/handlers/observability-new-endpoints.cjs +1 -1
  121. package/dist/server/handlers/observability-new-endpoints.d.ts +3239 -2158
  122. package/dist/server/handlers/observability-new-endpoints.d.ts.map +1 -1
  123. package/dist/server/handlers/observability-new-endpoints.js +1 -1
  124. package/dist/server/handlers/observability-shared.cjs +1 -1
  125. package/dist/server/handlers/observability-shared.js +1 -1
  126. package/dist/server/handlers/observability.cjs +2 -2
  127. package/dist/server/handlers/observability.d.ts +267 -149
  128. package/dist/server/handlers/observability.d.ts.map +1 -1
  129. package/dist/server/handlers/observability.js +2 -2
  130. package/dist/server/handlers/processor-providers.cjs +1 -1
  131. package/dist/server/handlers/processor-providers.d.ts +74 -34
  132. package/dist/server/handlers/processor-providers.d.ts.map +1 -1
  133. package/dist/server/handlers/processor-providers.js +1 -1
  134. package/dist/server/handlers/processors.cjs +1 -1
  135. package/dist/server/handlers/processors.d.ts +222 -173
  136. package/dist/server/handlers/processors.d.ts.map +1 -1
  137. package/dist/server/handlers/processors.js +1 -1
  138. package/dist/server/handlers/prompt-block-versions.cjs +1 -1
  139. package/dist/server/handlers/prompt-block-versions.d.ts +646 -506
  140. package/dist/server/handlers/prompt-block-versions.d.ts.map +1 -1
  141. package/dist/server/handlers/prompt-block-versions.js +1 -1
  142. package/dist/server/handlers/responses.cjs +1 -1
  143. package/dist/server/handlers/responses.d.ts +352 -362
  144. package/dist/server/handlers/responses.d.ts.map +1 -1
  145. package/dist/server/handlers/responses.js +1 -1
  146. package/dist/server/handlers/schedules.cjs +1 -1
  147. package/dist/server/handlers/schedules.d.ts +1190 -1028
  148. package/dist/server/handlers/schedules.d.ts.map +1 -1
  149. package/dist/server/handlers/schedules.js +1 -1
  150. package/dist/server/handlers/scorer-versions.cjs +1 -1
  151. package/dist/server/handlers/scorer-versions.d.ts +551 -411
  152. package/dist/server/handlers/scorer-versions.d.ts.map +1 -1
  153. package/dist/server/handlers/scorer-versions.js +1 -1
  154. package/dist/server/handlers/scores.cjs +1 -1
  155. package/dist/server/handlers/scores.d.ts +287 -167
  156. package/dist/server/handlers/scores.d.ts.map +1 -1
  157. package/dist/server/handlers/scores.js +1 -1
  158. package/dist/server/handlers/stored-agent-favorites.cjs +2 -2
  159. package/dist/server/handlers/stored-agent-favorites.d.ts +62 -22
  160. package/dist/server/handlers/stored-agent-favorites.d.ts.map +1 -1
  161. package/dist/server/handlers/stored-agent-favorites.js +2 -2
  162. package/dist/server/handlers/stored-agents.cjs +2 -2
  163. package/dist/server/handlers/stored-agents.d.ts +12248 -16428
  164. package/dist/server/handlers/stored-agents.d.ts.map +1 -1
  165. package/dist/server/handlers/stored-agents.js +2 -2
  166. package/dist/server/handlers/stored-mcp-clients.cjs +1 -1
  167. package/dist/server/handlers/stored-mcp-clients.d.ts +417 -324
  168. package/dist/server/handlers/stored-mcp-clients.d.ts.map +1 -1
  169. package/dist/server/handlers/stored-mcp-clients.js +1 -1
  170. package/dist/server/handlers/stored-prompt-blocks.cjs +1 -1
  171. package/dist/server/handlers/stored-prompt-blocks.d.ts +603 -555
  172. package/dist/server/handlers/stored-prompt-blocks.d.ts.map +1 -1
  173. package/dist/server/handlers/stored-prompt-blocks.js +1 -1
  174. package/dist/server/handlers/stored-scorers.cjs +1 -1
  175. package/dist/server/handlers/stored-scorers.d.ts +556 -472
  176. package/dist/server/handlers/stored-scorers.d.ts.map +1 -1
  177. package/dist/server/handlers/stored-scorers.js +1 -1
  178. package/dist/server/handlers/stored-skill-favorites.cjs +2 -2
  179. package/dist/server/handlers/stored-skill-favorites.d.ts +62 -22
  180. package/dist/server/handlers/stored-skill-favorites.d.ts.map +1 -1
  181. package/dist/server/handlers/stored-skill-favorites.js +2 -2
  182. package/dist/server/handlers/stored-skills.cjs +2 -2
  183. package/dist/server/handlers/stored-skills.d.ts +632 -515
  184. package/dist/server/handlers/stored-skills.d.ts.map +1 -1
  185. package/dist/server/handlers/stored-skills.js +2 -2
  186. package/dist/server/handlers/stored-workspaces.cjs +1 -1
  187. package/dist/server/handlers/stored-workspaces.d.ts +646 -546
  188. package/dist/server/handlers/stored-workspaces.d.ts.map +1 -1
  189. package/dist/server/handlers/stored-workspaces.js +1 -1
  190. package/dist/server/handlers/system.cjs +2 -2
  191. package/dist/server/handlers/system.d.ts +146 -106
  192. package/dist/server/handlers/system.d.ts.map +1 -1
  193. package/dist/server/handlers/system.js +2 -2
  194. package/dist/server/handlers/tool-providers.cjs +1 -1
  195. package/dist/server/handlers/tool-providers.d.ts +580 -331
  196. package/dist/server/handlers/tool-providers.d.ts.map +1 -1
  197. package/dist/server/handlers/tool-providers.js +1 -1
  198. package/dist/server/handlers/tools.cjs +1 -1
  199. package/dist/server/handlers/tools.d.ts +177 -77
  200. package/dist/server/handlers/tools.d.ts.map +1 -1
  201. package/dist/server/handlers/tools.js +1 -1
  202. package/dist/server/handlers/vector.cjs +1 -1
  203. package/dist/server/handlers/vector.d.ts +282 -126
  204. package/dist/server/handlers/vector.d.ts.map +1 -1
  205. package/dist/server/handlers/vector.js +1 -1
  206. package/dist/server/handlers/workflows.cjs +1 -1
  207. package/dist/server/handlers/workflows.d.ts +1703 -1181
  208. package/dist/server/handlers/workflows.d.ts.map +1 -1
  209. package/dist/server/handlers/workflows.js +1 -1
  210. package/dist/server/handlers/workspace.cjs +1 -1
  211. package/dist/server/handlers/workspace.d.ts +1936 -1150
  212. package/dist/server/handlers/workspace.d.ts.map +1 -1
  213. package/dist/server/handlers/workspace.js +1 -1
  214. package/dist/server/handlers.cjs +2 -2
  215. package/dist/server/handlers.js +2 -2
  216. package/dist/server/server-adapter/index.cjs +27 -6
  217. package/dist/server/server-adapter/index.cjs.map +1 -1
  218. package/dist/server/server-adapter/index.d.ts +14 -1
  219. package/dist/server/server-adapter/index.d.ts.map +1 -1
  220. package/dist/server/server-adapter/index.js +27 -6
  221. package/dist/server/server-adapter/index.js.map +1 -1
  222. package/dist/server/server-adapter/openapi-utils.d.ts.map +1 -1
  223. package/dist/server/server-adapter/routes/a2a.d.ts +544 -504
  224. package/dist/server/server-adapter/routes/a2a.d.ts.map +1 -1
  225. package/dist/server/server-adapter/routes/agent-builder.d.ts +1054 -749
  226. package/dist/server/server-adapter/routes/agent-builder.d.ts.map +1 -1
  227. package/dist/server/server-adapter/routes/channels.d.ts +153 -73
  228. package/dist/server/server-adapter/routes/channels.d.ts.map +1 -1
  229. package/dist/server/server-adapter/routes/conversations.d.ts +218 -138
  230. package/dist/server/server-adapter/routes/conversations.d.ts.map +1 -1
  231. package/dist/server/server-adapter/routes/datasets.d.ts +2312 -1877
  232. package/dist/server/server-adapter/routes/datasets.d.ts.map +1 -1
  233. package/dist/server/server-adapter/routes/editor-builder.d.ts +506 -349
  234. package/dist/server/server-adapter/routes/editor-builder.d.ts.map +1 -1
  235. package/dist/server/server-adapter/routes/legacy.d.ts +615 -629
  236. package/dist/server/server-adapter/routes/legacy.d.ts.map +1 -1
  237. package/dist/server/server-adapter/routes/logs.d.ts +243 -183
  238. package/dist/server/server-adapter/routes/logs.d.ts.map +1 -1
  239. package/dist/server/server-adapter/routes/mcp.d.ts +347 -147
  240. package/dist/server/server-adapter/routes/mcp.d.ts.map +1 -1
  241. package/dist/server/server-adapter/routes/memory.d.ts +1699 -1199
  242. package/dist/server/server-adapter/routes/memory.d.ts.map +1 -1
  243. package/dist/server/server-adapter/routes/observability.d.ts +2761 -2103
  244. package/dist/server/server-adapter/routes/observability.d.ts.map +1 -1
  245. package/dist/server/server-adapter/routes/processor-providers.d.ts +70 -30
  246. package/dist/server/server-adapter/routes/processor-providers.d.ts.map +1 -1
  247. package/dist/server/server-adapter/routes/processors.d.ts +220 -171
  248. package/dist/server/server-adapter/routes/processors.d.ts.map +1 -1
  249. package/dist/server/server-adapter/routes/responses.d.ts +350 -360
  250. package/dist/server/server-adapter/routes/responses.d.ts.map +1 -1
  251. package/dist/server/server-adapter/routes/route-builder.d.ts +6 -2
  252. package/dist/server/server-adapter/routes/route-builder.d.ts.map +1 -1
  253. package/dist/server/server-adapter/routes/scorers.d.ts +282 -162
  254. package/dist/server/server-adapter/routes/scorers.d.ts.map +1 -1
  255. package/dist/server/server-adapter/routes/stored-mcp-clients.d.ts +821 -588
  256. package/dist/server/server-adapter/routes/stored-mcp-clients.d.ts.map +1 -1
  257. package/dist/server/server-adapter/routes/stored-prompt-blocks.d.ts +1252 -1064
  258. package/dist/server/server-adapter/routes/stored-prompt-blocks.d.ts.map +1 -1
  259. package/dist/server/server-adapter/routes/stored-scorers.d.ts +1046 -822
  260. package/dist/server/server-adapter/routes/stored-scorers.d.ts.map +1 -1
  261. package/dist/server/server-adapter/routes/stored-skills.d.ts +683 -526
  262. package/dist/server/server-adapter/routes/stored-skills.d.ts.map +1 -1
  263. package/dist/server/server-adapter/routes/stored-workspaces.d.ts +637 -537
  264. package/dist/server/server-adapter/routes/stored-workspaces.d.ts.map +1 -1
  265. package/dist/server/server-adapter/routes/system.d.ts +145 -105
  266. package/dist/server/server-adapter/routes/system.d.ts.map +1 -1
  267. package/dist/server/server-adapter/routes/tool-providers.d.ts +566 -317
  268. package/dist/server/server-adapter/routes/tool-providers.d.ts.map +1 -1
  269. package/dist/server/server-adapter/routes/tools.d.ts +103 -43
  270. package/dist/server/server-adapter/routes/tools.d.ts.map +1 -1
  271. package/dist/server/server-adapter/routes/vectors.d.ts +275 -119
  272. package/dist/server/server-adapter/routes/vectors.d.ts.map +1 -1
  273. package/dist/server/server-adapter/routes/workflows.d.ts +1586 -1104
  274. package/dist/server/server-adapter/routes/workflows.d.ts.map +1 -1
  275. package/dist/server/server-adapter/routes/workspace.d.ts +1026 -613
  276. package/dist/server/server-adapter/routes/workspace.d.ts.map +1 -1
  277. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"channels-CPTIswT2.js","names":[],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\nfunction getChannelOrThrow(mastra: Mastra, platform: string): ChannelProvider {\n const channels = Object.values(mastra.channels ?? {});\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = Object.values(mastra.channels ?? {});\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"channels-B9yt3a2P.js","names":[],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\nfunction getChannelOrThrow(mastra: Mastra, platform: string): ChannelProvider {\n const channels = Object.values(mastra.channels ?? {});\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = Object.values(mastra.channels ?? {});\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  const require_http_exception = require("./http-exception-CKDHupKw.cjs");
2
- const require_route_builder = require("./route-builder-BBovb2TE.cjs");
2
+ const require_route_builder = require("./route-builder-BAAedfru.cjs");
3
3
  require("./constants-ChBaIptn.cjs");
4
4
  const require_server_handlers_error = require("./server/handlers/error.cjs");
5
5
  const require_server_handlers_authorship = require("./server/handlers/authorship.cjs");
@@ -227,4 +227,4 @@ Object.defineProperty(exports, "LIST_CHANNEL_PLATFORMS_ROUTE", {
227
227
  }
228
228
  });
229
229
 
230
- //# sourceMappingURL=channels-FoIf30Hv.cjs.map
230
+ //# sourceMappingURL=channels-BRoq3VKR.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"channels-FoIf30Hv.cjs","names":["z","coreFeatures","HTTPException","getCallerAuthorId","hasAdminBypass","hasScopedPermission","createRoute","handleError"],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\nfunction getChannelOrThrow(mastra: Mastra, platform: string): ChannelProvider {\n const channels = Object.values(mastra.channels ?? {});\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = Object.values(mastra.channels ?? {});\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"channels-BRoq3VKR.cjs","names":["z","coreFeatures","HTTPException","getCallerAuthorId","hasAdminBypass","hasScopedPermission","createRoute","handleError"],"sources":["../src/server/schemas/channels.ts","../src/server/handlers/channels.ts"],"sourcesContent":["import { z } from 'zod/v4';\n\n// ============================================================================\n// Path Parameter Schemas\n// ============================================================================\n\nexport const channelPlatformPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n});\n\nexport const channelAgentPathParams = z.object({\n platform: z.string().describe('Channel platform identifier (e.g., \"slack\")'),\n agentId: z.string().describe('Agent identifier'),\n});\n\n// ============================================================================\n// Body Parameter Schemas\n// ============================================================================\n\nexport const connectChannelBodySchema = z.object({\n agentId: z.string().describe('Agent identifier to connect'),\n options: z.record(z.string(), z.unknown()).optional().describe('Platform-specific connection options'),\n});\n\n// ============================================================================\n// Response Schemas\n// ============================================================================\n\nconst channelPlatformInfoSchema = z.object({\n id: z.string().describe('Platform identifier'),\n name: z.string().describe('Human-readable platform name'),\n isConfigured: z.boolean().describe('Whether the platform is ready to connect agents'),\n connectOptionsSchema: z.record(z.string(), z.unknown()).optional().describe('JSON Schema for connect options'),\n});\n\nconst channelInstallationInfoSchema = z.object({\n id: z.string().describe('Installation identifier'),\n platform: z.string().describe('Platform identifier'),\n agentId: z.string().describe('Connected agent identifier'),\n status: z.enum(['active', 'pending']).describe('Installation status'),\n displayName: z.string().optional().describe('Platform-specific display name'),\n installedAt: z.coerce.date().optional().describe('Installation timestamp'),\n});\n\nconst channelConnectOAuthSchema = z.object({\n type: z.literal('oauth').describe('OAuth-based connection requiring browser redirect'),\n authorizationUrl: z.string().describe('OAuth authorization URL for user redirect'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectDeepLinkSchema = z.object({\n type: z.literal('deep_link').describe('Deep-link connection requiring native app interaction'),\n url: z.string().describe('Deep link URL to open in platform app'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectImmediateSchema = z.object({\n type: z.literal('immediate').describe('Immediate connection with no user interaction needed'),\n installationId: z.string().describe('Installation identifier'),\n});\n\nconst channelConnectResultSchema = z.discriminatedUnion('type', [\n channelConnectOAuthSchema,\n channelConnectDeepLinkSchema,\n channelConnectImmediateSchema,\n]);\n\nexport const listChannelPlatformsResponseSchema = z.array(channelPlatformInfoSchema);\n\nexport const listChannelInstallationsResponseSchema = z.array(channelInstallationInfoSchema);\n\nexport const connectChannelResponseSchema = channelConnectResultSchema;\n\nexport const disconnectChannelResponseSchema = z.object({\n success: z.boolean(),\n});\n","import type { Mastra } from '@mastra/core';\nimport type { ChannelProvider } from '@mastra/core/channels';\nimport type { RequestContext } from '@mastra/core/di';\nimport { coreFeatures } from '@mastra/core/features';\n\nimport { MASTRA_USER_KEY } from '../constants';\nimport { HTTPException } from '../http-exception';\nimport {\n channelPlatformPathParams,\n channelAgentPathParams,\n connectChannelBodySchema,\n listChannelPlatformsResponseSchema,\n listChannelInstallationsResponseSchema,\n connectChannelResponseSchema,\n disconnectChannelResponseSchema,\n} from '../schemas/channels';\nimport { createRoute } from '../server-adapter/routes/route-builder';\n\nimport { assertWriteAccess, getCallerAuthorId, hasAdminBypass, hasScopedPermission } from './authorship';\nimport { handleError } from './error';\n\n// ============================================================================\n// Feature gate + helpers\n// ============================================================================\n\nfunction assertChannelsAvailable(): void {\n if (!coreFeatures.has('channels')) {\n throw new HTTPException(501, { message: 'Channels require a newer version of @mastra/core' });\n }\n}\n\nfunction getChannelOrThrow(mastra: Mastra, platform: string): ChannelProvider {\n const channels = Object.values(mastra.channels ?? {});\n const channel = channels.find(c => c.id === platform);\n if (!channel) {\n const available = channels.map(c => c.id).join(', ');\n throw new HTTPException(404, {\n message: `Channel \"${platform}\" is not registered. Available: ${available || 'none'}`,\n });\n }\n return channel;\n}\n\n/**\n * Unified connect/disconnect authorization.\n *\n * - Stored agent exists → same write access as editing the agent record.\n * - Code-defined agent (no stored record) → route's `requiresAuth` is the gate.\n * - Agent doesn't exist anywhere:\n * - connect → 404 (can't connect a channel to a non-existent agent)\n * - disconnect → orphan cleanup, gated on `channels:write`\n */\nasync function assertChannelAgentWriteAccess(\n mastra: Mastra,\n requestContext: RequestContext,\n agentId: string,\n action: 'connect' | 'disconnect',\n): Promise<void> {\n const storage = mastra.getStorage();\n const agentsStore = storage ? await storage.getStore('agents') : null;\n const stored = agentsStore ? await agentsStore.getById(agentId) : null;\n\n if (stored) {\n assertWriteAccess({\n requestContext,\n resource: 'agents',\n resourceId: agentId,\n action: 'edit',\n record: stored,\n });\n return;\n }\n\n // Not in stored-agents (or storage doesn't support it). Check the runtime\n // registry for a code-defined agent.\n const codeDefined = mastra.getAgentById(agentId);\n if (codeDefined) {\n // Code-defined agents have no owner/ACL — route's requiresAuth /\n // requiresPermission is the gate. Pass-through.\n return;\n }\n\n if (action === 'connect') {\n throw new HTTPException(404, { message: `Agent \"${agentId}\" not found` });\n }\n\n // Disconnect against an unknown agentId = orphan cleanup (stored agent was\n // deleted but the channel installation row is still around). Allow it, but\n // gate on channels:write so this isn't an \"any authenticated user\" backdoor.\n // Follow the same no-auth-configured pass-through as assertWriteAccess.\n const callerAuthorId = getCallerAuthorId(requestContext);\n if (!callerAuthorId && !requestContext.get(MASTRA_USER_KEY)) return;\n if (hasAdminBypass(requestContext, 'channels')) return;\n if (hasScopedPermission({ requestContext, resource: 'channels', action: 'write' })) return;\n\n throw new HTTPException(404, { message: 'Not found' });\n}\n\n// ============================================================================\n// Route Definitions\n// ============================================================================\n\n/**\n * GET /channels/platforms - List available channel platforms\n */\nexport const LIST_CHANNEL_PLATFORMS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/platforms',\n responseType: 'json',\n responseSchema: listChannelPlatformsResponseSchema,\n summary: 'List channel platforms',\n description: 'Returns available channel platforms and their configuration status',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra }) => {\n assertChannelsAvailable();\n try {\n const channels = Object.values(mastra.channels ?? {});\n return channels.map(channel => {\n if (channel.getInfo) {\n return channel.getInfo();\n }\n return {\n id: channel.id,\n name: channel.id.charAt(0).toUpperCase() + channel.id.slice(1),\n isConfigured: true,\n };\n });\n } catch (error) {\n return handleError(error, 'Error listing channel platforms');\n }\n },\n});\n\n/**\n * GET /channels/:platform/installations - List installations for a platform\n */\nexport const LIST_CHANNEL_INSTALLATIONS_ROUTE = createRoute({\n method: 'GET',\n path: '/channels/:platform/installations',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n responseSchema: listChannelInstallationsResponseSchema,\n summary: 'List channel installations',\n description: 'Returns all active and pending installations for a channel platform',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, platform }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.listInstallations) {\n return [];\n }\n\n return await channel.listInstallations();\n } catch (error) {\n return handleError(error, 'Error listing channel installations');\n }\n },\n});\n\n/**\n * POST /channels/:platform/connect - Connect an agent to a platform\n */\nexport const CONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/connect',\n responseType: 'json',\n pathParamSchema: channelPlatformPathParams,\n bodySchema: connectChannelBodySchema,\n responseSchema: connectChannelResponseSchema,\n summary: 'Connect agent to channel',\n description: 'Creates a platform app for the agent and returns an OAuth authorization URL',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId, options }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.connect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic connection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'connect');\n\n return await channel.connect(agentId, options);\n } catch (error) {\n return handleError(error, 'Error connecting agent to channel');\n }\n },\n});\n\n/**\n * POST /channels/:platform/:agentId/disconnect - Disconnect an agent from a platform\n */\nexport const DISCONNECT_CHANNEL_ROUTE = createRoute({\n method: 'POST',\n path: '/channels/:platform/:agentId/disconnect',\n responseType: 'json',\n pathParamSchema: channelAgentPathParams,\n responseSchema: disconnectChannelResponseSchema,\n summary: 'Disconnect agent from channel',\n description: 'Deletes the platform app and cleans up the installation',\n tags: ['Channels'],\n requiresAuth: true,\n handler: async ({ mastra, requestContext, platform, agentId }) => {\n assertChannelsAvailable();\n try {\n const channel = getChannelOrThrow(mastra, platform);\n\n if (!channel.disconnect) {\n throw new HTTPException(400, {\n message: `Channel \"${platform}\" does not support programmatic disconnection`,\n });\n }\n\n await assertChannelAgentWriteAccess(mastra, requestContext, agentId, 'disconnect');\n\n await channel.disconnect(agentId);\n return { success: true };\n } catch (error) {\n return handleError(error, 'Error disconnecting agent from channel');\n }\n },\n});\n"],"mappings":"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"}
@@ -3,7 +3,7 @@ name: mastra-server
3
3
  description: Documentation for @mastra/server. Use when working with @mastra/server APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/server"
6
- version: "1.58.0-alpha.12"
6
+ version: "1.58.0-alpha.13"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -18,6 +18,7 @@ Read the individual reference documents for detailed explanations and code examp
18
18
 
19
19
  - [A2A](references/docs-agents-a2a.md) - Expose and call remote Mastra agents over the Agent-to-Agent protocol.
20
20
  - [Custom adapters](references/docs-server-custom-adapters.md) - Create a custom server adapter for frameworks other than Hono or Express.
21
+ - [Custom API routes](references/docs-server-custom-api-routes.md) - Expose additional HTTP endpoints from your Mastra server.
21
22
  - [Middleware](references/docs-server-middleware.md) - Apply custom middleware functions to intercept requests.
22
23
 
23
24
  ### Reference
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.58.0-alpha.12",
2
+ "version": "1.58.0-alpha.13",
3
3
  "package": "@mastra/server",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -0,0 +1,375 @@
1
+ > Discover all available pages from the documentation index: https://mastra.ai/llms.txt
2
+
3
+ # Custom API routes
4
+
5
+ By default, Mastra automatically exposes registered agents and workflows via its server. For additional behavior you can define your own HTTP routes.
6
+
7
+ Routes are provided with a helper `registerApiRoute()` from `@mastra/core/server`. Routes can live in the same file as the `Mastra` instance but separating them helps keep configuration concise.
8
+
9
+ ```typescript
10
+ import { Mastra } from '@mastra/core'
11
+ import { registerApiRoute } from '@mastra/core/server'
12
+
13
+ export const mastra = new Mastra({
14
+ server: {
15
+ apiRoutes: [
16
+ registerApiRoute('/my-custom-route', {
17
+ method: 'GET',
18
+ handler: async c => {
19
+ const mastra = c.get('mastra')
20
+ const agent = await mastra.getAgent('my-agent')
21
+
22
+ return c.json({ message: 'Custom route' })
23
+ },
24
+ }),
25
+ ],
26
+ },
27
+ })
28
+ ```
29
+
30
+ Once registered, a custom route will be accessible from the root of the server. For example:
31
+
32
+ ```bash
33
+ curl http://localhost:4111/my-custom-route
34
+ ```
35
+
36
+ Each route's handler receives the Hono `Context`. Within the handler you can access the `Mastra` instance to fetch or call agents and workflows.
37
+
38
+ ## Schema validation
39
+
40
+ Use [`createRoute()`](https://mastra.ai/reference/server/create-route) in `apiRoutes` to parse and validate path parameters, query parameters, and request bodies with Zod. The schemas also infer the handler parameters and generate OpenAPI metadata.
41
+
42
+ ```typescript
43
+ import { Mastra } from '@mastra/core'
44
+ import { createRoute } from '@mastra/server/server-adapter'
45
+ import { z } from 'zod'
46
+
47
+ const createItemRoute = createRoute({
48
+ method: 'POST',
49
+ path: '/items',
50
+ responseType: 'json',
51
+ bodySchema: z.object({
52
+ name: z.string().min(1),
53
+ }),
54
+ responseSchema: z.object({
55
+ id: z.string(),
56
+ name: z.string(),
57
+ }),
58
+ handler: async ({ name }) => ({
59
+ id: crypto.randomUUID(),
60
+ name,
61
+ }),
62
+ })
63
+
64
+ export const mastra = new Mastra({
65
+ server: {
66
+ apiRoutes: [createItemRoute],
67
+ },
68
+ })
69
+ ```
70
+
71
+ By default, Mastra returns a `400` response when validation fails. The `onValidationError` callback can override the status and response body. Validated values and the `Mastra` server context are passed directly to the handler.
72
+
73
+ ## Middleware
74
+
75
+ To add route-specific middleware pass a `middleware` array when calling `registerApiRoute()`.
76
+
77
+ ```typescript
78
+ import { Mastra } from '@mastra/core'
79
+ import { registerApiRoute } from '@mastra/core/server'
80
+
81
+ export const mastra = new Mastra({
82
+ server: {
83
+ apiRoutes: [
84
+ registerApiRoute('/my-custom-route', {
85
+ method: 'GET',
86
+ middleware: [
87
+ async (c, next) => {
88
+ console.log(`${c.req.method} ${c.req.url}`)
89
+ await next()
90
+ },
91
+ ],
92
+ handler: async c => {
93
+ return c.json({ message: 'Custom route with middleware' })
94
+ },
95
+ }),
96
+ ],
97
+ },
98
+ })
99
+ ```
100
+
101
+ ## OpenAPI documentation
102
+
103
+ Custom routes can include OpenAPI metadata to appear in the Swagger UI alongside Mastra server routes. You can access the OpenAPI spec at `/api/openapi.json`, where both custom routes and built-in routes are listed. Pass an `openapi` option with standard OpenAPI operation fields.
104
+
105
+ ```typescript
106
+ import { Mastra } from '@mastra/core'
107
+ import { registerApiRoute } from '@mastra/core/server'
108
+ import { z } from 'zod'
109
+
110
+ export const mastra = new Mastra({
111
+ server: {
112
+ apiRoutes: [
113
+ registerApiRoute('/items/:itemId', {
114
+ method: 'GET',
115
+ openapi: {
116
+ summary: 'Get item by ID',
117
+ description: 'Retrieves a single item by its unique identifier',
118
+ tags: ['Items'],
119
+ parameters: [
120
+ {
121
+ name: 'itemId',
122
+ in: 'path',
123
+ required: true,
124
+ description: 'The item ID',
125
+ schema: { type: 'string' },
126
+ },
127
+ ],
128
+ responses: {
129
+ 200: {
130
+ description: 'Item found',
131
+ content: {
132
+ 'application/json': {
133
+ schema: {
134
+ type: 'object',
135
+ properties: {
136
+ id: { type: 'string' },
137
+ name: { type: 'string' },
138
+ },
139
+ },
140
+ },
141
+ },
142
+ },
143
+ 404: {
144
+ description: 'Item not found',
145
+ },
146
+ },
147
+ },
148
+ handler: async c => {
149
+ const itemId = c.req.param('itemId')
150
+ return c.json({ id: itemId, name: 'Example Item' })
151
+ },
152
+ }),
153
+ ],
154
+ },
155
+ })
156
+ ```
157
+
158
+ ### Using Zod Schemas
159
+
160
+ Zod schemas in the `openapi` configuration are converted to JSON Schema when the OpenAPI document is generated:
161
+
162
+ ```typescript
163
+ import { Mastra } from '@mastra/core'
164
+ import { registerApiRoute } from '@mastra/core/server'
165
+ import { z } from 'zod'
166
+
167
+ const ItemSchema = z.object({
168
+ id: z.string(),
169
+ name: z.string(),
170
+ price: z.number(),
171
+ })
172
+
173
+ const CreateItemSchema = z.object({
174
+ name: z.string().min(1),
175
+ price: z.number().positive(),
176
+ })
177
+
178
+ export const mastra = new Mastra({
179
+ server: {
180
+ apiRoutes: [
181
+ registerApiRoute('/items', {
182
+ method: 'POST',
183
+ openapi: {
184
+ summary: 'Create a new item',
185
+ tags: ['Items'],
186
+ requestBody: {
187
+ required: true,
188
+ content: {
189
+ 'application/json': {
190
+ schema: CreateItemSchema,
191
+ },
192
+ },
193
+ },
194
+ responses: {
195
+ 201: {
196
+ description: 'Item created',
197
+ content: {
198
+ 'application/json': {
199
+ schema: ItemSchema,
200
+ },
201
+ },
202
+ },
203
+ },
204
+ },
205
+ handler: async c => {
206
+ const body = await c.req.json()
207
+ return c.json({ id: 'new-id', ...body }, 201)
208
+ },
209
+ }),
210
+ ],
211
+ },
212
+ })
213
+ ```
214
+
215
+ ### Viewing in Swagger UI
216
+
217
+ When running in development mode (`mastra dev`) or with `swaggerUI: true` in build options, your custom routes appear in the Swagger UI at `/swagger-ui`.
218
+
219
+ ```typescript
220
+ export const mastra = new Mastra({
221
+ server: {
222
+ build: {
223
+ swaggerUI: true, // Enable in production builds
224
+ },
225
+ apiRoutes: [
226
+ // Your routes...
227
+ ],
228
+ },
229
+ })
230
+ ```
231
+
232
+ ## Authentication
233
+
234
+ When authentication is configured on your Mastra server, custom API routes require authentication by default. To make a route publicly accessible, set `requiresAuth: false`:
235
+
236
+ ```typescript
237
+ import { Mastra } from '@mastra/core'
238
+ import { registerApiRoute } from '@mastra/core/server'
239
+ import { MastraJwtAuth } from '@mastra/auth'
240
+
241
+ export const mastra = new Mastra({
242
+ server: {
243
+ auth: new MastraJwtAuth({
244
+ secret: process.env.MASTRA_JWT_SECRET,
245
+ }),
246
+ apiRoutes: [
247
+ // Protected route (default behavior)
248
+ registerApiRoute('/protected-data', {
249
+ method: 'GET',
250
+ handler: async c => {
251
+ // Access authenticated user from request context
252
+ const user = c.get('requestContext').get('user')
253
+ return c.json({ message: 'Authenticated user', user })
254
+ },
255
+ }),
256
+
257
+ // Public route (no authentication required)
258
+ registerApiRoute('/webhooks/github', {
259
+ method: 'POST',
260
+ requiresAuth: false, // Explicitly opt out of authentication
261
+ handler: async c => {
262
+ const payload = await c.req.json()
263
+ // Process webhook without authentication
264
+ return c.json({ received: true })
265
+ },
266
+ }),
267
+ ],
268
+ },
269
+ })
270
+ ```
271
+
272
+ ### Authentication behavior
273
+
274
+ - **No auth configured**: All routes (built-in and custom) are public
275
+
276
+ - **Auth configured**:
277
+
278
+ - Mastra-provided routes (`/api/agents/*`, `/api/workflows/*`, etc.) require authentication
279
+ - Custom routes require authentication by default
280
+ - Custom routes can opt out with `requiresAuth: false`
281
+
282
+ ### Accessing user information
283
+
284
+ When a request is authenticated, the user object is available in the request context:
285
+
286
+ ```typescript
287
+ registerApiRoute('/user-profile', {
288
+ method: 'GET',
289
+ handler: async c => {
290
+ const requestContext = c.get('requestContext')
291
+ const user = requestContext.get('user')
292
+
293
+ return c.json({ user })
294
+ },
295
+ })
296
+ ```
297
+
298
+ For more information about authentication providers, see the [Auth documentation](https://mastra.ai/docs/server/auth).
299
+
300
+ ## Continue generation after client disconnect
301
+
302
+ Built-in streaming helpers such as [`chatRoute()`](https://mastra.ai/reference/ai-sdk/chat-route) forward the incoming request's `AbortSignal` to `agent.stream()`. That's the right default when a browser disconnect should cancel the model call.
303
+
304
+ For custom streaming routes that should stop when the client disconnects, pass `c.req.raw.signal` to long-running work such as `agent.stream()`. Mastra's Node-based adapters also stop reading streamed `Response` bodies from custom routes when the client connection closes. Streamed response body errors that aren't caused by client disconnects still propagate through the adapter's normal error handling. In Hono, disconnect behavior depends on the host runtime forwarding connection closes to `request.signal`.
305
+
306
+ ```typescript
307
+ registerApiRoute('/stream', {
308
+ method: 'GET',
309
+ handler: async c => {
310
+ const stream = await agent.stream(prompt, {
311
+ abortSignal: c.req.raw.signal,
312
+ })
313
+
314
+ return stream.toTextStreamResponse()
315
+ },
316
+ })
317
+ ```
318
+
319
+ If you want the server to keep generating and persist the final response even after the client disconnects, build a custom route around the underlying `MastraModelOutput`. Start the agent stream without forwarding `c.req.raw.signal`, then call `consumeStream()` in the background so generation continues server-side.
320
+
321
+ ```typescript
322
+ import {
323
+ createUIMessageStream,
324
+ createUIMessageStreamResponse,
325
+ InferUIMessageChunk,
326
+ UIMessage,
327
+ } from 'ai'
328
+ import { toAISdkStream } from '@mastra/ai-sdk'
329
+ import { Mastra } from '@mastra/core'
330
+ import { registerApiRoute } from '@mastra/core/server'
331
+
332
+ export const mastra = new Mastra({
333
+ server: {
334
+ apiRoutes: [
335
+ registerApiRoute('/chat/persist/:agentId', {
336
+ method: 'POST',
337
+ handler: async c => {
338
+ const { messages, memory } = await c.req.json()
339
+ const mastra = c.get('mastra')
340
+ const agent = mastra.getAgent(c.req.param('agentId'))
341
+
342
+ const stream = await agent.stream(messages, {
343
+ memory,
344
+ // Do not pass c.req.raw.signal if this route should keep running
345
+ // after the client disconnects.
346
+ })
347
+
348
+ void stream.consumeStream().catch(error => {
349
+ mastra.getLogger()?.error('Background stream consumption failed', { error })
350
+ })
351
+
352
+ const uiStream = createUIMessageStream({
353
+ originalMessages: messages,
354
+ execute: async ({ writer }) => {
355
+ for await (const part of toAISdkStream(stream, { from: 'agent' })) {
356
+ writer.write(part as InferUIMessageChunk<UIMessage>)
357
+ }
358
+ },
359
+ })
360
+
361
+ return createUIMessageStreamResponse({ stream: uiStream })
362
+ },
363
+ }),
364
+ ],
365
+ },
366
+ })
367
+ ```
368
+
369
+ > **Note:** Use this pattern only when you intentionally want work to continue after the HTTP client is gone. If you want disconnects to cancel generation, keep using `chatRoute()` or forward the request `AbortSignal` yourself.
370
+
371
+ ## Related
372
+
373
+ - [registerApiRoute() Reference](https://mastra.ai/reference/server/register-api-route): Full API reference
374
+ - [Server Middleware](https://mastra.ai/docs/server/middleware): Global middleware configuration
375
+ - [Mastra Server](https://mastra.ai/docs/server/mastra-server): Server configuration options
@@ -72,10 +72,36 @@ handler: async params => {
72
72
 
73
73
  ## Return value
74
74
 
75
- Returns a `ServerRoute` object that can be registered with an adapter.
75
+ Returns a `ServerRoute` object that can be registered with an adapter or passed to `server.apiRoutes` on the `Mastra` instance.
76
76
 
77
77
  ## Examples
78
78
 
79
+ ### Register through `server.apiRoutes`
80
+
81
+ Routes created with `createRoute()` can be passed to `server.apiRoutes`. The adapter registers them with runtime validation, typed handler parameters, and generated OpenAPI metadata. See [Custom API routes](https://mastra.ai/docs/server/custom-api-routes) for details.
82
+
83
+ ```typescript
84
+ import { Mastra } from '@mastra/core'
85
+ import { createRoute } from '@mastra/server/server-adapter'
86
+ import { z } from 'zod'
87
+
88
+ const createItemRoute = createRoute({
89
+ method: 'POST',
90
+ path: '/items',
91
+ responseType: 'json',
92
+ bodySchema: z.object({
93
+ name: z.string(),
94
+ }),
95
+ handler: async ({ name }) => ({ id: 'new-id', name }),
96
+ })
97
+
98
+ export const mastra = new Mastra({
99
+ server: {
100
+ apiRoutes: [createItemRoute],
101
+ },
102
+ })
103
+ ```
104
+
79
105
  ### GET route with path params
80
106
 
81
107
  ```typescript
@@ -1,6 +1,6 @@
1
1
  import { n as __exportAll } from "./rolldown-runtime-DuvcJU0W.js";
2
2
  import { t as HTTPException } from "./http-exception-CyfxZB6W.js";
3
- import { n as createRoute } from "./route-builder-CQkb7tQY.js";
3
+ import { n as createRoute } from "./route-builder-YQ_gLIvW.js";
4
4
  import { handleError } from "./server/handlers/error.js";
5
5
  import { z } from "zod/v4";
6
6
  //#region src/server/schemas/dynamic-workflows.ts
@@ -335,4 +335,4 @@ const DELETE_DYNAMIC_WORKFLOW_ROUTE = createRoute({
335
335
  //#endregion
336
336
  export { dynamic_workflows_exports as a, UPSERT_DYNAMIC_WORKFLOW_ROUTE as i, GET_DYNAMIC_WORKFLOW_ROUTE as n, LIST_DYNAMIC_WORKFLOWS_ROUTE as r, DELETE_DYNAMIC_WORKFLOW_ROUTE as t };
337
337
 
338
- //# sourceMappingURL=dynamic-workflows-CQs6_anZ.js.map
338
+ //# sourceMappingURL=dynamic-workflows-B0TE8mjA.js.map