Pipelines
On this page
Creating a pipelinePipeline statusInput mappingExecuting a pipelineMCP and A2A integrationVisual builderRun historyAPI referenceParallel groupsLimitsPipelines let you chain MCP tools into sequential workflows. The output of one tool feeds the input of the next. Active pipelines are automatically exposed as MCP tools and A2A skills.
Creating a pipeline
Dashboard
Navigate to Pipelines in the sidebar. Click Create Pipeline, enter a name and description, then use the visual builder to add steps.
API
curl -X POST https://api.fold.run/pipelines \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "summarize-and-translate",
"description": "Summarize text then translate to Spanish",
"steps": [
{ "id": "step_1", "tool_name": "summarize", "function_id": "fn_abc", "position": 0 },
{ "id": "step_2", "tool_name": "translate", "function_id": "fn_xyz", "position": 1 }
],
"input_schema": {
"type": "object",
"properties": { "text": { "type": "string" } }
}
}'Pipeline status
| Status | Description |
|---|---|
draft |
Pipeline is being built. Can be executed for testing but not exposed via MCP/A2A. |
active |
Pipeline is live. Auto-registered as pipeline:{name} MCP tool and A2A skill. |
archived |
Pipeline is disabled. Cannot be executed. |
Input mapping
Each step can map its input from three sources:
| Source | Format | Example |
|---|---|---|
| Pipeline input | $input.fieldName |
$input.text |
| Previous step output | $steps.step_id.fieldName |
$steps.step_1.summary |
| Literal value | literal:value |
literal:es |
If no input_mapping is specified, the entire output of the previous step (or the pipeline input for the first step) is passed through.
Example
{
"steps": [
{
"id": "step_1",
"tool_name": "summarize",
"function_id": "fn_abc",
"position": 0,
"input_mapping": { "text": "$input.text" }
},
{
"id": "step_2",
"tool_name": "translate",
"function_id": "fn_xyz",
"position": 1,
"input_mapping": {
"text": "$steps.step_1.summary",
"target_language": "literal:es"
}
}
]
}Executing a pipeline
curl -X POST https://api.fold.run/pipelines/pipe_abc/execute \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "input": { "text": "Long article to process..." } }'The response includes the final output and per-step results:
{
"id": "run_xyz",
"pipeline_id": "pipe_abc",
"status": "completed",
"output": { "translated": "Resumen en espanol..." },
"step_results": [
{ "step_id": "step_1", "tool_name": "summarize", "status": "success", "duration_ms": 120 },
{ "step_id": "step_2", "tool_name": "translate", "status": "success", "duration_ms": 85 }
],
"duration_ms": 205
}MCP and A2A integration
Active pipelines are automatically registered as:
- MCP tool:
pipeline:{name}— callable via your/.well-known/mcpendpoint - A2A skill:
pipeline:{name}— callable viatasks/sendortasks/sendSubscribeat/_a2a/
Agents see pipelines alongside individual tools in the MCP tool list and Agent Card skills.
Visual builder
The dashboard includes a React Flow-based visual builder at Pipelines > {pipeline name}:
- Drag tools from the palette on the right
- Steps are displayed vertically with animated connections
- Click a step to configure its input mapping
- Use the action bar to Save, toggle Active/Draft, and run test executions
Run history
Each pipeline execution is recorded. View run history at Pipelines > {pipeline name} or via the API:
GET /pipelines/{id}/runs # List runs
GET /pipelines/runs/{runId} # Get specific runAPI reference
| Method | Path | Description |
|---|---|---|
GET /pipelines |
List pipelines | |
POST /pipelines |
Create pipeline | |
GET /pipelines/:id |
Get pipeline | |
PUT /pipelines/:id |
Update pipeline (bumps version) | |
DELETE /pipelines/:id |
Delete pipeline | |
POST /pipelines/:id/execute |
Execute pipeline | |
GET /pipelines/:id/runs |
List runs | |
GET /pipelines/runs/:runId |
Get run details |
Parallel groups
Steps with the same parallel_group value in consecutive positions run concurrently instead of sequentially. Steps without a parallel_group run one at a time as before.
{
"steps": [
{ "id": "s1", "tool_name": "fetch-data", "function_id": "fn_1", "position": 0 },
{ "id": "s2", "tool_name": "enrich-a", "function_id": "fn_2", "position": 1, "parallel_group": "enrich" },
{ "id": "s3", "tool_name": "enrich-b", "function_id": "fn_3", "position": 2, "parallel_group": "enrich" },
{ "id": "s4", "tool_name": "merge", "function_id": "fn_4", "position": 3 }
]
}In this example, steps s2 and s3 run in parallel after s1 completes. Step s4 runs after both parallel steps finish. The output of a parallel group is an object keyed by step ID: { "s2": <output>, "s3": <output> }.
Use $steps.s2.field or $steps.s3.field in the input mapping of subsequent steps to reference individual parallel step outputs.
Limits
- Maximum 20 steps per pipeline
- Pipeline name must match
^[a-z0-9][a-z0-9-]*$(max 63 characters) - Parallel groups must contain consecutive steps with the same
parallel_groupvalue