Skip to content

Chain three calls

When a workflow is a strict sequence - each step depends on the previous one’s output - issuing N independent tools/call requests wastes round-trips and exposes intermediate state. The mcp_pipeline meta-tool batches them into one request, with {{step_id.path}} interpolation between steps.

A community manager says: “Announce the office-hours session in #announcements, create a scheduled event for it, then give the host the ‘event-host’ role.”

Three calls. Each depends on the previous. Pipeline-shaped.

  1. Build the pipeline payload.

    Each step has id (for interpolation), tool (the tool name), and args. Strings inside args may contain {{step_id.path}} placeholders. Below the announcement step’s message_id flows into the event’s description. The host’s user ID and the role ID are known workflow inputs and are supplied directly to the role-grant step.

    {
    "name": "mcp_pipeline",
    "arguments": {
    "steps": [
    {
    "id": "announce",
    "tool": "messages_send",
    "args": {
    "channel_id": "222233334444555566",
    "content": "Office hours start in 30 minutes! React with :wave: to attend."
    }
    },
    {
    "id": "event",
    "tool": "events_create",
    "args": {
    "guild_id": "111122223333444455",
    "name": "Office hours - January 1",
    "scheduled_start_time": "2030-01-01T17:00:00Z",
    "scheduled_end_time": "2030-01-01T18:00:00Z",
    "entity_type": 3,
    "privacy_level": 2,
    "entity_metadata": { "location": "https://discord.com/channels/111122223333444455/222233334444555566/{{announce.message_id}}" },
    "description": "Linked to announcement {{announce.message_id}}"
    }
    },
    {
    "id": "grant",
    "tool": "members_add_role",
    "args": {
    "guild_id": "111122223333444455",
    "user_id": "777788889999000011",
    "role_id": "555566667777888899"
    }
    }
    ]
    }
    }
  2. Read the response.

    The pipeline returns steps[] with per-step status, variables (the interpolation namespace at completion), total_duration_ms, and aborted.

    {
    "steps": [
    {
    "id": "announce",
    "tool": "messages_send",
    "status": "success",
    "result": {
    "message_id": "888899990000111122",
    "channel_id": "222233334444555566",
    "jump_url": "https://discord.com/channels/111122223333444455/222233334444555566/888899990000111122",
    "timestamp": "2030-01-01T16:30:00.000Z"
    },
    "duration_ms": 142
    },
    {
    "id": "event",
    "tool": "events_create",
    "status": "success",
    "result": {
    "id": "333344445555666677",
    "guild_id": "111122223333444455",
    "name": "Office hours - January 1",
    "description": "Linked to announcement 888899990000111122",
    "scheduled_start_time": "2030-01-01T17:00:00.000Z",
    "scheduled_end_time": "2030-01-01T18:00:00.000Z",
    "status": 1,
    "entity_type": 3,
    "channel_id": null
    },
    "duration_ms": 218
    },
    {
    "id": "grant",
    "tool": "members_add_role",
    "status": "success",
    "result": {
    "added": true,
    "user_id": "777788889999000011",
    "role_id": "555566667777888899"
    },
    "duration_ms": 96
    }
    ],
    "variables": {
    "announce": { "message_id": "888899990000111122", "channel_id": "222233334444555566" },
    "event": { "id": "333344445555666677", "name": "Office hours - May 1" },
    "grant": { "added": true, "user_id": "777788889999000011", "role_id": "555566667777888899" }
    },
    "total_duration_ms": 456,
    "aborted": false
    }
  • Default abort-on-error. When a step returns an error, the pipeline sets aborted: true and stops immediately. Subsequent steps are not dispatched and do not appear in steps - the array simply ends at the failing step. The agent sees exactly which step blew up and what the partial state is.
  • Continue past errors. Set continue_on_error: true on a step to keep going. Use sparingly - it implies later steps must tolerate missing interpolation values.
  • Recursion guard. A step whose tool is mcp_pipeline is rejected up front with the error code PIPELINE_RECURSION. The pipeline aborts before running any step.
  • Limit. Pipelines cap at 20 steps. For larger workloads, split into multiple pipelines or use the dedicated bulk tool for that resource.
ConcernN separate tools/callOne mcp_pipeline
Round-tripsN1
Stop after a failed stepclient must re-implementserver-side, built in
Intermediate stateclient jugglesexposed via variables
Audit loggingDepends on each tool’s idempotency metadataOne parent event plus events for non-idempotent leaves; idempotent leaves are skipped