You can now add dynamic workflows to your live Mastra server without changing or redeploying code. Users, external systems, or agents can build workflows on the fly as structured JSON objects, then add them to a running Mastra server.
Before dynamic workflows, every workflow had to be authored in TypeScript, registered with the Mastra instance, and deployed as part of the server bundle. Now, creating workflows isn't limited to engineers who can write and deploy code — agents or other team members can create them too.
A dynamic workflow is a graph of agents, tools, and control-flow steps, persisted in storage as JSON that references registered primitives by id. Once added to a live server, a dynamic workflow is available to run from any HTTP client.
Workflow steps still need to receive expected inputs and pass expected outputs. You can use mapConfig to read from ${initData._} (the workflow input) or ${stepResults.<id>._} (a prior step's output), so any agent or tool can be used at any step.
Get started
Install @mastra/core and a storage adapter to persist workflow definitions:
npm install @mastra/core @mastra/libsql@mastra/core@1.58.0 or later, added in PR #20471.Register the agents and tools dynamic workflows can reference. This is a standard Mastra setup — the only additional requirement is a storage adapter:
import { Mastra } from "@mastra/core/mastra";
import { LibSQLStore } from "@mastra/libsql";
import { subjectExtractor } from "./agents/subject-extractor-agent";
import { summarizer } from "./agents/summarizer-agent";
import { exaWebSearch } from "./tools/exa-web-search-tool";
export const mastra = new Mastra({
storage: new LibSQLStore({
id: "mastra-storage",
url: "file:./mastra.db"
}),
agents: { subjectExtractor, summarizer },
tools: { exaWebSearch }
});Manage over HTTP
The examples below show how to manage dynamic workflows using server routes. The Mastra Client SDK's workflows API can also be used.
UPSERT workflow
To update or insert a workflow definition and registered on the Mastra instance, send a POST request to /api/stored/workflows with a valid JSON body:
await fetch(`${MASTRA_URL}/api/stored/workflows`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
id: "wf-nnxe8nah",
description: "A quick test workflow",
inputSchema: {},
outputSchema: {},
graph: [
{
type: "mapping",
id: "map-to-subject-extractor",
mapConfig: '{"prompt":{"template":"${initData.message}"}}'
},
{
type: "agent",
id: "subject-extractor",
agentId: "subject-extractor",
description: "Extracts the main subject from a user message"
}
]
})
});### GET workflows
To list registered workflows, send a GET request to /api/stored/workflows:
const res = await fetch(`${MASTRA_URL}/api/stored/workflows`, {
method: "GET"
});
const { workflows } = await res.json();DELETE workflow
To delete a registered workflow, send a DELETE request to /api/stored/workflows/:id, passing the id of the workflow you want to remove:
await fetch(`${MASTRA_URL}/api/stored/workflows/${id}`, {
method: "DELETE"
});For more information and full configuration options, see:
