Using Workflows via MCP Tools

The workflow engine exposes five MCP tools. Any agent connected to the MCP server with the workflow permission can use them. This is the primary way AI agents create and monitor workflows.

Available Tools

Tool Description
workflow_create Define and start a workflow
workflow_list List workflows with status
workflow_get Get a workflow and its step history
workflow_cancel Cancel a running workflow
workflow_step_ready Unblock a pending step (approval gate)

workflow_create

Creates a workflow and starts it immediately. The flow object defines the step graph. The input object provides variables that step args can reference as {{input.key}}.

Parameters:

Example – two-step sequential workflow:

{
  "name": "greet-and-count",
  "flow": {
    "start": {
      "name": "greet",
      "tool": "get_greeting",
      "args": {"name": "World"},
      "next": "count"
    },
    "count": {
      "name": "count",
      "tool": "get_counter",
      "args": {},
      "done": true
    }
  },
  "input": {}
}

Response:

{"id": 1773850841512, "status": "started"}

Example – with input variables:

{
  "name": "research",
  "flow": {
    "start": {
      "name": "search",
      "tool": "knowledge_search",
      "args": {"query": "{{input.topic}}"},
      "done": true
    }
  },
  "input": {"topic": "MCP server architecture"}
}

Example – branching on a condition:

{
  "name": "conditional",
  "flow": {
    "start": {
      "name": "check_admin",
      "tool": "is_admin",
      "args": {},
      "branch": [
        {"if": "result == true",  "then": "admin_step"},
        {"if": "result == false", "then": "user_step"}
      ]
    },
    "admin_step": {
      "name": "admin_step",
      "tool": "knowledge_list",
      "args": {},
      "done": true
    },
    "user_step": {
      "name": "user_step",
      "tool": "get_greeting",
      "args": {"name": "World"},
      "done": true
    }
  },
  "input": {}
}

Example – approval gate before a write:

{
  "name": "approved-write",
  "flow": {
    "start": {
      "name": "await_approval",
      "tool": null,
      "args": {},
      "next": "write_doc"
    },
    "write_doc": {
      "name": "write_doc",
      "tool": "knowledge_add",
      "args": {
        "title": "{{input.title}}",
        "content": "{{input.content}}",
        "scope": "general"
      },
      "done": true
    }
  },
  "input": {
    "title": "Deployment Runbook",
    "content": "Steps for deploying to production..."
  }
}

The await_approval step has "tool": null – it runs as a no-op and waits. Use workflow_step_ready to unblock it.

Example – parallel fan-out:

{
  "name": "parallel-research",
  "flow": {
    "start": {
      "name": "fan_out",
      "tool": null,
      "args": {},
      "parallel": ["search_docs", "search_blogs"]
    },
    "search_docs": {
      "name": "search_docs",
      "tool": "knowledge_search",
      "args": {"query": "{{input.topic}}"},
      "join": "summarize"
    },
    "search_blogs": {
      "name": "search_blogs",
      "tool": "knowledge_search_text",
      "args": {"query": "{{input.topic}}"},
      "join": "summarize"
    },
    "summarize": {
      "name": "summarize",
      "tool": "get_greeting",
      "args": {"name": "World"},
      "done": true
    }
  },
  "input": {"topic": "workflow engines"}
}

Both search steps run concurrently. summarize is created only after both complete.


workflow_list

Lists workflows. Returns newest first.

Parameters:

Response:

[
  {
    "id": 1773850841512,
    "name": "research",
    "status": "completed",
    "created_by": "james",
    "completed_at": 1773850843000
  },
  {
    "id": 1773850800000,
    "name": "approved-write",
    "status": "running",
    "created_by": "james",
    "completed_at": null
  }
]

Statuses: running, completed, failed, cancelled.


workflow_get

Returns a workflow with its full step history.

Parameters:

Response:

{
  "id": 1773850841512,
  "name": "research",
  "status": "completed",
  "created_by": "james",
  "steps": [
    {
      "id": 1773850841600,
      "name": "search",
      "tool": "knowledge_search",
      "status": "done",
      "attempt": 1,
      "result_json": "[{\"title\":\"Workflow Design\",\"score\":0.95}]",
      "started_at": 1773850841700,
      "completed_at": 1773850842500
    }
  ]
}

Use this to:


workflow_cancel

Cancels a running or paused workflow immediately.

Parameters:

Response:

{"cancelled": true}

workflow_step_ready

Unblocks a pending or paused step. The primary use case is releasing an approval gate after a human reviews and approves.

Parameters:

Response:

{"queued": true}

The executor picks it up on the next poll (within one second).


Typical Agent Pattern

An agent creating a workflow, waiting for it to complete, and reading the result:

1. Call workflow_create with name, flow, input
   -> receive {id: 1773850841512}

2. Call workflow_get with id: 1773850841512
   -> check status

3. If status == "running": wait and call workflow_get again
   If status == "completed": read step results from steps array
   If status == "failed": check last step's result_json for error

4. For approval gates:
   -> workflow_get shows a step with tool=null and status="running"
   -> notify human (via Pushover, WhatsApp, etc.)
   -> when human approves, call workflow_step_ready with step_id
   -> poll workflow_get until status == "completed"

Supported Condition Strings for Branching

The "if" field in branch specs supports these exact strings:

Condition Matches when
"result == true" Tool returned true
"result == false" Tool returned false
"result != nil" Tool returned any non-null value
"result == nil" Tool returned null
"result == \"some_value\"" Tool returned the exact string some_value

Conditions are evaluated by exact pattern matching – no expression evaluation.


Flow Definition Reference

Every step spec is an object with these fields:

Field Required Description
name yes Step name (unique within the workflow)
tool yes MCP tool to call, or null for no-op/approval gate
args no Args map for the tool, supports {{input.key}} templates
next one of Name of the next step (sequential)
branch one of Array of {if, then} objects (conditional)
parallel one of Array of step names to run concurrently
join one of Name of the join step to create when this parallel branch finishes
done one of true to mark the workflow complete

The "start" key in the flow object points to the first step spec. All other keys are step names used by next, branch, parallel, and join references.