@mastra/mcp-docs-server 0.13.5-alpha.0 → 0.13.6

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 (93) hide show
  1. package/.docs/organized/changelogs/%40internal%2Fstorage-test-utils.md +76 -76
  2. package/.docs/organized/changelogs/%40mastra%2Fagui.md +61 -61
  3. package/.docs/organized/changelogs/%40mastra%2Fclickhouse.md +54 -54
  4. package/.docs/organized/changelogs/%40mastra%2Fclient-js.md +211 -211
  5. package/.docs/organized/changelogs/%40mastra%2Fcloudflare-d1.md +75 -75
  6. package/.docs/organized/changelogs/%40mastra%2Fcloudflare.md +91 -91
  7. package/.docs/organized/changelogs/%40mastra%2Fcore.md +185 -185
  8. package/.docs/organized/changelogs/%40mastra%2Fdeployer-cloudflare.md +237 -237
  9. package/.docs/organized/changelogs/%40mastra%2Fdeployer-netlify.md +143 -143
  10. package/.docs/organized/changelogs/%40mastra%2Fdeployer-vercel.md +143 -143
  11. package/.docs/organized/changelogs/%40mastra%2Fdeployer.md +235 -235
  12. package/.docs/organized/changelogs/%40mastra%2Fdynamodb.md +84 -84
  13. package/.docs/organized/changelogs/%40mastra%2Fevals.md +56 -56
  14. package/.docs/organized/changelogs/%40mastra%2Ffastembed.md +7 -0
  15. package/.docs/organized/changelogs/%40mastra%2Ffirecrawl.md +75 -75
  16. package/.docs/organized/changelogs/%40mastra%2Flance.md +55 -0
  17. package/.docs/organized/changelogs/%40mastra%2Flibsql.md +56 -56
  18. package/.docs/organized/changelogs/%40mastra%2Fmcp-docs-server.md +25 -25
  19. package/.docs/organized/changelogs/%40mastra%2Fmcp.md +38 -38
  20. package/.docs/organized/changelogs/%40mastra%2Fmemory.md +119 -119
  21. package/.docs/organized/changelogs/%40mastra%2Fmongodb.md +58 -58
  22. package/.docs/organized/changelogs/%40mastra%2Fmssql.md +69 -0
  23. package/.docs/organized/changelogs/%40mastra%2Fpg.md +119 -119
  24. package/.docs/organized/changelogs/%40mastra%2Fplayground-ui.md +244 -244
  25. package/.docs/organized/changelogs/%40mastra%2Frag.md +73 -73
  26. package/.docs/organized/changelogs/%40mastra%2Fschema-compat.md +24 -0
  27. package/.docs/organized/changelogs/%40mastra%2Fserver.md +211 -211
  28. package/.docs/organized/changelogs/%40mastra%2Fupstash.md +76 -76
  29. package/.docs/organized/changelogs/%40mastra%2Fvoice-openai-realtime.md +44 -44
  30. package/.docs/organized/changelogs/create-mastra.md +126 -126
  31. package/.docs/organized/changelogs/mastra.md +256 -256
  32. package/.docs/organized/code-examples/agent.md +6 -0
  33. package/.docs/organized/code-examples/agui.md +3 -3
  34. package/.docs/organized/code-examples/ai-sdk-useChat.md +2 -2
  35. package/.docs/organized/code-examples/ai-sdk-v5.md +201 -0
  36. package/.docs/organized/code-examples/assistant-ui.md +2 -2
  37. package/.docs/organized/code-examples/bird-checker-with-nextjs-and-eval.md +2 -2
  38. package/.docs/organized/code-examples/bird-checker-with-nextjs.md +2 -2
  39. package/.docs/organized/code-examples/client-side-tools.md +1 -1
  40. package/.docs/organized/code-examples/crypto-chatbot.md +5 -5
  41. package/.docs/organized/code-examples/openapi-spec-writer.md +2 -2
  42. package/.docs/organized/code-examples/workflow-with-suspend-resume.md +181 -0
  43. package/.docs/raw/agents/agent-memory.mdx +126 -0
  44. package/.docs/raw/agents/dynamic-agents.mdx +34 -2
  45. package/.docs/raw/agents/overview.mdx +21 -33
  46. package/.docs/raw/community/licensing.mdx +27 -19
  47. package/.docs/raw/deployment/cloud-providers/amazon-ec2.mdx +60 -26
  48. package/.docs/raw/deployment/cloud-providers/digital-ocean.mdx +1 -1
  49. package/.docs/raw/deployment/cloud-providers/index.mdx +44 -9
  50. package/.docs/raw/deployment/server-deployment.mdx +56 -0
  51. package/.docs/raw/deployment/serverless-platforms/cloudflare-deployer.mdx +9 -30
  52. package/.docs/raw/deployment/serverless-platforms/index.mdx +13 -13
  53. package/.docs/raw/frameworks/agentic-uis/ai-sdk.mdx +291 -216
  54. package/.docs/raw/frameworks/agentic-uis/assistant-ui.mdx +0 -34
  55. package/.docs/raw/frameworks/agentic-uis/copilotkit.mdx +162 -181
  56. package/.docs/raw/frameworks/servers/express.mdx +1 -1
  57. package/.docs/raw/frameworks/web-frameworks/astro.mdx +2 -2
  58. package/.docs/raw/frameworks/web-frameworks/next-js.mdx +1 -1
  59. package/.docs/raw/frameworks/web-frameworks/sveltekit.mdx +4 -4
  60. package/.docs/raw/frameworks/web-frameworks/vite-react.mdx +1 -1
  61. package/.docs/raw/getting-started/installation.mdx +10 -7
  62. package/.docs/raw/getting-started/model-capability.mdx +1 -1
  63. package/.docs/raw/memory/overview.mdx +8 -0
  64. package/.docs/raw/memory/semantic-recall.mdx +6 -0
  65. package/.docs/raw/observability/tracing.mdx +30 -0
  66. package/.docs/raw/rag/retrieval.mdx +24 -5
  67. package/.docs/raw/reference/agents/agent.mdx +2 -2
  68. package/.docs/raw/reference/cli/create-mastra.mdx +7 -0
  69. package/.docs/raw/reference/cli/dev.mdx +4 -3
  70. package/.docs/raw/reference/client-js/agents.mdx +8 -0
  71. package/.docs/raw/reference/memory/query.mdx +35 -14
  72. package/.docs/raw/reference/observability/providers/keywordsai.mdx +73 -0
  73. package/.docs/raw/reference/rag/rerankWithScorer.mdx +213 -0
  74. package/.docs/raw/reference/storage/mssql.mdx +108 -0
  75. package/.docs/raw/server-db/custom-api-routes.mdx +67 -0
  76. package/.docs/raw/server-db/production-server.mdx +66 -0
  77. package/.docs/raw/tools-mcp/mcp-overview.mdx +28 -7
  78. package/.docs/raw/workflows/control-flow.mdx +91 -93
  79. package/.docs/raw/workflows/input-data-mapping.mdx +31 -43
  80. package/.docs/raw/workflows/overview.mdx +22 -12
  81. package/.docs/raw/workflows/pausing-execution.mdx +49 -4
  82. package/.docs/raw/workflows/suspend-and-resume.mdx +17 -16
  83. package/.docs/raw/workflows/using-with-agents-and-tools.mdx +16 -13
  84. package/.docs/raw/workflows-legacy/overview.mdx +11 -0
  85. package/LICENSE.md +11 -42
  86. package/package.json +7 -9
  87. package/.docs/raw/deployment/custom-api-routes.mdx +0 -55
  88. package/.docs/raw/deployment/server.mdx +0 -116
  89. package/.docs/raw/frameworks/ai-sdk-v5.mdx +0 -91
  90. /package/.docs/raw/{local-dev/mastra-dev.mdx → server-db/local-dev-playground.mdx} +0 -0
  91. /package/.docs/raw/{client-js/overview.mdx → server-db/mastra-client.mdx} +0 -0
  92. /package/.docs/raw/{deployment → server-db}/middleware.mdx +0 -0
  93. /package/.docs/raw/{storage/overview.mdx → server-db/storage.mdx} +0 -0
@@ -0,0 +1,108 @@
1
+ ---
2
+ title: "MSSQL Storage | Storage System | Mastra Core"
3
+ description: Documentation for the MSSQL storage implementation in Mastra.
4
+ ---
5
+
6
+ # MSSQL Storage
7
+
8
+ The MSSQL storage implementation provides a production-ready storage solution using Microsoft SQL Server databases.
9
+
10
+ ## Installation
11
+
12
+ ```bash copy
13
+ npm install @mastra/mssql@latest
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ```typescript copy showLineNumbers
19
+ import { MSSQLStore } from "@mastra/mssql";
20
+
21
+ const storage = new MSSQLStore({
22
+ connectionString: process.env.DATABASE_URL,
23
+ });
24
+ ```
25
+
26
+ ## Parameters
27
+
28
+ <PropertiesTable
29
+ content={[
30
+ {
31
+ name: "connectionString",
32
+ type: "string",
33
+ description:
34
+ "MSSQL connection string (e.g., mssql://user:pass@host:1433/dbname)",
35
+ isOptional: false,
36
+ },
37
+ {
38
+ name: "schemaName",
39
+ type: "string",
40
+ description:
41
+ "The name of the schema you want the storage to use. Will use the default schema if not provided.",
42
+ isOptional: true,
43
+ },
44
+ ]}
45
+ />
46
+
47
+ ## Constructor Examples
48
+
49
+ You can instantiate `MSSQLStore` in the following ways:
50
+
51
+ ```ts
52
+ import { MSSQLStore } from "@mastra/mssql";
53
+
54
+ // Using a connection string only
55
+ const store1 = new MSSQLStore({
56
+ connectionString: "mssql://user:password@localhost:1433/mydb",
57
+ });
58
+
59
+ // Using a connection string with a custom schema name
60
+ const store2 = new MSSQLStore({
61
+ connectionString: "mssql://user:password@localhost:1433/mydb",
62
+ schemaName: "custom_schema", // optional
63
+ });
64
+
65
+ // Using individual connection parameters
66
+ const store4 = new MSSQLStore({
67
+ server: "localhost",
68
+ port: 1433,
69
+ database: "mydb",
70
+ user: "user",
71
+ password: "password",
72
+ });
73
+
74
+ // Individual parameters with schemaName
75
+ const store5 = new MSSQLStore({
76
+ server: "localhost",
77
+ port: 1433,
78
+ database: "mydb",
79
+ user: "user",
80
+ password: "password",
81
+ schemaName: "custom_schema", // optional
82
+ });
83
+ ```
84
+
85
+ ## Additional Notes
86
+
87
+ ### Schema Management
88
+
89
+ The storage implementation handles schema creation and updates automatically. It creates the following tables:
90
+
91
+ - `threads`: Stores conversation threads
92
+ - `messages`: Stores individual messages
93
+ - `metadata`: Stores additional metadata for threads and messages
94
+
95
+ ### Direct Database and Pool Access
96
+
97
+ `MSSQLStore` exposes the mssql connection pool as public fields:
98
+
99
+ ```typescript
100
+ store.pool // mssql connection pool instance
101
+ ```
102
+
103
+ This enables direct queries and custom transaction management. When using these fields:
104
+ - You are responsible for proper connection and transaction handling.
105
+ - Closing the store (`store.close()`) will destroy the associated connection pool.
106
+ - Direct access bypasses any additional logic or validation provided by MSSQLStore methods.
107
+
108
+ This approach is intended for advanced scenarios where low-level access is required.
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: "Custom API Routes"
3
+ description: "Expose additional HTTP endpoints from your Mastra server."
4
+ ---
5
+
6
+ # Custom API Routes
7
+
8
+ By default Mastra automatically exposes registered agents and workflows via the server. For additional behavior you can define your own HTTP routes.
9
+
10
+ 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.
11
+
12
+ ```typescript filename="src/mastra/index.ts" copy showLineNumbers
13
+ import { Mastra } from "@mastra/core/mastra";
14
+ import { registerApiRoute } from "@mastra/core/server";
15
+
16
+ export const mastra = new Mastra({
17
+ // ...
18
+ server: {
19
+ apiRoutes: [
20
+ registerApiRoute("/my-custom-route", {
21
+ method: "GET",
22
+ handler: async (c) => {
23
+ const mastra = c.get("mastra");
24
+ const agents = await mastra.getAgent("my-agent");
25
+
26
+ return c.json({ message: "Custom route" });
27
+ },
28
+ }),
29
+ ],
30
+ },
31
+ });
32
+ ```
33
+
34
+ Once registered, a custom route will be accessible from the root of the server. For example:
35
+
36
+ ```bash
37
+ curl http://localhost:4111/my-custom-route
38
+ ```
39
+
40
+ Each route's handler receives the Hono `Context`. Within the handler you can access the `Mastra` instance to fetch or call agents and workflows.
41
+
42
+ To add route-specific middleware pass a `middleware` array when calling `registerApiRoute`.
43
+
44
+ ```typescript filename="src/mastra/index.ts" copy showLineNumbers
45
+ import { Mastra } from "@mastra/core/mastra";
46
+ import { registerApiRoute } from "@mastra/core/server";
47
+
48
+ export const mastra = new Mastra({
49
+ // ...
50
+ server: {
51
+ apiRoutes: [
52
+ registerApiRoute("/my-custom-route", {
53
+ method: "GET",
54
+ middleware: [
55
+ async (c, next) => {
56
+ console.log(`${c.req.method} ${c.req.url}`);
57
+ await next();
58
+ }
59
+ ],
60
+ handler: async (c) => {
61
+ return c.json({ message: "Custom route with middleware" });
62
+ }
63
+ })
64
+ ]
65
+ }
66
+ });
67
+ ```
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: "Create A Mastra Production Server"
3
+ description: "Learn how to configure and deploy a production-ready Mastra server with custom settings for APIs, CORS, and more"
4
+ ---
5
+
6
+ # Create a Mastra Production Server
7
+
8
+ When deploying your Mastra application to production, it runs as an HTTP server that exposes your agents, workflows, and other functionality as API endpoints. This page covers how to configure and customize the server for a production environment.
9
+
10
+ ## Server Architecture
11
+
12
+ Mastra uses [Hono](https://hono.dev) as its underlying HTTP server framework. When you build a Mastra application using `mastra build`, it generates a Hono-based HTTP server in the `.mastra` directory.
13
+
14
+ The server provides:
15
+
16
+ - API endpoints for all registered agents
17
+ - API endpoints for all registered workflows
18
+ - Custom API route support
19
+ - Custom middleware support
20
+ - Configuration of timeout
21
+ - Configuration of port
22
+ - Configuration of body limit
23
+
24
+ See the [Middleware](/docs/server-db/middleware) and
25
+ [Custom API Routes](/docs/server-db/custom-api-routes) pages for details on
26
+ adding additional server behaviour.
27
+
28
+ ## Server configuration
29
+
30
+ You can configure server `port` and `timeout` in the Mastra instance.
31
+
32
+ ```typescript filename="src/mastra/index.ts" copy showLineNumbers
33
+ import { Mastra } from "@mastra/core/mastra";
34
+
35
+ export const mastra = new Mastra({
36
+ // ...
37
+ server: {
38
+ port: 3000, // Defaults to 4111
39
+ timeout: 10000, // Defaults to 30000 (30s)
40
+ },
41
+ });
42
+ ```
43
+
44
+ The `method` option can be one of `"GET"`, `"POST"`, `"PUT"`,
45
+ `"DELETE"` or `"ALL"`. Using `"ALL"` will cause the handler to be
46
+ invoked for any HTTP method that matches the path.
47
+
48
+ ## Custom CORS Config
49
+
50
+ Mastra allows you to configure CORS (Cross-Origin Resource Sharing) settings for your server.
51
+
52
+ ```typescript filename="src/mastra/index.ts" copy showLineNumbers
53
+ import { Mastra } from "@mastra/core/mastra";
54
+
55
+ export const mastra = new Mastra({
56
+ // ...
57
+ server: {
58
+ cors: {
59
+ origin: ["https://example.com"], // Allow specific origins or '*' for all
60
+ allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
61
+ allowHeaders: ["Content-Type", "Authorization"],
62
+ credentials: false,
63
+ },
64
+ },
65
+ });
66
+ ```
@@ -122,7 +122,30 @@ The tabs help users understand how to connect to various MCP server providers an
122
122
  Each tab shows the specific URL patterns and configuration needed for that registry service.
123
123
  */}
124
124
 
125
- <Tabs items={["mcp.run", "Composio.dev", "Smithery.ai", "Ampersand"]}>
125
+ <Tabs items={["Klavis AI", "mcp.run", "Composio.dev", "Smithery.ai", "Ampersand"]}>
126
+ <Tabs.Tab>
127
+ [Klavis AI](https://klavis.ai) provides hosted, enterprise-authenticated, high-quality MCP servers.
128
+
129
+ ```typescript
130
+ import { MCPClient } from "@mastra/mcp";
131
+
132
+ const mcp = new MCPClient({
133
+ servers: {
134
+ salesforce: {
135
+ url: new URL("https://salesforce-mcp-server.klavis.ai/mcp/?instance_id={private-instance-id}"),
136
+ },
137
+ hubspot: {
138
+ url: new URL("https://hubspot-mcp-server.klavis.ai/mcp/?instance_id={private-instance-id}"),
139
+ },
140
+ },
141
+ });
142
+ ```
143
+
144
+ Klavis AI offers enterprise-grade authentication and security for production deployments.
145
+
146
+ For more details on how to integrate Mastra with Klavis, check out their [documentation](https://docs.klavis.ai/documentation/ai-platform-integration/mastra).
147
+
148
+ </Tabs.Tab>
126
149
  <Tabs.Tab>
127
150
  [mcp.run](https://www.mcp.run/) provides pre-authenticated, managed MCP servers. Tools are grouped into Profiles, each with a unique, signed URL.
128
151
 
@@ -313,7 +336,7 @@ Workflows will use their `inputSchema` for the tool's input.
313
336
 
314
337
  You can define an `outputSchema` for your tools to enforce a specific structure for the tool's output. This is useful for ensuring that the tool returns data in a consistent and predictable format, which can then be validated by the client.
315
338
 
316
- When a tool includes an `outputSchema`, its `execute` function **must** return an object containing a `structuredContent` property. The value of `structuredContent` must conform to the `outputSchema`. Mastra will automatically validate this output on both the server and client sides.
339
+ When a tool includes an `outputSchema`, its `execute` function **must** return an object. The value of the object must conform to the `outputSchema`. Mastra will automatically validate this output on both the server and client sides.
317
340
 
318
341
  Here's an example of a tool with an `outputSchema`:
319
342
 
@@ -331,12 +354,10 @@ export const structuredTool = createTool({
331
354
  timestamp: z.string().describe('An ISO timestamp.'),
332
355
  }),
333
356
  execute: async ({ input }) => {
334
- // When outputSchema is defined, you must return a structuredContent object
357
+ // When outputSchema is defined, you must return an object
335
358
  return {
336
- structuredContent: {
337
- processedInput: `processed: ${input}`,
338
- timestamp: new Date().toISOString(),
339
- },
359
+ processedInput: `processed: ${input}`,
360
+ timestamp: new Date().toISOString(),
340
361
  };
341
362
  },
342
363
  });
@@ -10,11 +10,13 @@ When you build a workflow, you typically break down operations into smaller task
10
10
  - If the schemas match, the `outputSchema` from each step is automatically passed to the `inputSchema` of the next step.
11
11
  - If the schemas don't match, use [Input data mapping](./input-data-mapping.mdx) to transform the `outputSchema` into the expected `inputSchema`.
12
12
 
13
- ## Sequential
13
+ ## Chaining steps with `.then()`
14
14
 
15
- Chain steps to execute in sequence using `.then()`:
15
+ Chain steps to execute sequentially using `.then()`:
16
16
 
17
- ```typescript {8-9} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
17
+ ![Chaining steps with .then()](/image/workflows/workflows-control-flow-then.jpg)
18
+
19
+ ```typescript {8-9,4-5} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
18
20
  import { createWorkflow, createStep } from "@mastra/core/workflows";
19
21
  import { z } from "zod";
20
22
 
@@ -27,31 +29,39 @@ export const testWorkflow = createWorkflow({...})
27
29
  .commit();
28
30
  ```
29
31
 
30
- ## Parallel
32
+ This does what you'd expect: it executes `step1`, then it executes `step2`.
33
+
34
+ ## Simultaneous steps with `.parallel()`
31
35
 
32
- Execute steps in parallel using `.parallel()`:
36
+ Execute steps simultaneously using `.parallel()`:
33
37
 
34
- ```typescript {8} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
38
+ ![Concurrent steps with .parallel()](/image/workflows/workflows-control-flow-parallel.jpg)
39
+
40
+ ```typescript {8,4-5} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
35
41
  import { createWorkflow, createStep } from "@mastra/core/workflows";
36
42
  import { z } from "zod";
37
43
 
38
44
  const step1 = createStep({...});
39
45
  const step2 = createStep({...});
46
+ const step3 = createStep({...});
40
47
 
41
48
  export const testWorkflow = createWorkflow({...})
42
49
  .parallel([step1, step2])
50
+ .then(step3)
43
51
  .commit();
44
52
  ```
45
53
 
46
- This executes all steps in the array concurrently, then continues to the next step after all parallel steps complete.
54
+ This executes `step1` and `step2` concurrently, then continues to `step3` after both complete.
47
55
 
48
56
  > See [Parallel Execution with Steps](/examples/workflows/parallel-steps) for more information.
49
57
 
50
- ## Branch
58
+ ## Conditional logic with `.branch()`
59
+
60
+ Execute steps conditionally using `.branch()`:
51
61
 
52
- Create conditional branches using `.branch()`:
62
+ ![Conditional branching with .branch()](/image/workflows/workflows-control-flow-branch.jpg)
53
63
 
54
- ```typescript {8-11} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
64
+ ```typescript {8-11,4-5} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
55
65
  import { createWorkflow, createStep } from "@mastra/core/workflows";
56
66
  import { z } from "zod";
57
67
 
@@ -60,8 +70,8 @@ const greaterThanStep = createStep({...});
60
70
 
61
71
  export const testWorkflow = createWorkflow({...})
62
72
  .branch([
63
- [async ({ inputData: { some_value } }) => some_value <= 9, lessThanStep],
64
- [async ({ inputData: { some_value } }) => some_value >= 10, greaterThanStep]
73
+ [async ({ inputData: { value } }) => (value < 9), lessThanStep],
74
+ [async ({ inputData: { value } }) => (value >= 9), greaterThanStep]
65
75
  ])
66
76
  .commit();
67
77
  ```
@@ -70,19 +80,20 @@ Branch conditions are evaluated sequentially, but steps with matching conditions
70
80
 
71
81
  > See [Workflow with Conditional Branching](/examples/workflows/conditional-branching) for more information.
72
82
 
73
- ## Loops
83
+ ## Looping steps
74
84
 
75
85
  Workflows support two types of loops. When looping a step, or any step-compatible construct like a nested workflow, the initial `inputData` is sourced from the output of the previous step.
76
86
 
77
- To ensure compatibility, the loop’s initial input must either:
87
+ To ensure compatibility, the loop’s initial input must either match the shape of the previous step’s output, or be explicitly transformed using the `map` function.
78
88
 
79
89
  - Match the shape of the previous step’s output, or
80
90
  - Be explicitly transformed using the `map` function.
81
91
 
92
+ ### Repeating with `.dowhile()`
82
93
 
83
- ### Dowhile
94
+ Executes step repeatedly while a condition is true.
84
95
 
85
- Executes a step repeatedly while a condition is true.
96
+ ![Repeating with .dowhile()](/image/workflows/workflows-control-flow-dowhile.jpg)
86
97
 
87
98
  ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
88
99
  import { createWorkflow, createStep } from "@mastra/core/workflows";
@@ -95,9 +106,11 @@ export const testWorkflow = createWorkflow({...})
95
106
  .commit();
96
107
  ```
97
108
 
98
- ### Dountil
109
+ ### Repeating with `.dountil()`
99
110
 
100
- Executes a step repeatedly until a condition becomes true.
111
+ Executes step repeatedly until a condition becomes true.
112
+
113
+ ![Repeating with .dountil()](/image/workflows/workflows-control-flow-dountil.jpg)
101
114
 
102
115
  ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
103
116
  import { createWorkflow, createStep } from "@mastra/core/workflows";
@@ -110,11 +123,12 @@ export const testWorkflow = createWorkflow({...})
110
123
  .commit();
111
124
  ```
112
125
 
113
-
114
- ### Foreach
126
+ ### Repeating with `.foreach()`
115
127
 
116
128
  Sequentially executes the same step for each item from the `inputSchema`.
117
129
 
130
+ ![Repeating with .foreach()](/image/workflows/workflows-control-flow-foreach.jpg)
131
+
118
132
  ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
119
133
  import { createWorkflow, createStep } from "@mastra/core/workflows";
120
134
  import { z } from "zod";
@@ -126,132 +140,116 @@ export const testWorkflow = createWorkflow({...})
126
140
  .commit();
127
141
  ```
128
142
 
129
- ### Early exit
143
+ #### Setting concurrency limits
130
144
 
131
- You can bail out of a workflow execution successfully by calling `bail()` in a step. This returns whatever payload is passed to the `bail()` function as the result of the workflow.
145
+ Use `concurrency` to execute steps in parallel with a limit on the number of concurrent executions.
132
146
 
133
147
  ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
134
148
  import { createWorkflow, createStep } from "@mastra/core/workflows";
135
149
  import { z } from "zod";
136
150
 
137
- const step1 = createStep({
138
- id: 'step1',
139
- execute: async ({ bail, inputData }) => {
140
- return bail({ result: 'bailed' });
141
- },
142
- inputSchema: z.object({ value: z.string() }),
143
- outputSchema: z.object({ result: z.string() }),
144
- });
151
+ const mapStep = createStep({...})
145
152
 
146
153
  export const testWorkflow = createWorkflow({...})
147
- .then(step1)
154
+ .foreach(mapStep, { concurrency: 2 })
148
155
  .commit();
149
156
  ```
150
157
 
151
- Unsuccessful bails happen through throwing an error in the step.
158
+ ## Using a nested workflow
152
159
 
153
- ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
160
+ Use a nested workflow as a step by passing it to `.then()`. This runs each of its steps in sequence as part of the parent workflow.
161
+
162
+ ```typescript {4,7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
154
163
  import { createWorkflow, createStep } from "@mastra/core/workflows";
155
164
  import { z } from "zod";
156
165
 
157
- const step1 = createStep({
158
- id: 'step1',
159
- execute: async ({ bail, inputData }) => {
160
- throw new Error('bailed');
161
- },
162
- inputSchema: z.object({ value: z.string() }),
163
- outputSchema: z.object({ result: z.string() }),
164
- });
166
+ export const nestedWorkflow = createWorkflow({...})
165
167
 
166
168
  export const testWorkflow = createWorkflow({...})
167
- .then(step1)
169
+ .then(nestedWorkflow)
168
170
  .commit();
169
171
  ```
170
- #### Example Run Instance
171
-
172
- The following example demonstrates how to start a run with multiple inputs. Each input will pass through the `mapStep` sequentially.
173
-
174
- ```typescript {6} filename="src/test-workflow.ts" showLineNumbers copy
175
- import { mastra } from "./mastra";
176
-
177
- const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
178
-
179
- const result = await run.start({
180
- inputData: [{ number: 10 }, { number: 100 }, { number: 200 }]
181
- });
182
- ```
183
-
184
- To execute this run from your terminal:
185
-
186
- ```bash copy
187
- npx tsx src/test-workflow.ts
188
- ```
189
172
 
190
- #### Concurrency
173
+ ## Cloning a workflow
191
174
 
192
- Optionally, using `concurrency` allows you to execute steps in parallel with a limit on the number of concurrent executions.
175
+ Use `cloneWorkflow` to duplicate an existing workflow. This lets you reuse its structure while overriding parameters like `id`.
193
176
 
194
- ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
195
- import { createWorkflow, createStep } from "@mastra/core/workflows";
177
+ ```typescript {6,10} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
178
+ import { createWorkflow, createStep, cloneWorkflow } from "@mastra/core/workflows";
196
179
  import { z } from "zod";
197
180
 
198
- const mapStep = createStep({...})
181
+ const step1 = createStep({...});
182
+ const parentWorkflow = createWorkflow({...})
183
+ const clonedWorkflow = cloneWorkflow(parentWorkflow, { id: "cloned-workflow" });
199
184
 
200
185
  export const testWorkflow = createWorkflow({...})
201
- .foreach(mapStep, { concurrency: 2 })
186
+ .then(step1)
187
+ .then(clonedWorkflow)
202
188
  .commit();
203
189
  ```
204
190
 
205
- ## Parallel Workflows
191
+ ## Exiting early with `bail()`
206
192
 
207
- Workflows themselves can also be executed in parallel.
193
+ Use `bail()` in a step to exit early with a successful result. This returns the provided payload as the step output and ends workflow execution.
208
194
 
209
- ```typescript {4-5,8} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
195
+ ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
210
196
  import { createWorkflow, createStep } from "@mastra/core/workflows";
211
197
  import { z } from "zod";
212
198
 
213
- const workflow1 = createWorkflow({...});
214
- const workflow2 = createWorkflow({...});
199
+ const step1 = createStep({
200
+ id: 'step1',
201
+ execute: async ({ bail }) => {
202
+ return bail({ result: 'bailed' });
203
+ },
204
+ inputSchema: z.object({ value: z.string() }),
205
+ outputSchema: z.object({ result: z.string() }),
206
+ });
215
207
 
216
208
  export const testWorkflow = createWorkflow({...})
217
- .parallel([workflow1, workflow2])
209
+ .then(step1)
218
210
  .commit();
219
211
  ```
220
212
 
221
- Parallel steps receive previous step results as input. Their outputs are passed into the next step input as an object where the key is the step `id` and the value is the step `output`.
213
+ ## Exiting early with `Error()`
222
214
 
223
- ## Nested Workflows
215
+ Use `throw new Error()` in a step to exit with an error.
224
216
 
225
- In the example below, `nestedWorkflow` is used as a step within `testWorkflow`. The `testWorkflow` uses `step1` whilst the `nestedWorkflow` composes `step2` and `step3`
226
-
227
-
228
- ```typescript {4,7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
217
+ ```typescript {7} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
229
218
  import { createWorkflow, createStep } from "@mastra/core/workflows";
230
219
  import { z } from "zod";
231
220
 
232
- export const nestedWorkflow = createWorkflow({...})
221
+ const step1 = createStep({
222
+ id: 'step1',
223
+ execute: async () => {
224
+ throw new Error('bailed');
225
+ },
226
+ inputSchema: z.object({ value: z.string() }),
227
+ outputSchema: z.object({ result: z.string() }),
228
+ });
233
229
 
234
230
  export const testWorkflow = createWorkflow({...})
235
- .then(nestedWorkflow)
231
+ .then(step1)
236
232
  .commit();
237
233
  ```
238
234
 
239
- When using `.branch()` or `.parallel()` to build more complex control flows, executing more than one step requires wrapping those steps in a nested workflow, along with a clear definition of how they should be executed.
235
+ This throws an error from the step and stops workflow execution, returning the error as the result.
240
236
 
237
+ ## Example Run Instance
241
238
 
242
- ## Cloned Workflows
239
+ The following example demonstrates how to start a run with multiple inputs. Each input will pass through the `mapStep` sequentially.
243
240
 
244
- In the example below, `clonedWorkflow` is a clone of `workflow1` and is used as a step within `testWorkflow`. The `clonedWorkflow` is run sequentially after `step1`.
241
+ ```typescript {6} filename="src/test-workflow.ts" showLineNumbers copy
242
+ import { mastra } from "./mastra";
245
243
 
246
- ```typescript {5,9} filename="src/mastra/workflows/test-workflow.ts" showLineNumbers copy
247
- import { createWorkflow, createStep, cloneWorkflow } from "@mastra/core/workflows";
248
- import { z } from "zod";
244
+ const run = await mastra.getWorkflow("testWorkflow").createRunAsync();
249
245
 
250
- const step1 = createStep({...});
251
- const clonedWorkflow = cloneWorkflow(step1, { id: "cloned-workflow" });
246
+ const result = await run.start({
247
+ inputData: [{ number: 10 }, { number: 100 }, { number: 200 }]
248
+ });
249
+ ```
252
250
 
253
- export const testWorkflow = createWorkflow({...})
254
- .then(step1)
255
- .then(clonedWorkflow)
256
- .commit();
251
+ To execute this run from your terminal:
252
+
253
+ ```bash copy
254
+ npx tsx src/test-workflow.ts
257
255
  ```