Workflows execute jobs in dependency order with automatic cycle detection, parallel batching, and per-step error handling.
Why Workflows?
Workflows handle orchestration that individual jobs cannot:| Aspect | Job | Workflow | Skill |
|---|---|---|---|
| Purpose | Single unit of work | Multi-step pipeline | AI instruction guide |
| Composition | Standalone | Chains multiple jobs | References tools |
| Dependencies | None | DAG with dependsOn | None |
| Parallelism | Single execution | Bounded concurrent steps | None |
| Triggers | On-demand | Manual, webhook, or event | On-demand |
- Multi-step data pipelines — extract, transform, load sequences
- Approval chains — sequential steps with conditional logic
- Parallel processing — fan-out/fan-in patterns with bounded concurrency
- Event-driven automation — webhook-triggered multi-job flows
Creating Workflows
Workflows are defined declaratively using the@Workflow decorator with a steps array:
Function Style
Registering Workflows
Add workflows to your app via theworkflows array:
Jobs referenced by workflow steps must be registered in the same app or available in the scope’s job registry.
Workflow Steps
Each step defines a job to execute and how it connects to other steps:| Field | Type | Default | Description |
|---|---|---|---|
id | string | — | Required. Unique step identifier |
jobName | string | — | Required. Name of the job to execute |
dependsOn | string[] | [] | Step IDs that must complete before this step runs |
input | object | function | Workflow input | Static input or dynamic callback from previous step outputs |
condition | function | — | Skip step if returns false |
continueOnError | boolean | false | Continue workflow if this step fails |
timeout | number | Job default | Per-step timeout override in ms |
retry | JobRetryConfig | Job default | Per-step retry override |
Step Dependencies
Steps declare dependencies usingdependsOn. The engine validates the DAG before execution:
- Duplicate ID detection — no two steps can share an ID
- Missing reference detection —
dependsOnmust reference existing step IDs - Cycle detection — DFS-based cycle detection prevents infinite loops
Dynamic Input
Steps can compute their input dynamically based on previous step outputs:steps context provides a get(stepId) method that returns WorkflowStepResult:
Conditional Steps
Steps can be conditionally skipped based on previous step results:false, the step is marked as skipped and downstream steps that depend on it will still execute (skipped steps are treated as completed for dependency resolution).
Parallel Execution
Steps with no mutual dependencies execute in parallel, bounded bymaxConcurrency:
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
name | string | — | Required. Unique workflow identifier |
description | string | — | Human-readable description |
steps | WorkflowStep[] | — | Required. Ordered step definitions (min 1) |
trigger | 'manual' | 'webhook' | 'event' | 'manual' | How the workflow is triggered |
webhook | WorkflowWebhookConfig | — | Webhook configuration (when trigger is 'webhook') |
timeout | number | 600000 | Maximum total execution time in ms (10 min) |
maxConcurrency | number | 5 | Maximum parallel step concurrency |
id | string | name | Stable identifier for tracking |
tags | string[] | — | Categorization tags |
labels | Record<string, string> | — | Fine-grained key-value labels |
hideFromDiscovery | boolean | false | Hide from list-workflows |
permissions | JobPermission[] | — | RBAC permission rules |
inputSchema | ZodShape | — | Workflow-level input schema |
outputSchema | ZodShape | — | Workflow-level output schema |
Webhook Configuration
Triggers
| Trigger | Description |
|---|---|
manual | Triggered via execute-workflow tool or DirectClient |
webhook | Triggered by HTTP webhook with optional secret validation |
event | Triggered by internal events |
Execution Flow
Error Handling
When a step fails:- Default behavior — the step is marked as
failed, and downstream dependents areskipped - With
continueOnError: true— the step is marked asfailedbut treated as completed for dependency resolution, allowing downstream steps to proceed
MCP Tools
When workflows are enabled, the following MCP tools are automatically registered:| Tool | Description |
|---|---|
list-workflows | List registered workflows with optional filtering |
execute-workflow | Execute a workflow (inline or background) |
get-workflow-status | Get execution status with per-step results |
register-workflow | Register a dynamic workflow at runtime |
remove-workflow | Remove a dynamic workflow |
Best Practices
Do:- Keep steps focused on a single job each
- Use
dependsOnto make data flow explicit - Set
continueOnError: truefor non-critical steps - Use dynamic input functions to pass data between steps
- Set appropriate
maxConcurrencybased on resource constraints
- Create deeply nested dependency chains when parallel execution is possible
- Skip DAG validation by referencing non-existent step IDs
- Set
maxConcurrencytoo high for resource-intensive jobs - Use workflows for single-step operations (use jobs directly)
Next Steps
Jobs
Define the jobs that workflows orchestrate
@Workflow
Decorator reference
WorkflowRegistry
Registry API reference
DirectClient
Programmatic workflow execution