@mastra/mcp-docs-server 0.0.0-commonjs-20250414101718

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 (254) hide show
  1. package/.docs/organized/changelogs/%40mastra%2Fastra.md +302 -0
  2. package/.docs/organized/changelogs/%40mastra%2Fchroma.md +302 -0
  3. package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +161 -0
  4. package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +302 -0
  5. package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +110 -0
  6. package/.docs/organized/changelogs/%40mastra%2Fcore.md +302 -0
  7. package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +302 -0
  8. package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +302 -0
  9. package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +302 -0
  10. package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +302 -0
  11. package/.docs/organized/changelogs/%40mastra%2Fevals.md +302 -0
  12. package/.docs/organized/changelogs/%40mastra%2Ffirecrawl.md +302 -0
  13. package/.docs/organized/changelogs/%40mastra%2Fgithub.md +302 -0
  14. package/.docs/organized/changelogs/%40mastra%2Floggers.md +302 -0
  15. package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +302 -0
  16. package/.docs/organized/changelogs/%40mastra%2Fmcp-registry-registry.md +26 -0
  17. package/.docs/organized/changelogs/%40mastra%2Fmcp.md +302 -0
  18. package/.docs/organized/changelogs/%40mastra%2Fmem0.md +196 -0
  19. package/.docs/organized/changelogs/%40mastra%2Fmemory.md +302 -0
  20. package/.docs/organized/changelogs/%40mastra%2Fpg.md +302 -0
  21. package/.docs/organized/changelogs/%40mastra%2Fpinecone.md +302 -0
  22. package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +302 -0
  23. package/.docs/organized/changelogs/%40mastra%2Fqdrant.md +302 -0
  24. package/.docs/organized/changelogs/%40mastra%2Frag.md +302 -0
  25. package/.docs/organized/changelogs/%40mastra%2Fragie.md +302 -0
  26. package/.docs/organized/changelogs/%40mastra%2Fserver.md +302 -0
  27. package/.docs/organized/changelogs/%40mastra%2Fspeech-azure.md +302 -0
  28. package/.docs/organized/changelogs/%40mastra%2Fspeech-deepgram.md +302 -0
  29. package/.docs/organized/changelogs/%40mastra%2Fspeech-elevenlabs.md +302 -0
  30. package/.docs/organized/changelogs/%40mastra%2Fspeech-google.md +302 -0
  31. package/.docs/organized/changelogs/%40mastra%2Fspeech-ibm.md +302 -0
  32. package/.docs/organized/changelogs/%40mastra%2Fspeech-murf.md +302 -0
  33. package/.docs/organized/changelogs/%40mastra%2Fspeech-openai.md +302 -0
  34. package/.docs/organized/changelogs/%40mastra%2Fspeech-playai.md +302 -0
  35. package/.docs/organized/changelogs/%40mastra%2Fspeech-replicate.md +302 -0
  36. package/.docs/organized/changelogs/%40mastra%2Fspeech-speechify.md +302 -0
  37. package/.docs/organized/changelogs/%40mastra%2Fturbopuffer.md +302 -0
  38. package/.docs/organized/changelogs/%40mastra%2Fupstash.md +302 -0
  39. package/.docs/organized/changelogs/%40mastra%2Fvectorize.md +302 -0
  40. package/.docs/organized/changelogs/%40mastra%2Fvoice-azure.md +250 -0
  41. package/.docs/organized/changelogs/%40mastra%2Fvoice-cloudflare.md +250 -0
  42. package/.docs/organized/changelogs/%40mastra%2Fvoice-deepgram.md +302 -0
  43. package/.docs/organized/changelogs/%40mastra%2Fvoice-elevenlabs.md +302 -0
  44. package/.docs/organized/changelogs/%40mastra%2Fvoice-google.md +302 -0
  45. package/.docs/organized/changelogs/%40mastra%2Fvoice-murf.md +302 -0
  46. package/.docs/organized/changelogs/%40mastra%2Fvoice-openai-realtime.md +302 -0
  47. package/.docs/organized/changelogs/%40mastra%2Fvoice-openai.md +302 -0
  48. package/.docs/organized/changelogs/%40mastra%2Fvoice-playai.md +302 -0
  49. package/.docs/organized/changelogs/%40mastra%2Fvoice-sarvam.md +302 -0
  50. package/.docs/organized/changelogs/%40mastra%2Fvoice-speechify.md +302 -0
  51. package/.docs/organized/changelogs/create-mastra.md +302 -0
  52. package/.docs/organized/changelogs/mastra.md +302 -0
  53. package/.docs/organized/code-examples/agent-network.md +282 -0
  54. package/.docs/organized/code-examples/agent.md +388 -0
  55. package/.docs/organized/code-examples/ai-sdk-useChat.md +378 -0
  56. package/.docs/organized/code-examples/assistant-ui.md +37 -0
  57. package/.docs/organized/code-examples/bird-checker-with-express.md +235 -0
  58. package/.docs/organized/code-examples/bird-checker-with-nextjs-and-eval.md +360 -0
  59. package/.docs/organized/code-examples/bird-checker-with-nextjs.md +250 -0
  60. package/.docs/organized/code-examples/client-side-tools.md +69 -0
  61. package/.docs/organized/code-examples/crypto-chatbot.md +96 -0
  62. package/.docs/organized/code-examples/fireworks-r1.md +159 -0
  63. package/.docs/organized/code-examples/mcp-registry-registry.md +63 -0
  64. package/.docs/organized/code-examples/memory-todo-agent.md +164 -0
  65. package/.docs/organized/code-examples/memory-with-context.md +167 -0
  66. package/.docs/organized/code-examples/memory-with-libsql.md +204 -0
  67. package/.docs/organized/code-examples/memory-with-mem0.md +121 -0
  68. package/.docs/organized/code-examples/memory-with-pg.md +224 -0
  69. package/.docs/organized/code-examples/memory-with-upstash.md +268 -0
  70. package/.docs/organized/code-examples/quick-start.md +129 -0
  71. package/.docs/organized/code-examples/stock-price-tool.md +124 -0
  72. package/.docs/organized/code-examples/weather-agent.md +353 -0
  73. package/.docs/organized/code-examples/workflow-ai-recruiter.md +159 -0
  74. package/.docs/organized/code-examples/workflow-with-inline-steps.md +111 -0
  75. package/.docs/organized/code-examples/workflow-with-memory.md +393 -0
  76. package/.docs/organized/code-examples/workflow-with-separate-steps.md +131 -0
  77. package/.docs/raw/agents/adding-tools.mdx +317 -0
  78. package/.docs/raw/agents/adding-voice.mdx +175 -0
  79. package/.docs/raw/agents/agent-memory.mdx +62 -0
  80. package/.docs/raw/agents/mcp-guide.mdx +215 -0
  81. package/.docs/raw/agents/overview.mdx +303 -0
  82. package/.docs/raw/community/discord.mdx +12 -0
  83. package/.docs/raw/community/licensing.mdx +63 -0
  84. package/.docs/raw/deployment/client.mdx +120 -0
  85. package/.docs/raw/deployment/deployment.mdx +127 -0
  86. package/.docs/raw/deployment/server.mdx +282 -0
  87. package/.docs/raw/evals/custom-eval.mdx +22 -0
  88. package/.docs/raw/evals/overview.mdx +95 -0
  89. package/.docs/raw/evals/running-in-ci.mdx +81 -0
  90. package/.docs/raw/evals/textual-evals.mdx +54 -0
  91. package/.docs/raw/faq/index.mdx +63 -0
  92. package/.docs/raw/frameworks/ai-sdk.mdx +296 -0
  93. package/.docs/raw/frameworks/next-js.mdx +238 -0
  94. package/.docs/raw/getting-started/installation.mdx +442 -0
  95. package/.docs/raw/getting-started/mcp-docs-server.mdx +141 -0
  96. package/.docs/raw/getting-started/project-structure.mdx +80 -0
  97. package/.docs/raw/index.mdx +22 -0
  98. package/.docs/raw/integrations/index.mdx +213 -0
  99. package/.docs/raw/local-dev/add-to-existing-project.mdx +48 -0
  100. package/.docs/raw/local-dev/creating-a-new-project.mdx +54 -0
  101. package/.docs/raw/local-dev/mastra-dev.mdx +108 -0
  102. package/.docs/raw/memory/memory-processors.mdx +131 -0
  103. package/.docs/raw/memory/overview.mdx +119 -0
  104. package/.docs/raw/memory/semantic-recall.mdx +122 -0
  105. package/.docs/raw/memory/working-memory.mdx +87 -0
  106. package/.docs/raw/observability/logging.mdx +38 -0
  107. package/.docs/raw/observability/nextjs-tracing.mdx +108 -0
  108. package/.docs/raw/observability/tracing.mdx +115 -0
  109. package/.docs/raw/rag/chunking-and-embedding.mdx +156 -0
  110. package/.docs/raw/rag/overview.mdx +85 -0
  111. package/.docs/raw/rag/retrieval.mdx +365 -0
  112. package/.docs/raw/rag/vector-databases.mdx +340 -0
  113. package/.docs/raw/reference/agents/createTool.mdx +229 -0
  114. package/.docs/raw/reference/agents/generate.mdx +334 -0
  115. package/.docs/raw/reference/agents/getAgent.mdx +54 -0
  116. package/.docs/raw/reference/agents/stream.mdx +369 -0
  117. package/.docs/raw/reference/cli/build.mdx +55 -0
  118. package/.docs/raw/reference/cli/dev.mdx +134 -0
  119. package/.docs/raw/reference/cli/init.mdx +43 -0
  120. package/.docs/raw/reference/client-js/agents.mdx +107 -0
  121. package/.docs/raw/reference/client-js/error-handling.mdx +38 -0
  122. package/.docs/raw/reference/client-js/logs.mdx +24 -0
  123. package/.docs/raw/reference/client-js/memory.mdx +97 -0
  124. package/.docs/raw/reference/client-js/telemetry.mdx +20 -0
  125. package/.docs/raw/reference/client-js/tools.mdx +44 -0
  126. package/.docs/raw/reference/client-js/vectors.mdx +79 -0
  127. package/.docs/raw/reference/client-js/workflows.mdx +136 -0
  128. package/.docs/raw/reference/core/mastra-class.mdx +232 -0
  129. package/.docs/raw/reference/deployer/cloudflare.mdx +207 -0
  130. package/.docs/raw/reference/deployer/deployer.mdx +159 -0
  131. package/.docs/raw/reference/deployer/netlify.mdx +109 -0
  132. package/.docs/raw/reference/deployer/vercel.mdx +117 -0
  133. package/.docs/raw/reference/evals/answer-relevancy.mdx +186 -0
  134. package/.docs/raw/reference/evals/bias.mdx +186 -0
  135. package/.docs/raw/reference/evals/completeness.mdx +174 -0
  136. package/.docs/raw/reference/evals/content-similarity.mdx +183 -0
  137. package/.docs/raw/reference/evals/context-position.mdx +190 -0
  138. package/.docs/raw/reference/evals/context-precision.mdx +189 -0
  139. package/.docs/raw/reference/evals/context-relevancy.mdx +188 -0
  140. package/.docs/raw/reference/evals/contextual-recall.mdx +191 -0
  141. package/.docs/raw/reference/evals/faithfulness.mdx +193 -0
  142. package/.docs/raw/reference/evals/hallucination.mdx +219 -0
  143. package/.docs/raw/reference/evals/keyword-coverage.mdx +176 -0
  144. package/.docs/raw/reference/evals/prompt-alignment.mdx +238 -0
  145. package/.docs/raw/reference/evals/summarization.mdx +205 -0
  146. package/.docs/raw/reference/evals/textual-difference.mdx +161 -0
  147. package/.docs/raw/reference/evals/tone-consistency.mdx +181 -0
  148. package/.docs/raw/reference/evals/toxicity.mdx +165 -0
  149. package/.docs/raw/reference/index.mdx +12 -0
  150. package/.docs/raw/reference/memory/Memory.mdx +212 -0
  151. package/.docs/raw/reference/memory/createThread.mdx +95 -0
  152. package/.docs/raw/reference/memory/getThreadById.mdx +46 -0
  153. package/.docs/raw/reference/memory/getThreadsByResourceId.mdx +48 -0
  154. package/.docs/raw/reference/memory/query.mdx +167 -0
  155. package/.docs/raw/reference/networks/agent-network.mdx +159 -0
  156. package/.docs/raw/reference/observability/create-logger.mdx +106 -0
  157. package/.docs/raw/reference/observability/logger.mdx +55 -0
  158. package/.docs/raw/reference/observability/otel-config.mdx +120 -0
  159. package/.docs/raw/reference/observability/providers/braintrust.mdx +40 -0
  160. package/.docs/raw/reference/observability/providers/dash0.mdx +40 -0
  161. package/.docs/raw/reference/observability/providers/index.mdx +16 -0
  162. package/.docs/raw/reference/observability/providers/laminar.mdx +41 -0
  163. package/.docs/raw/reference/observability/providers/langfuse.mdx +51 -0
  164. package/.docs/raw/reference/observability/providers/langsmith.mdx +48 -0
  165. package/.docs/raw/reference/observability/providers/langwatch.mdx +45 -0
  166. package/.docs/raw/reference/observability/providers/new-relic.mdx +40 -0
  167. package/.docs/raw/reference/observability/providers/signoz.mdx +40 -0
  168. package/.docs/raw/reference/observability/providers/traceloop.mdx +40 -0
  169. package/.docs/raw/reference/rag/astra.mdx +258 -0
  170. package/.docs/raw/reference/rag/chroma.mdx +281 -0
  171. package/.docs/raw/reference/rag/chunk.mdx +235 -0
  172. package/.docs/raw/reference/rag/document.mdx +127 -0
  173. package/.docs/raw/reference/rag/embeddings.mdx +160 -0
  174. package/.docs/raw/reference/rag/extract-params.mdx +226 -0
  175. package/.docs/raw/reference/rag/graph-rag.mdx +182 -0
  176. package/.docs/raw/reference/rag/libsql.mdx +357 -0
  177. package/.docs/raw/reference/rag/metadata-filters.mdx +298 -0
  178. package/.docs/raw/reference/rag/pg.mdx +477 -0
  179. package/.docs/raw/reference/rag/pinecone.mdx +281 -0
  180. package/.docs/raw/reference/rag/qdrant.mdx +236 -0
  181. package/.docs/raw/reference/rag/rerank.mdx +212 -0
  182. package/.docs/raw/reference/rag/turbopuffer.mdx +249 -0
  183. package/.docs/raw/reference/rag/upstash.mdx +247 -0
  184. package/.docs/raw/reference/rag/vectorize.mdx +298 -0
  185. package/.docs/raw/reference/storage/libsql.mdx +74 -0
  186. package/.docs/raw/reference/storage/postgresql.mdx +48 -0
  187. package/.docs/raw/reference/storage/upstash.mdx +86 -0
  188. package/.docs/raw/reference/tools/client.mdx +207 -0
  189. package/.docs/raw/reference/tools/document-chunker-tool.mdx +141 -0
  190. package/.docs/raw/reference/tools/graph-rag-tool.mdx +154 -0
  191. package/.docs/raw/reference/tools/mcp-configuration.mdx +206 -0
  192. package/.docs/raw/reference/tools/vector-query-tool.mdx +212 -0
  193. package/.docs/raw/reference/voice/composite-voice.mdx +140 -0
  194. package/.docs/raw/reference/voice/deepgram.mdx +164 -0
  195. package/.docs/raw/reference/voice/elevenlabs.mdx +216 -0
  196. package/.docs/raw/reference/voice/google.mdx +198 -0
  197. package/.docs/raw/reference/voice/mastra-voice.mdx +394 -0
  198. package/.docs/raw/reference/voice/murf.mdx +251 -0
  199. package/.docs/raw/reference/voice/openai-realtime.mdx +431 -0
  200. package/.docs/raw/reference/voice/openai.mdx +168 -0
  201. package/.docs/raw/reference/voice/playai.mdx +159 -0
  202. package/.docs/raw/reference/voice/sarvam.mdx +260 -0
  203. package/.docs/raw/reference/voice/speechify.mdx +145 -0
  204. package/.docs/raw/reference/voice/voice.answer.mdx +122 -0
  205. package/.docs/raw/reference/voice/voice.connect.mdx +124 -0
  206. package/.docs/raw/reference/voice/voice.listen.mdx +195 -0
  207. package/.docs/raw/reference/voice/voice.on.mdx +189 -0
  208. package/.docs/raw/reference/voice/voice.send.mdx +118 -0
  209. package/.docs/raw/reference/voice/voice.speak.mdx +203 -0
  210. package/.docs/raw/reference/workflows/after.mdx +88 -0
  211. package/.docs/raw/reference/workflows/afterEvent.mdx +76 -0
  212. package/.docs/raw/reference/workflows/commit.mdx +37 -0
  213. package/.docs/raw/reference/workflows/createRun.mdx +77 -0
  214. package/.docs/raw/reference/workflows/else.mdx +72 -0
  215. package/.docs/raw/reference/workflows/events.mdx +305 -0
  216. package/.docs/raw/reference/workflows/execute.mdx +110 -0
  217. package/.docs/raw/reference/workflows/if.mdx +107 -0
  218. package/.docs/raw/reference/workflows/resume.mdx +155 -0
  219. package/.docs/raw/reference/workflows/resumeWithEvent.mdx +133 -0
  220. package/.docs/raw/reference/workflows/snapshots.mdx +207 -0
  221. package/.docs/raw/reference/workflows/start.mdx +84 -0
  222. package/.docs/raw/reference/workflows/step-class.mdx +100 -0
  223. package/.docs/raw/reference/workflows/step-condition.mdx +134 -0
  224. package/.docs/raw/reference/workflows/step-function.mdx +92 -0
  225. package/.docs/raw/reference/workflows/step-options.mdx +69 -0
  226. package/.docs/raw/reference/workflows/step-retries.mdx +203 -0
  227. package/.docs/raw/reference/workflows/suspend.mdx +70 -0
  228. package/.docs/raw/reference/workflows/then.mdx +74 -0
  229. package/.docs/raw/reference/workflows/until.mdx +165 -0
  230. package/.docs/raw/reference/workflows/watch.mdx +118 -0
  231. package/.docs/raw/reference/workflows/while.mdx +168 -0
  232. package/.docs/raw/reference/workflows/workflow.mdx +233 -0
  233. package/.docs/raw/storage/overview.mdx +378 -0
  234. package/.docs/raw/voice/overview.mdx +135 -0
  235. package/.docs/raw/voice/speech-to-text.mdx +45 -0
  236. package/.docs/raw/voice/text-to-speech.mdx +52 -0
  237. package/.docs/raw/voice/voice-to-voice.mdx +310 -0
  238. package/.docs/raw/workflows/control-flow.mdx +778 -0
  239. package/.docs/raw/workflows/dynamic-workflows.mdx +236 -0
  240. package/.docs/raw/workflows/error-handling.mdx +183 -0
  241. package/.docs/raw/workflows/nested-workflows.mdx +352 -0
  242. package/.docs/raw/workflows/overview.mdx +203 -0
  243. package/.docs/raw/workflows/steps.mdx +108 -0
  244. package/.docs/raw/workflows/suspend-and-resume.mdx +404 -0
  245. package/.docs/raw/workflows/variables.mdx +313 -0
  246. package/LICENSE.md +46 -0
  247. package/README.md +129 -0
  248. package/dist/_tsup-dts-rollup.d.ts +149 -0
  249. package/dist/chunk-QWYMT5LP.js +194 -0
  250. package/dist/prepare-docs/prepare.d.ts +1 -0
  251. package/dist/prepare-docs/prepare.js +1 -0
  252. package/dist/stdio.d.ts +1 -0
  253. package/dist/stdio.js +518 -0
  254. package/package.json +60 -0
@@ -0,0 +1,778 @@
1
+ ---
2
+ title: "Branching, Merging, Conditions | Workflows | Mastra Docs"
3
+ description: "Control flow in Mastra workflows allows you to manage branching, merging, and conditions to construct workflows that meet your logic requirements."
4
+ ---
5
+
6
+ # Control Flow in Workflows: Branching, Merging, and Conditions
7
+
8
+ When you create a multi-step process, you may need to run steps in parallel, chain them sequentially, or follow different paths based on outcomes. This page describes how you can manage branching, merging, and conditions to construct workflows that meet your logic requirements. The code snippets show the key patterns for structuring complex control flow.
9
+
10
+ ## Parallel Execution
11
+
12
+ You can run multiple steps at the same time if they don't depend on each other. This approach can speed up your workflow when steps perform independent tasks. The code below shows how to add two steps in parallel:
13
+
14
+ ```typescript
15
+ myWorkflow.step(fetchUserData).step(fetchOrderData);
16
+ ```
17
+
18
+ See the [Parallel Steps](../../examples/workflows/parallel-steps.mdx) example for more details.
19
+
20
+ ## Sequential Execution
21
+
22
+ Sometimes you need to run steps in strict order to ensure outputs from one step become inputs for the next. Use .then() to link dependent operations. The code below shows how to chain steps sequentially:
23
+
24
+ ```typescript
25
+ myWorkflow.step(fetchOrderData).then(validateData).then(processOrder);
26
+ ```
27
+
28
+ See the [Sequential Steps](../../examples/workflows/sequential-steps.mdx) example for more details.
29
+
30
+ ## Branching and Merging Paths
31
+
32
+ When different outcomes require different paths, branching is helpful. You can also merge paths later once they complete. The code below shows how to branch after stepA and later converge on stepF:
33
+
34
+ ```typescript
35
+ myWorkflow
36
+ .step(stepA)
37
+ .then(stepB)
38
+ .then(stepD)
39
+ .after(stepA)
40
+ .step(stepC)
41
+ .then(stepE)
42
+ .after([stepD, stepE])
43
+ .step(stepF);
44
+ ```
45
+
46
+ In this example:
47
+
48
+ - stepA leads to stepB, then to stepD.
49
+ - Separately, stepA also triggers stepC, which in turn leads to stepE.
50
+ - Separately, stepF is triggered when both stepD and stepE are completed.
51
+
52
+ See the [Branching Paths](../../examples/workflows/branching-paths.mdx) example for more details.
53
+
54
+ ## Merging Multiple Branches
55
+
56
+ Sometimes you need a step to execute only after multiple other steps have completed. Mastra provides a compound `.after([])` syntax that allows you to specify multiple dependencies for a step.
57
+
58
+ ```typescript
59
+ myWorkflow
60
+ .step(fetchUserData)
61
+ .then(validateUserData)
62
+ .step(fetchProductData)
63
+ .then(validateProductData)
64
+ // This step will only run after BOTH validateUserData AND validateProductData have completed
65
+ .after([validateUserData, validateProductData])
66
+ .step(processOrder)
67
+ ```
68
+
69
+ In this example:
70
+ - `fetchUserData` and `fetchProductData` run in parallel branches
71
+ - Each branch has its own validation step
72
+ - The `processOrder` step only executes after both validation steps have completed successfully
73
+
74
+ This pattern is particularly useful for:
75
+ - Joining parallel execution paths
76
+ - Implementing synchronization points in your workflow
77
+ - Ensuring all required data is available before proceeding
78
+
79
+ You can also create complex dependency patterns by combining multiple `.after([])` calls:
80
+
81
+ ```typescript
82
+ myWorkflow
83
+ // First branch
84
+ .step(stepA)
85
+ .then(stepB)
86
+ .then(stepC)
87
+
88
+ // Second branch
89
+ .step(stepD)
90
+ .then(stepE)
91
+
92
+ // Third branch
93
+ .step(stepF)
94
+ .then(stepG)
95
+
96
+ // This step depends on the completion of multiple branches
97
+ .after([stepC, stepE, stepG])
98
+ .step(finalStep)
99
+ ```
100
+
101
+ ## Cyclical Dependencies and Loops
102
+
103
+ Workflows often need to repeat steps until certain conditions are met. Mastra provides two powerful methods for creating loops: `until` and `while`. These methods offer an intuitive way to implement repetitive tasks.
104
+
105
+ ### Using Manual Cyclical Dependencies (Legacy Approach)
106
+
107
+ In earlier versions, you could create loops by manually defining cyclical dependencies with conditions:
108
+
109
+ ```typescript
110
+ myWorkflow
111
+ .step(fetchData)
112
+ .then(processData)
113
+ .after(processData)
114
+ .step(finalizeData, {
115
+ when: { "processData.status": "success" },
116
+ })
117
+ .step(fetchData, {
118
+ when: { "processData.status": "retry" },
119
+ });
120
+ ```
121
+
122
+ While this approach still works, the newer `until` and `while` methods provide a cleaner and more maintainable way to create loops.
123
+
124
+ ### Using `until` for Condition-Based Loops
125
+
126
+ The `until` method repeats a step until a specified condition becomes true. It takes these arguments:
127
+ 1. A condition that determines when to stop looping
128
+ 2. The step to repeat
129
+ 3. Optional variables to pass to the repeated step
130
+
131
+ ```typescript
132
+ // Step that increments a counter until target is reached
133
+ const incrementStep = new Step({
134
+ id: 'increment',
135
+ inputSchema: z.object({
136
+ // Current counter value
137
+ counter: z.number().optional(),
138
+ }),
139
+ outputSchema: z.object({
140
+ // Updated counter value
141
+ updatedCounter: z.number(),
142
+ }),
143
+ execute: async ({ context }) => {
144
+ const { counter = 0 } = context.inputData;
145
+ return { updatedCounter: counter + 1 };
146
+ },
147
+ });
148
+
149
+ workflow
150
+ .step(incrementStep)
151
+ .until(
152
+ async ({ context }) => {
153
+ // Stop when counter reaches 10
154
+ const result = context.getStepResult(incrementStep);
155
+ return (result?.updatedCounter ?? 0) >= 10;
156
+ },
157
+ incrementStep,
158
+ {
159
+ // Pass current counter to next iteration
160
+ counter: {
161
+ step: incrementStep,
162
+ path: 'updatedCounter'
163
+ }
164
+ }
165
+ )
166
+ .then(finalStep);
167
+ ```
168
+
169
+ You can also use a reference-based condition:
170
+
171
+ ```typescript
172
+ workflow
173
+ .step(incrementStep)
174
+ .until(
175
+ {
176
+ ref: { step: incrementStep, path: 'updatedCounter' },
177
+ query: { $gte: 10 },
178
+ },
179
+ incrementStep,
180
+ {
181
+ counter: {
182
+ step: incrementStep,
183
+ path: 'updatedCounter'
184
+ }
185
+ }
186
+ )
187
+ .then(finalStep);
188
+ ```
189
+
190
+ ### Using `while` for Condition-Based Loops
191
+
192
+ The `while` method repeats a step as long as a specified condition remains true. It takes the same arguments as `until`:
193
+ 1. A condition that determines when to continue looping
194
+ 2. The step to repeat
195
+ 3. Optional variables to pass to the repeated step
196
+
197
+ ```typescript
198
+ // Step that increments a counter while below target
199
+ const incrementStep = new Step({
200
+ id: 'increment',
201
+ inputSchema: z.object({
202
+ // Current counter value
203
+ counter: z.number().optional(),
204
+ }),
205
+ outputSchema: z.object({
206
+ // Updated counter value
207
+ updatedCounter: z.number(),
208
+ }),
209
+ execute: async ({ context }) => {
210
+ const { counter = 0 } = context.inputData;
211
+ return { updatedCounter: counter + 1 };
212
+ },
213
+ });
214
+
215
+ workflow
216
+ .step(incrementStep)
217
+ .while(
218
+ async ({ context }) => {
219
+ // Continue while counter is less than 10
220
+ const result = context.getStepResult(incrementStep);
221
+ return (result?.updatedCounter ?? 0) < 10;
222
+ },
223
+ incrementStep,
224
+ {
225
+ // Pass current counter to next iteration
226
+ counter: {
227
+ step: incrementStep,
228
+ path: 'updatedCounter'
229
+ }
230
+ }
231
+ )
232
+ .then(finalStep);
233
+ ```
234
+
235
+ You can also use a reference-based condition:
236
+
237
+ ```typescript
238
+ workflow
239
+ .step(incrementStep)
240
+ .while(
241
+ {
242
+ ref: { step: incrementStep, path: 'updatedCounter' },
243
+ query: { $lt: 10 },
244
+ },
245
+ incrementStep,
246
+ {
247
+ counter: {
248
+ step: incrementStep,
249
+ path: 'updatedCounter'
250
+ }
251
+ }
252
+ )
253
+ .then(finalStep);
254
+ ```
255
+
256
+ ### Comparison Operators for Reference Conditions
257
+
258
+ When using reference-based conditions, you can use these comparison operators:
259
+
260
+ | Operator | Description |
261
+ |----------|-------------|
262
+ | `$eq` | Equal to |
263
+ | `$ne` | Not equal to |
264
+ | `$gt` | Greater than |
265
+ | `$gte` | Greater than or equal to |
266
+ | `$lt` | Less than |
267
+ | `$lte` | Less than or equal to |
268
+
269
+ ## Conditions
270
+
271
+ Use the when property to control whether a step runs based on data from previous steps. Below are three ways to specify conditions.
272
+
273
+ ### Option 1: Function
274
+
275
+ ```typescript
276
+ myWorkflow.step(
277
+ new Step({
278
+ id: "processData",
279
+ execute: async ({ context }) => {
280
+ // Action logic
281
+ },
282
+ }),
283
+ {
284
+ when: async ({ context }) => {
285
+ const fetchData = context?.getStepResult<{ status: string }>("fetchData");
286
+ return fetchData?.status === "success";
287
+ },
288
+ },
289
+ );
290
+ ```
291
+
292
+ ### Option 2: Query Object
293
+
294
+ ```typescript
295
+ myWorkflow.step(
296
+ new Step({
297
+ id: "processData",
298
+ execute: async ({ context }) => {
299
+ // Action logic
300
+ },
301
+ }),
302
+ {
303
+ when: {
304
+ ref: {
305
+ step: {
306
+ id: "fetchData",
307
+ },
308
+ path: "status",
309
+ },
310
+ query: { $eq: "success" },
311
+ },
312
+ },
313
+ );
314
+ ```
315
+
316
+ ### Option 3: Simple Path Comparison
317
+
318
+ ```typescript
319
+ myWorkflow.step(
320
+ new Step({
321
+ id: "processData",
322
+ execute: async ({ context }) => {
323
+ // Action logic
324
+ },
325
+ }),
326
+ {
327
+ when: {
328
+ "fetchData.status": "success",
329
+ },
330
+ },
331
+ );
332
+ ```
333
+
334
+ ## Data Access Patterns
335
+
336
+ Mastra provides several ways to pass data between steps:
337
+
338
+ 1. **Context Object** - Access step results directly through the context object
339
+ 2. **Variable Mapping** - Explicitly map outputs from one step to inputs of another
340
+ 3. **getStepResult Method** - Type-safe method to retrieve step outputs
341
+
342
+ Each approach has its advantages depending on your use case and requirements for type safety.
343
+
344
+ ### Using getStepResult Method
345
+
346
+ The `getStepResult` method provides a type-safe way to access step results. This is the recommended approach when working with TypeScript as it preserves type information.
347
+
348
+ #### Basic Usage
349
+
350
+ For better type safety, you can provide a type parameter to `getStepResult`:
351
+
352
+ ```typescript showLineNumbers filename="src/mastra/workflows/get-step-result.ts" copy
353
+ import { Step, Workflow } from "@mastra/core/workflows";
354
+ import { z } from "zod";
355
+
356
+ const fetchUserStep = new Step({
357
+ id: 'fetchUser',
358
+ outputSchema: z.object({
359
+ name: z.string(),
360
+ userId: z.string(),
361
+ }),
362
+ execute: async ({ context }) => {
363
+ return { name: 'John Doe', userId: '123' };
364
+ },
365
+ });
366
+
367
+ const analyzeDataStep = new Step({
368
+ id: "analyzeData",
369
+ execute: async ({ context }) => {
370
+ // Type-safe access to previous step result
371
+ const userData = context.getStepResult<{ name: string, userId: string }>("fetchUser");
372
+
373
+ if (!userData) {
374
+ return { status: "error", message: "User data not found" };
375
+ }
376
+
377
+ return {
378
+ analysis: `Analyzed data for user ${userData.name}`,
379
+ userId: userData.userId
380
+ };
381
+ },
382
+ });
383
+ ```
384
+
385
+
386
+ #### Using Step References
387
+
388
+ The most type-safe approach is to reference the step directly in the `getStepResult` call:
389
+
390
+ ```typescript showLineNumbers filename="src/mastra/workflows/step-reference.ts" copy
391
+ import { Step, Workflow } from "@mastra/core/workflows";
392
+ import { z } from "zod";
393
+
394
+ // Define step with output schema
395
+ const fetchUserStep = new Step({
396
+ id: "fetchUser",
397
+ outputSchema: z.object({
398
+ userId: z.string(),
399
+ name: z.string(),
400
+ email: z.string(),
401
+ }),
402
+ execute: async () => {
403
+ return {
404
+ userId: "user123",
405
+ name: "John Doe",
406
+ email: "john@example.com"
407
+ };
408
+ },
409
+ });
410
+
411
+ const processUserStep = new Step({
412
+ id: "processUser",
413
+ execute: async ({ context }) => {
414
+ // TypeScript will infer the correct type from fetchUserStep's outputSchema
415
+ const userData = context.getStepResult(fetchUserStep);
416
+
417
+ return {
418
+ processed: true,
419
+ userName: userData?.name
420
+ };
421
+ },
422
+ });
423
+
424
+ const workflow = new Workflow({
425
+ name: "user-workflow",
426
+ });
427
+
428
+ workflow
429
+ .step(fetchUserStep)
430
+ .then(processUserStep)
431
+ .commit();
432
+ ```
433
+
434
+
435
+
436
+
437
+
438
+ ### Using Variable Mapping
439
+
440
+ Variable mapping is an explicit way to define data flow between steps.
441
+ This approach makes dependencies clear and provides good type safety.
442
+ The data injected into the step is available in the `context.inputData` object, and typed based on the `inputSchema` of the step.
443
+
444
+ ```typescript showLineNumbers filename="src/mastra/workflows/variable-mapping.ts" copy
445
+ import { Step, Workflow } from "@mastra/core/workflows";
446
+ import { z } from "zod";
447
+
448
+ const fetchUserStep = new Step({
449
+ id: "fetchUser",
450
+ outputSchema: z.object({
451
+ userId: z.string(),
452
+ name: z.string(),
453
+ email: z.string(),
454
+ }),
455
+ execute: async () => {
456
+ return {
457
+ userId: "user123",
458
+ name: "John Doe",
459
+ email: "john@example.com"
460
+ };
461
+ },
462
+ });
463
+
464
+ const sendEmailStep = new Step({
465
+ id: "sendEmail",
466
+ inputSchema: z.object({
467
+ recipientEmail: z.string(),
468
+ recipientName: z.string(),
469
+ }),
470
+ execute: async ({ context }) => {
471
+ const { recipientEmail, recipientName } = context.inputData;
472
+
473
+ // Send email logic here
474
+ return {
475
+ status: "sent",
476
+ to: recipientEmail
477
+ };
478
+ },
479
+ });
480
+
481
+ const workflow = new Workflow({
482
+ name: "email-workflow",
483
+ });
484
+
485
+ workflow
486
+ .step(fetchUserStep)
487
+ .then(sendEmailStep, {
488
+ variables: {
489
+ // Map specific fields from fetchUser to sendEmail inputs
490
+ recipientEmail: { step: fetchUserStep, path: 'email' },
491
+ recipientName: { step: fetchUserStep, path: 'name' }
492
+ }
493
+ })
494
+ .commit();
495
+ ```
496
+
497
+ For more details on variable mapping, see the [Data Mapping with Workflow Variables](./variables.mdx) documentation.
498
+
499
+ ### Using the Context Object
500
+
501
+ The context object provides direct access to all step results and their outputs. This approach is more flexible but requires careful handling to maintain type safety.
502
+ You can access step results directly through the `context.steps` object:
503
+
504
+ ```typescript showLineNumbers filename="src/mastra/workflows/context-access.ts" copy
505
+ import { Step, Workflow } from "@mastra/core/workflows";
506
+ import { z } from "zod";
507
+
508
+ const processOrderStep = new Step({
509
+ id: 'processOrder',
510
+ execute: async ({ context }) => {
511
+ // Access data from a previous step
512
+ let userData: { name: string, userId: string };
513
+ if (context.steps['fetchUser']?.status === 'success') {
514
+ userData = context.steps.fetchUser.output;
515
+ } else {
516
+ throw new Error('User data not found');
517
+ }
518
+
519
+ return {
520
+ orderId: 'order123',
521
+ userId: userData.userId,
522
+ status: 'processing',
523
+ };
524
+ },
525
+ });
526
+
527
+ const workflow = new Workflow({
528
+ name: "order-workflow",
529
+ });
530
+
531
+ workflow
532
+ .step(fetchUserStep)
533
+ .then(processOrderStep)
534
+ .commit();
535
+ ```
536
+
537
+ ### Workflow-Level Type Safety
538
+
539
+ For comprehensive type safety across your entire workflow, you can define types for all steps and pass them to the Workflow
540
+ This allows you to get type safety for the context object on conditions, and on step results in the final workflow output.
541
+
542
+ ```typescript showLineNumbers filename="src/mastra/workflows/workflow-typing.ts" copy
543
+ import { Step, Workflow } from "@mastra/core/workflows";
544
+ import { z } from "zod";
545
+
546
+
547
+ // Create steps with typed outputs
548
+ const fetchUserStep = new Step({
549
+ id: "fetchUser",
550
+ outputSchema: z.object({
551
+ userId: z.string(),
552
+ name: z.string(),
553
+ email: z.string(),
554
+ }),
555
+ execute: async () => {
556
+ return {
557
+ userId: "user123",
558
+ name: "John Doe",
559
+ email: "john@example.com"
560
+ };
561
+ },
562
+ });
563
+
564
+ const processOrderStep = new Step({
565
+ id: "processOrder",
566
+ execute: async ({ context }) => {
567
+ // TypeScript knows the shape of userData
568
+ const userData = context.getStepResult(fetchUserStep);
569
+
570
+ return {
571
+ orderId: "order123",
572
+ status: "processing"
573
+ };
574
+ },
575
+ });
576
+
577
+ const workflow = new Workflow<[typeof fetchUserStep, typeof processOrderStep]>({
578
+ name: "typed-workflow",
579
+ });
580
+
581
+ workflow
582
+ .step(fetchUserStep)
583
+ .then(processOrderStep)
584
+ .until(async ({ context }) => {
585
+ // TypeScript knows the shape of userData here
586
+ const res = context.getStepResult('fetchUser');
587
+ return res?.userId === '123';
588
+ }, processOrderStep)
589
+ .commit();
590
+ ```
591
+
592
+ ### Accessing Trigger Data
593
+
594
+ In addition to step results, you can access the original trigger data that started the workflow:
595
+
596
+ ```typescript showLineNumbers filename="src/mastra/workflows/trigger-data.ts" copy
597
+ import { Step, Workflow } from "@mastra/core/workflows";
598
+ import { z } from "zod";
599
+
600
+ // Define trigger schema
601
+ const triggerSchema = z.object({
602
+ customerId: z.string(),
603
+ orderItems: z.array(z.string()),
604
+ });
605
+
606
+ type TriggerType = z.infer<typeof triggerSchema>;
607
+
608
+ const processOrderStep = new Step({
609
+ id: "processOrder",
610
+ execute: async ({ context }) => {
611
+ // Access trigger data with type safety
612
+ const triggerData = context.getStepResult<TriggerType>('trigger');
613
+
614
+ return {
615
+ customerId: triggerData?.customerId,
616
+ itemCount: triggerData?.orderItems.length || 0,
617
+ status: "processing"
618
+ };
619
+ },
620
+ });
621
+
622
+ const workflow = new Workflow({
623
+ name: "order-workflow",
624
+ triggerSchema,
625
+ });
626
+
627
+ workflow
628
+ .step(processOrderStep)
629
+ .commit();
630
+ ```
631
+
632
+ ### Accessing Resume Data
633
+
634
+ The data injected into the step is available in the `context.inputData` object, and typed based on the `inputSchema` of the step.
635
+
636
+ ```typescript showLineNumbers filename="src/mastra/workflows/resume-data.ts" copy
637
+ import { Step, Workflow } from "@mastra/core/workflows";
638
+ import { z } from "zod";
639
+
640
+ const processOrderStep = new Step({
641
+ id: "processOrder",
642
+ inputSchema: z.object({
643
+ orderId: z.string(),
644
+ }),
645
+ execute: async ({ context, suspend }) => {
646
+ const { orderId } = context.inputData;
647
+
648
+ if (!orderId) {
649
+ await suspend();
650
+ return;
651
+ }
652
+
653
+ return {
654
+ orderId,
655
+ status: "processed"
656
+ };
657
+ },
658
+ });
659
+
660
+ const workflow = new Workflow({
661
+ name: "order-workflow",
662
+ });
663
+
664
+ workflow
665
+ .step(processOrderStep)
666
+ .commit();
667
+
668
+ const run = workflow.createRun();
669
+ const result = await run.start();
670
+
671
+ const resumedResult = await workflow.resume({
672
+ runId: result.runId,
673
+ stepId: 'processOrder',
674
+ inputData: {
675
+ orderId: '123',
676
+ },
677
+ });
678
+
679
+ console.log({resumedResult});
680
+ ```
681
+
682
+ ### Accessing Workflow Results
683
+
684
+ You can get typed access to the results of a workflow by injecting the step types into the `Workflow` type params:
685
+
686
+ ```typescript showLineNumbers filename="src/mastra/workflows/get-results.ts" copy
687
+ import { Workflow } from "@mastra/core/workflows";
688
+
689
+ const fetchUserStep = new Step({
690
+ id: "fetchUser",
691
+ outputSchema: z.object({
692
+ userId: z.string(),
693
+ name: z.string(),
694
+ email: z.string(),
695
+ }),
696
+ execute: async () => {
697
+ return {
698
+ userId: "user123",
699
+ name: "John Doe",
700
+ email: "john@example.com"
701
+ };
702
+ },
703
+ });
704
+
705
+ const processOrderStep = new Step({
706
+ id: "processOrder",
707
+ outputSchema: z.object({
708
+ orderId: z.string(),
709
+ status: z.string(),
710
+ }),
711
+ execute: async ({ context }) => {
712
+ const userData = context.getStepResult(fetchUserStep);
713
+ return {
714
+ orderId: "order123",
715
+ status: "processing"
716
+ };
717
+ },
718
+ });
719
+
720
+ const workflow = new Workflow<[typeof fetchUserStep, typeof processOrderStep]>({
721
+ name: "typed-workflow",
722
+ });
723
+
724
+ workflow
725
+ .step(fetchUserStep)
726
+ .then(processOrderStep)
727
+ .commit();
728
+
729
+ const run = workflow.createRun();
730
+ const result = await run.start();
731
+
732
+ // The result is a discriminated union of the step results
733
+ // So it needs to be narrowed down via status checks
734
+ if (result.results.processOrder.status === 'success') {
735
+ // TypeScript will know the shape of the results
736
+ const orderId = result.results.processOrder.output.orderId;
737
+ console.log({orderId});
738
+ }
739
+
740
+ if (result.results.fetchUser.status === 'success') {
741
+ const userId = result.results.fetchUser.output.userId;
742
+ console.log({userId});
743
+ }
744
+ ```
745
+
746
+ ### Best Practices for Data Flow
747
+
748
+ 1. **Use getStepResult with Step References for Type Safety**
749
+ - Ensures TypeScript can infer the correct types
750
+ - Catches type errors at compile time
751
+
752
+ 2. **Use Variable Mapping for Explicit Dependencies*
753
+ - Makes data flow clear and maintainable
754
+ - Provides good documentation of step dependencies
755
+
756
+ 3. **Define Output Schemas for Steps**
757
+ - Validates data at runtime
758
+ - Validates return type of the `execute` function
759
+ - Improves type inference in TypeScript
760
+
761
+ 4. **Handle Missing Data Gracefully**
762
+ - Always check if step results exist before accessing properties
763
+ - Provide fallback values for optional data
764
+
765
+ 5. **Keep Data Transformations Simple**
766
+ - Transform data in dedicated steps rather than in variable mappings
767
+ - Makes workflows easier to test and debug
768
+
769
+ ### Comparison of Data Flow Methods
770
+
771
+ | Method | Type Safety | Explicitness | Use Case |
772
+ |--------|------------|--------------|----------|
773
+ | getStepResult | Highest | High | Complex workflows with strict typing requirements |
774
+ | Variable Mapping | High | High | When dependencies need to be clear and explicit |
775
+ | context.steps | Medium | Low | Quick access to step data in simple workflows |
776
+
777
+ By choosing the right data flow method for your use case, you can create workflows that are both type-safe and maintainable.
778
+