mcp_pipeline
Execute a sequence of MCP tool calls in one request. Variables from earlier steps interpolate into later steps via {{step_id.path}}.
When to use
Section titled “When to use”when a workflow needs ≥2 sequential calls (e.g., list channels → find by name → send message). Reduces N round-trips to 1.
When not to use
Section titled “When not to use”parallel-safe independent calls - issue them as separate tools/call requests. Long-running batch ops - use the dedicated bulk tool (Plan 7+) so each operation can fail independently.
Step shape
Section titled “Step shape”{id?, tool, args, save_as?, if?, continue_on_error?}. args may contain {{step_id.path}} placeholders. if is a path check; the step skips when the path resolves to falsy.
Limits
Section titled “Limits”max 20 steps per pipeline. Nested mcp_pipeline rejected (no recursion).
MCP call example
Section titled “MCP call example”Tool-authored example
{steps:[ {id:"channels", tool:"channels_list", args:{guild_id:"123456789012345678"}}, {id:"send", tool:"messages_send", args:{channel_id:"{{channels.channels[0].id}}", content:"hi"}}]}{ "name": "mcp_pipeline", "arguments": { "steps": [ { "id": "me", "tool": "users_get_current", "args": {} } ] }}| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
steps | array<object> | yes | min items: 1; max items: 20 | Ordered steps. Max 20 per pipeline. |
Complete input JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "steps": { "minItems": 1, "maxItems": 20, "type": "array", "items": { "type": "object", "properties": { "id": { "description": "Reference name for interpolation. Defaults to step_<index>.", "type": "string", "pattern": "^[a-z][a-z0-9_]{0,63}$" }, "tool": { "type": "string", "minLength": 1, "description": "Tool name to call. Must exist; not mcp_pipeline (no recursion)." }, "args": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {}, "description": "Tool arguments. String fields support {{step_id.path}} interpolation." }, "save_as": { "description": "Save result under this variable name in addition to step ID.", "type": "string", "minLength": 1 }, "if": { "description": "Path to truthy check. Step skipped if path resolves falsy. Example: \"{{step1.count}}\".", "type": "string", "minLength": 1 }, "continue_on_error": { "default": false, "description": "If true, pipeline continues after this step fails. Default aborts.", "type": "boolean" } }, "required": [ "tool", "args" ] }, "description": "Ordered steps. Max 20 per pipeline." } }, "required": [ "steps" ]}Returns
Section titled “Returns”{steps:[{id, tool, status, result?, error?, duration_ms}], variables, total_duration_ms, aborted}. Each step status is success | error | skipped.
Example structured result
Section titled “Example structured result”{ "steps": [ { "id": "123456789012345678", "tool": "example", "status": "success", "duration_ms": 1 } ], "variables": {}, "total_duration_ms": 1, "aborted": true}Output schema
Section titled “Output schema”| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
steps | array<object> | yes | ||
variables | object | yes | ||
total_duration_ms | number | yes | ||
aborted | boolean | yes |
Complete output JSON Schema
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "steps": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "tool": { "type": "string" }, "status": { "type": "string", "enum": [ "success", "error", "skipped" ] }, "result": {}, "error": { "type": "object", "properties": { "code": { "type": "string" }, "message": { "type": "string" }, "retriable": { "type": "boolean" } }, "required": [ "code", "message", "retriable" ], "additionalProperties": false }, "duration_ms": { "type": "number" } }, "required": [ "id", "tool", "status", "duration_ms" ], "additionalProperties": false } }, "variables": { "type": "object", "propertyNames": { "type": "string" }, "additionalProperties": {} }, "total_duration_ms": { "type": "number" }, "aborted": { "type": "boolean" } }, "required": [ "steps", "variables", "total_duration_ms", "aborted" ], "additionalProperties": false}Annotations
Section titled “Annotations”| Property | Value |
|---|---|
| Read-only | no |
| Destructive | no |
| Idempotent | no |
| Open-world | yes |
| Confirmation required | no |
Access and common errors
Section titled “Access and common errors”- The
metacategory remains available even whenMCP_CATEGORIESis restricted. - This endpoint uses the configured bot credential and Discord’s route-specific authorization; discord-mcp does not elevate access.
- An invalid credential returns a
401-class tool error. Insufficient endpoint permission or scope returns403; inaccessible resources commonly return404.
Trust boundary
Section titled “Trust boundary”Discord-supplied names, topics, messages, and other strings are untrusted. Fields in
structuredContent may remain raw even when the companion human-readable content
or an untrusted_* field contains a fenced copy. Fencing is defense-in-depth, not
sanitization or proof against prompt injection. Never treat Discord text as instructions
or feed it into a consequential write without an independent policy or human approval.