# Workflows MCP tools

> Tool descriptions and complete input schemas for workflow operations.

Source: https://docs.graph8.com/developers/mcp-reference/workflow/

Use this reference to find a tool and its inputs. [Connect an MCP client](https://docs.graph8.com/developers/mcp/) before calling tools. Tool visibility depends on discovery and permissions.

For actions that send messages, spend credits, delete data, or start execution, review the intended records and confirm the action before proceeding. Obtain IDs from a prior result; do not invent them. A registered tool does not guarantee that its supporting service is available in every organization.

## g8_workflow_add_node

> Add one node to an existing workflow's graph. Fetches the current graph, appends the node (and optionally one edge), and PUTs the result. Errors if ``node_id`` already exists - use ``g8_workflow_update_node`` for that. Writes the node in canonical snake_case. When ``connect_from`` is set, appends the edge AND appends ``node_id`` to the source node's ``connections`` list (the executor traverses ``connections``, not ``edges``, so an edge-only node never runs). Prefer ``add_node(..., connect_from=upstream)`` over a separate ``connect_nodes`` call - same result, one fewer PUT. Args: action_id: Workflow id. node_id: New node's id, unique within the graph. Convention: ``&#123;node_type&#125;-&#123;8-hex&#125;`` (e.g. ``send_email-2e3bb0d7``). node_type: A value from ``g8_workflow_list_node_types``. config: Per-node config dict; shape varies by node_type (see ``g8_workflow_describe_node_type``). label: Optional display label. Defaults to ``node_type``. position: Optional ``&#123;"x": float, "y": float&#125;``. Defaults to ``&#123;"x": 0, "y": 0&#125;``. connect_from: Optional source node id. Adds edge ``connect_from -&gt; node_id`` and appends ``node_id`` to that node's ``connections``. Skip to wire up later via ``g8_workflow_connect_nodes``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `node_id` | Yes | string | See the schema below for constraints and defaults. |
| `node_type` | Yes | string | See the schema below for constraints and defaults. |
| `config` | No | object / null | See the schema below for constraints and defaults. |
| `label` | No | string / null | See the schema below for constraints and defaults. |
| `position` | No | object / null | See the schema below for constraints and defaults. |
| `connect_from` | No | string / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "node_id": {
      "title": "Node Id",
      "type": "string"
    },
    "node_type": {
      "title": "Node Type",
      "type": "string"
    },
    "config": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Config"
    },
    "label": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Label"
    },
    "position": {
      "anyOf": [
        {
          "additionalProperties": {
            "type": "number"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Position"
    },
    "connect_from": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Connect From"
    }
  },
  "required": [
    "action_id",
    "node_id",
    "node_type"
  ],
  "title": "add_nodeArguments",
  "type": "object"
}
```

</details>

## g8_workflow_connect_nodes

> Add an edge connecting one node to another. DUAL write: appends to top-level ``edges`` AND appends ``target`` to the source node's ``connections`` list (the field the executor actually traverses; an edge without it renders but never executes). Idempotent on (source, target) when both are already present. For branch / decision nodes, pass ``condition`` to set the edge label, and use ``g8_workflow_update_node`` to set the source node's ``conditional_connections`` (&#123;path_id: target_node_id&#125;). Args: action_id: Workflow id. source: Upstream node id. target: Downstream node id. edge_id: Optional explicit edge id. Defaults to ``"edge-&#123;source&#125;-&#123;target&#125;"``. condition: Optional condition string for branch / decision nodes (e.g. ``"true"``, ``"false"``, ``"matches_icp"``).

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `source` | Yes | string | See the schema below for constraints and defaults. |
| `target` | Yes | string | See the schema below for constraints and defaults. |
| `edge_id` | No | string / null | See the schema below for constraints and defaults. |
| `condition` | No | string / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "source": {
      "title": "Source",
      "type": "string"
    },
    "target": {
      "title": "Target",
      "type": "string"
    },
    "edge_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Edge Id"
    },
    "condition": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Condition"
    }
  },
  "required": [
    "action_id",
    "source",
    "target"
  ],
  "title": "connect_nodesArguments",
  "type": "object"
}
```

</details>

## g8_workflow_create

> Create a new workflow. Persists a real workflow row - ALWAYS confirm with the user first. Recommended pattern: run ``g8_workflow_validate``, then call with ``dry_run=True`` to render a confirmation widget, then ``dry_run=False`` after the user confirms. ``config`` follows the canonical snake_case shape. Each node MUST carry a ``connections`` list (the executor traverses via ``node.connections[0]``, NOT top-level ``edges``); a node with only an edge halts the executor. Branch / condition nodes also use ``conditional_connections`` (&#123;path_id: target_node_id&#125;) to gate which downstream branch fires. Shape (per node): ``&#123;node_id, node_type, name, config, position, connections: [...]&#125;`` plus a top-level ``&#123;metadata, settings, start_node_id, nodes: [...], edges: [...]&#125;``. Get the per-node-type ``config`` fields from ``g8_workflow_describe_node_type``. Conventions: ``node_id`` = ``&#123;node_type&#125;-&#123;8-hex&#125;``, ``edge.id`` = ``edge-&#123;source&#125;-&#123;target&#125;``, cross-node refs = ``$&#123;node_id.field&#125;``, and ``input_mappings`` = ``[&#123;target_field, source_expression&#125;]``. ``runtime_type='workflow'`` and ``org_id`` are pinned server-side. Args: name: Workflow display name. config: The graph dict (nodes / edges / start_node_id / trigger). description: Optional human-readable summary. category: Optional grouping (e.g. ``"sales"``). enabled: Default ``False`` so a fresh workflow stays paused until the user enables it. Set ``True`` only if already approved. dry_run: When ``True``, return a confirmation preview without creating the workflow.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `name` | Yes | string | See the schema below for constraints and defaults. |
| `config` | Yes | object | See the schema below for constraints and defaults. |
| `description` | No | string / null | See the schema below for constraints and defaults. |
| `category` | No | string / null | See the schema below for constraints and defaults. |
| `enabled` | No | boolean | See the schema below for constraints and defaults. |
| `dry_run` | No | boolean | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "name": {
      "title": "Name",
      "type": "string"
    },
    "config": {
      "additionalProperties": true,
      "title": "Config",
      "type": "object"
    },
    "description": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Description"
    },
    "category": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Category"
    },
    "enabled": {
      "default": false,
      "title": "Enabled",
      "type": "boolean"
    },
    "dry_run": {
      "default": false,
      "title": "Dry Run",
      "type": "boolean"
    }
  },
  "required": [
    "name",
    "config"
  ],
  "title": "create_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_create_workbench

> Create an empty workbench and return its ``workbench_id``. Use when a workflow needs somewhere to write and the org has none, or the user asks for a NEW one. Check ``g8_workflow_list_workbenches`` first so you reuse an existing workbench instead of making a near-duplicate. Args: name: Display name. Required. entity_type: ``contact`` or ``company``. Optional; a blank workbench may defer it. Use ``company`` when each row is a company or domain (e.g. per-domain verdicts), ``contact`` when each row is a person. description: Optional free text. on_duplicate: What to do when an active workbench already has this name (case-insensitive). ``allow`` (default): create anyway and add ``warnings``. ``reuse``: create nothing and return the existing workbench with ``reused: true`` (get-or-create). ``error``: refuse with a 409 naming the existing id(s). Prefer ``reuse`` when a workflow just needs "the" workbench of a name. Returns ``&#123;workbench_id, name, entity_type, description&#125;``. Feed ``workbench_id`` straight into the workbench node config. Duplicate names are allowed by default, but the response then also carries ``warnings`` naming the existing workbench(es) with that name.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `name` | Yes | string | See the schema below for constraints and defaults. |
| `entity_type` | No | string / null | See the schema below for constraints and defaults. |
| `description` | No | string / null | See the schema below for constraints and defaults. |
| `on_duplicate` | No | string / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "name": {
      "title": "Name",
      "type": "string"
    },
    "entity_type": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Entity Type"
    },
    "description": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Description"
    },
    "on_duplicate": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "On Duplicate"
    }
  },
  "required": [
    "name"
  ],
  "title": "create_workbenchArguments",
  "type": "object"
}
```

</details>

## g8_workflow_delete

> Delete a workflow permanently. One-way - ``g8_workflow_get`` 404s after. ALWAYS confirm with the user; call ``dry_run=True`` first to render the confirmation widget. Args: action_id: Workflow id. dry_run: When ``True``, return a confirmation preview without deleting.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `dry_run` | No | boolean | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "dry_run": {
      "default": false,
      "title": "Dry Run",
      "type": "boolean"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "delete_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_describe_form_fields

> Discover the field names submitted to a form by sampling recent submissions. REQUIRED before authoring a ``new_form_submitted`` trigger node, otherwise the field picker is empty. Call right after the user names a form_id, then pass the returned ``fields`` list as ``form_fields`` on the trigger node config: g8_workflow_add_node(node_type="trigger", config=&#123; "trigger_type": "new_form_submitted", "form_id": "contact-us-form", "form_fields": ["email", "name", "title", "message"], &#125;) Downstream nodes reference values via ``$&#123;&lt;trigger_node_id&gt;.&lt;field&gt;&#125;``. Returns ``&#123;form_id, fields: [str], sample_size: int&#125;``. An empty ``fields`` list means no submissions exist yet - ask the user instead. Args: form_id: HTML form id (form_tag_id) - same value used as ``form_id`` on the trigger node config.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `form_id` | Yes | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "form_id": {
      "title": "Form Id",
      "type": "string"
    }
  },
  "required": [
    "form_id"
  ],
  "title": "describe_form_fieldsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_describe_node_type

> Get the config schema for a single node type. Cheaper than ``g8_workflow_list_node_types(detail="full")`` when you already know the type - returns one entry, same payload shape. Args: node_type: A value from ``g8_workflow_list_node_types`` (e.g. ``"sequence_reply_trigger"``, ``"llm_completion"``). detail: ``"slim"`` or ``"full"`` (default ``"full"``).

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `node_type` | Yes | string | See the schema below for constraints and defaults. |
| `detail` | No | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "node_type": {
      "title": "Node Type",
      "type": "string"
    },
    "detail": {
      "default": "full",
      "title": "Detail",
      "type": "string"
    }
  },
  "required": [
    "node_type"
  ],
  "title": "describe_node_typeArguments",
  "type": "object"
}
```

</details>

## g8_workflow_execute

> Trigger a workflow run. Runs for real - can spend credits, send messages, or call external APIs depending on the nodes. ALWAYS confirm with the user; call ``dry_run=True`` first for a confirmation widget, then ``dry_run=False`` after the user confirms. Returns ``&#123;execution_id, status: "queued" \| "running"&#125;``. Poll with ``g8_workflow_get_execution`` until ``completed`` or ``failed``. A run started here does not fire the trigger: the trigger node gets ONLY ``input_data``. For an event trigger (e.g. ``campaign_visitor``) the values a real event carries (``company_name``, ``sequence_name``, ``contact_email``, ...) are absent unless you pass them, so every ``$&#123;trigger.*&#125;`` reference renders blank and a send node whose recipient is a trigger field has no one to send to. For a test run, pass the trigger's output fields (see ``g8_workflow_describe_node_type``) with the values to test, including the recipient. If the response has ``status: "unknown"``, the run MAY have started: check ``possible_executions`` / the executions list before doing anything else. NEVER re-run after an error without passing the SAME ``idempotency_key`` (the preview's confirm_args carry one): with it a retry returns the first run instead of starting a second one. Args: action_id: Workflow id. input_data: Optional ``&#123;key: value&#125;`` dict - becomes ``&#123;&#123;trigger.key&#125;&#125;`` references inside the graph. Defaults to ``&#123;&#125;``. Inputs the workflow's ``input_schema`` marks ``required`` must be present: a run missing any is refused with a 400 that lists them. triggered_by: Optional caller user_id (defaults to the API key's user server-side). dry_run: When ``True``, return a confirmation preview without firing the workflow. idempotency_key: Optional key for this ONE logical run. Reuse it when retrying the same run; a new run needs a new key. The dry-run preview mints one into its confirm_args.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `input_data` | No | object / null | See the schema below for constraints and defaults. |
| `triggered_by` | No | string / null | See the schema below for constraints and defaults. |
| `dry_run` | No | boolean | See the schema below for constraints and defaults. |
| `idempotency_key` | No | string / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "input_data": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Input Data"
    },
    "triggered_by": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Triggered By"
    },
    "dry_run": {
      "default": false,
      "title": "Dry Run",
      "type": "boolean"
    },
    "idempotency_key": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Idempotency Key"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "execute_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_get

> Get the full graph for a workflow (nodes + edges + trigger). Shape: ``&#123;action_id, name, description, runtime_type, enabled, config: &#123;metadata, settings, nodes: [...], edges: [...], start_node_id&#125;, managed_by&#125;``. Call before any granular edit to get current node/edge ids. Each node uses canonical snake_case (flat ``node_id`` / ``node_type`` / ``name`` / ``config`` / ``position``); the granular helpers also read legacy ReactFlow-shape rows. Args: action_id: Workflow id from ``g8_workflow_list`` or the URL ``app.graph8.com/agents/workflows/&#123;action_id&#125;``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "get_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_get_execution

> Get a workflow execution's status / output / token cost. Polling pattern: call every few seconds after ``g8_workflow_execute`` until ``status`` is ``completed`` or ``failed``. 404s for executions outside the caller's org. Args: execution_id: Execution UUID returned by ``g8_workflow_execute``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `execution_id` | Yes | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "execution_id": {
      "title": "Execution Id",
      "type": "string"
    }
  },
  "required": [
    "execution_id"
  ],
  "title": "get_executionArguments",
  "type": "object"
}
```

</details>

## g8_workflow_get_trigger_status

> Get the trigger status (cursor + config) for a workflow. Useful for debugging "why isn't my workflow firing?" - surfaces whether a trigger is configured, its type, and the last cursor timestamp processed. Args: action_id: Workflow id.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "get_trigger_statusArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list

> List workflows owned by the caller's organization. Returns ``runtime_type='workflow'`` actions only. A row with a non-null ``managed_by`` (``&#123;kind: "work_routine", routine_id&#125;``) is the backing workflow of an event-triggered Work routine: read it freely, but change it from Agents &gt; Routines, not here. Args: enabled: ``True`` for enabled only, ``False`` for disabled. Omit to return both. category: Optional free-form category filter (e.g. ``"sales"``). is_template: ``True`` returns templates other orgs can fork. Omit for non-templates.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `enabled` | No | boolean / null | See the schema below for constraints and defaults. |
| `category` | No | string / null | See the schema below for constraints and defaults. |
| `is_template` | No | boolean / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "enabled": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Enabled"
    },
    "category": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Category"
    },
    "is_template": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Is Template"
    }
  },
  "title": "list_workflowsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_dispositions

> List every valid call disposition - system values AND this organization's own custom dispositions. The ``value`` of each entry is EXACTLY what goes into ``disposition_filters`` on the **new_call_disposition** trigger. That is the ONLY trigger with a server-side disposition filter. ``new_call_ended`` carries a ``disposition`` output field for downstream nodes but does NOT filter on it, and ``new_voicemail_detected`` has no disposition field at all; setting ``disposition_filters`` on either saves cleanly and is then silently ignored, so the workflow fires on every call. Returns ``&#123;dispositions: [&#123;value, label, category, origin, ...&#125;], custom_count, source&#125;``: - ``origin`` is ``system`` (built-in vocabulary) or ``custom`` (defined by this org). Custom entries also carry ``description``, ``color`` and ``is_connected``. - A custom disposition's ``value`` is its stored ``custom_&#123;id&#125;`` key - NEVER its display name. Filtering on the name silently never matches. - ``category`` is ``sdr_selectable`` (a rep can pick it) or ``system_set`` (only the dialer backend writes it). - ``source`` is ``voice`` normally, or ``static_fallback`` if the custom-disposition lookup was unavailable. On ``static_fallback``, say you could not confirm this org's custom dispositions rather than claiming there are none. Matching is an EXACT, case-sensitive comparison against the stored key, and an empty filter fires for every disposition. Always resolve the user's wording through this tool instead of guessing a key.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_dispositionsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_inbox_tags

> List the org's AI Inbox tags, so a human description becomes a tag ID. REQUIRED before authoring a **new_inbox_tag_set** trigger: its ``tag_filters`` takes tag IDs, not tag names, and there is no other way to discover them. Resolve phrasing like "out of office", "interested", "referred me to a colleague", "unsubscribe request" to the matching tag's ``id`` here, then pass those ids: g8_workflow_add_node(node_type="trigger", config=&#123; "trigger_type": "new_inbox_tag_set", "tag_filters": ["&lt;id from this tool&gt;", "..."], "tag_source_filters": ["ai"], &#125;) ``tag_source_filters`` accepts ``"ai"`` (the inbox AI agent applied the tag, normally within seconds of the email arriving) and ``"manual"`` (a human applied it). Omit it to fire on both. Prefer this over a ``new_email_reply`` trigger plus a condition node that greps the body text. The inbox AI agent has already classified the reply; re-deriving intent from raw text is fragile and fires late. Args: ai_applicable_only: When ``True``, return only tags the AI agent is allowed to apply automatically (``ai_can_apply``). Those are the tags a ``new_inbox_tag_set`` trigger fires on with no human in the loop. Returns ``&#123;tags: [&#123;id, name, description, color, ai_can_apply&#125;], total&#125;``. An empty list means the org has no inbox tags configured yet - tell the user to create them in Inbox -&gt; Tags rather than inventing ids.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `ai_applicable_only` | No | boolean | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "ai_applicable_only": {
      "default": false,
      "title": "Ai Applicable Only",
      "type": "boolean"
    }
  },
  "title": "list_inbox_tagsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_linkedin_senders

> List the org's LinkedIn sender accounts (seats). Resolves the ``sender_account_id`` on ``send_netrion_connection_request`` and ``send_netrion_message``, and the ``linkedin_account_id`` carried by the ``linkedin_connection_accepted`` / ``linkedin_message_sent`` / ``linkedin_reply_received`` triggers. USE ``sender_account_id`` VERBATIM: it is the numeric PK as a string. Do NOT pass ``account_id`` (the ``lia_...`` form): the resolver cannot parse it, and these nodes run in strict mode, so naming it FAILS the send rather than falling back to another seat. Returns ``&#123;senders: [&#123;sender_account_id, account_id, display_name, public_identifier, status, account_tier&#125;], total_count&#125;``. Seats that are not ``status='OK'`` are included WITH their status, so a disconnected seat can be reported as such instead of looking like no seats at all. An empty list means LinkedIn is not connected for this org.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_linkedin_sendersArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_mcp_servers

> List MCP servers connected to the org with their available tools. Use to fill the ``tool`` node config: ``mcp_server_id`` from ``servers[].mcp_server_id`` and ``mcp_tool_name`` from the per-server tools list. Returns ``&#123;servers: [...], total&#125;``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_mcp_serversArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_node_types

> List every workflow node type with its config schema. Call this BEFORE building a workflow to learn the valid ``type`` strings and what each one's ``config`` must contain. Covers triggers, actions, and integrations. Action-vs-Agent node choice: for ANY one-shot natural-language step (summarize, generate, extract, classify, draft, parse) pick an Action node (``llm_completion``) bound to an LLM skill authored via ``g8_workflow_skill_create_llm``; wire its ``&#123;variable&#125;`` placeholders to upstream nodes via ``input_mappings`` and read its output as ``&#123;&#123;&lt;node_id&gt;.result&#125;&#125;``. Pick an ``agent`` node ONLY for autonomous multi-turn tool use across turns. The catalog also includes ``trigger_output_schemas`` (the input_data each trigger run provides, for ``&#123;&#123;trigger.field&#125;&#125;`` refs), ``resolver_tool_hints`` (MCP tools that resolve opaque id fields), and ``example_workflows`` (worked runnable graphs). Args: detail: ``"slim"`` (default) returns a compact ``[(field_name, type_str)]`` per node. ``"full"`` returns the Pydantic JSON schema for every config field - use when slim is not enough.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `detail` | No | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "detail": {
      "default": "slim",
      "title": "Detail",
      "type": "string"
    }
  },
  "title": "list_node_typesArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_roam_groups

> List Roam groups connected to the org. Resolves a group description into the ``address_id`` needed for ``send_roam_notification`` (mode=group, recipient_id=...). Returns ``&#123;groups: [&#123;address_id, name, group_type, access_mode&#125;]&#125;``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_roam_groupsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_roam_users

> List Roam users connected to the org. Resolves a user description into the user_ids needed for ``send_roam_notification`` (mode=dm, user_ids=[...]). Returns ``&#123;users: [&#123;id, name, email&#125;]&#125;``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_roam_usersArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_slack_channels

> List Slack channels in the connected workspace. Resolves a channel description into the Slack channel_id needed for ``send_slack_notification`` (mode=channel, channel_id=...). Returns ``&#123;channels: [&#123;id, name, is_private, num_members&#125;]&#125;``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_slack_channelsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_slack_users

> List Slack users in the connected workspace. Resolves a user description into the Slack user_id needed for ``send_slack_notification`` (mode=dm, user_id=...). Returns ``&#123;users: [&#123;id, name, real_name, is_bot, deleted&#125;]&#125;``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| None | No | — | No user-supplied inputs. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {},
  "title": "list_slack_usersArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_workbenches

> List the org's workbenches (staging tables). Resolves the ``workbench_id`` required by ``add_to_workbench``, ``workbench_lookup`` and ``workbench_pull_rows``. It is the same id the Workbench page URL shows, so you and the user are naming the same thing. Returns ``&#123;workbenches: [&#123;workbench_id, name, entity_type, description, row_count, created_at&#125;], total, page, limit&#125;``. An empty list means the org has none yet; create one with ``g8_workflow_create_workbench``. ``limit`` must be 1-100. ``filter_name`` is a case-insensitive literal substring: ``%`` and ``_`` match only themselves.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `limit` | No | integer | See the schema below for constraints and defaults. |
| `page` | No | integer | See the schema below for constraints and defaults. |
| `filter_name` | No | string / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "limit": {
      "default": 50,
      "title": "Limit",
      "type": "integer"
    },
    "page": {
      "default": 1,
      "title": "Page",
      "type": "integer"
    },
    "filter_name": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Filter Name"
    }
  },
  "title": "list_workbenchesArguments",
  "type": "object"
}
```

</details>

## g8_workflow_list_workflow_executions

> List workflow executions for the caller's org (recover a lost execution_id). Uses the current organization and existing API permissions. API: GET /workflows/executions

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | No | string / null | Filter to a single workflow's executions. |
| `status_filter` | No | string / null | Filter by execution status (equality match - one status per call). The backend writes seven values: pending\|running\|completed\|failed\|paused\|pending_approval\|stopped. The four terminal-or-early states are pending, running, completed, failed; paused and pending_approval are resumable, stopped is terminal. |
| `triggered_by` | No | string / null | Filter by the identity that started the run (user email, agent id, 'api', ...). |
| `created_after` | No | string / null | ISO-8601 datetime. Only return executions created at or after this instant (inclusive, `created_at &gt;= created_after`), for polling 'runs since my last read'. A value with no UTC offset is read as UTC. Omitted: no lower bound. |
| `limit` | No | integer / null | Page size (1..200). |
| `offset` | No | integer / null | Rows to skip for pagination. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Filter to a single workflow's executions.",
      "title": "Action Id"
    },
    "status_filter": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Filter by execution status (equality match - one status per call). The backend writes seven values: pending|running|completed|failed|paused|pending_approval|stopped. The four terminal-or-early states are pending, running, completed, failed; paused and pending_approval are resumable, stopped is terminal.",
      "title": "Status Filter"
    },
    "triggered_by": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Filter by the identity that started the run (user email, agent id, 'api', ...).",
      "title": "Triggered By"
    },
    "created_after": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "ISO-8601 datetime. Only return executions created at or after this instant (inclusive, `created_at >= created_after`), for polling 'runs since my last read'. A value with no UTC offset is read as UTC. Omitted: no lower bound.",
      "title": "Created After"
    },
    "limit": {
      "anyOf": [
        {
          "maximum": 200,
          "minimum": 1,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Page size (1..200).",
      "title": "Limit"
    },
    "offset": {
      "anyOf": [
        {
          "minimum": 0,
          "type": "integer"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Rows to skip for pagination.",
      "title": "Offset"
    }
  },
  "title": "g8_workflow_list_workflow_executionsArguments",
  "type": "object"
}
```

</details>

## g8_workflow_pause_execution

> Pause a running workflow execution. Reversible - call ``g8_workflow_resume_execution`` to flip back to ``running``. Idempotent: pausing an already-paused execution is a no-op. Args: execution_id: Execution UUID. reason: Optional short reason saved with the execution. message: Optional human-readable note.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `execution_id` | Yes | string | See the schema below for constraints and defaults. |
| `reason` | No | string / null | See the schema below for constraints and defaults. |
| `message` | No | string / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "execution_id": {
      "title": "Execution Id",
      "type": "string"
    },
    "reason": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Reason"
    },
    "message": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Message"
    }
  },
  "required": [
    "execution_id"
  ],
  "title": "pause_executionArguments",
  "type": "object"
}
```

</details>

## g8_workflow_plan_inline_workflow

> Preview a normalized execution plan for an inline workflow graph. Uses the current organization and existing API permissions. Review the intended change and set confirm=true to execute; otherwise no API request is sent. API: POST /workflows/plan

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `body` | Yes | object | See the schema below for constraints and defaults. |
| `confirm` | No | boolean | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "body": {
      "additionalProperties": true,
      "title": "Body",
      "type": "object"
    },
    "confirm": {
      "default": false,
      "title": "Confirm",
      "type": "boolean"
    }
  },
  "required": [
    "body"
  ],
  "title": "g8_workflow_plan_inline_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_plan_workflow

> Preview a normalized execution plan for a saved workflow. Uses the current organization and existing API permissions. Review the intended change and set confirm=true to execute; otherwise no API request is sent. API: POST /workflows/&#123;action_id&#125;/plan

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | Workflow action_id. |
| `body` | No | object / null | See the schema below for constraints and defaults. |
| `confirm` | No | boolean | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "description": "Workflow action_id.",
      "minLength": 1,
      "title": "Action Id",
      "type": "string"
    },
    "body": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Body"
    },
    "confirm": {
      "default": false,
      "title": "Confirm",
      "type": "boolean"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "g8_workflow_plan_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_remove_node

> Remove a node from a workflow's graph. Also drops any edge referencing the node and scrubs the id from other nodes' ``connections`` / ``conditional_connections`` and from the node ids they carry in config (a condition's ``true_node_id`` / ``false_node_id``, a loop's ``body_node_id``, an error ``fallback_node_id``) so no dangling reference remains - voice refuses to save a graph that still points at the removed node. If ``node_id`` is the workflow's ``start_node_id`` the graph becomes invalid and the PUT is rejected - pick a new start node via ``g8_workflow_update`` first. Args: action_id: Workflow id. node_id: Node to remove.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `node_id` | Yes | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "node_id": {
      "title": "Node Id",
      "type": "string"
    }
  },
  "required": [
    "action_id",
    "node_id"
  ],
  "title": "remove_nodeArguments",
  "type": "object"
}
```

</details>

## g8_workflow_reset_trigger_cursor

> Reset the workflow's trigger cursor to ``now()``. Use before re-enabling a workflow that was disabled for a while, so it does not replay the backlog - the cursor jumps forward and only events from now on fire it. Args: action_id: Workflow id.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "reset_trigger_cursorArguments",
  "type": "object"
}
```

</details>

## g8_workflow_resume_execution

> Resume a paused workflow execution. Idempotent. Args: execution_id: Execution UUID. from_step: Optional step id to resume from (defaults to the step where the pause happened). skip_failed: When ``True``, skip any previously-failed step instead of retrying.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `execution_id` | Yes | string | See the schema below for constraints and defaults. |
| `from_step` | No | string / null | See the schema below for constraints and defaults. |
| `skip_failed` | No | boolean / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "execution_id": {
      "title": "Execution Id",
      "type": "string"
    },
    "from_step": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "From Step"
    },
    "skip_failed": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Skip Failed"
    }
  },
  "required": [
    "execution_id"
  ],
  "title": "resume_executionArguments",
  "type": "object"
}
```

</details>

## g8_workflow_stop_execution

> Stop a workflow execution permanently. One-way - cannot be resumed after stop; use ``g8_workflow_pause_execution`` instead if the user might want to flip it back. ALWAYS confirm with the user; call ``dry_run=True`` first. Args: execution_id: Execution UUID. reason: Optional short reason saved with the execution. save_partial_results: When ``True``, persist per-step output produced before the stop. Default ``False``. message: Optional human-readable note. dry_run: When ``True``, return a confirmation preview.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `execution_id` | Yes | string | See the schema below for constraints and defaults. |
| `reason` | No | string / null | See the schema below for constraints and defaults. |
| `save_partial_results` | No | boolean / null | See the schema below for constraints and defaults. |
| `message` | No | string / null | See the schema below for constraints and defaults. |
| `dry_run` | No | boolean | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "execution_id": {
      "title": "Execution Id",
      "type": "string"
    },
    "reason": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Reason"
    },
    "save_partial_results": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Save Partial Results"
    },
    "message": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Message"
    },
    "dry_run": {
      "default": false,
      "title": "Dry Run",
      "type": "boolean"
    }
  },
  "required": [
    "execution_id"
  ],
  "title": "stop_executionArguments",
  "type": "object"
}
```

</details>

## g8_workflow_update

> Update a workflow's metadata or graph. Partial update - pass only the fields you want to change. For node/edge edits prefer the granular ``g8_workflow_add_node`` / ``update_node`` / ``remove_node`` / ``connect_nodes`` helpers, which fetch + mutate + put for you. A workflow whose ``managed_by.kind`` is ``work_routine`` accepts only ``enabled``; any other edit is refused with "This workflow is managed by a Work routine. Edit it in Agents › Routines." Relay that to the user instead of retrying. Args: action_id: Workflow id. name: New display name (omit to keep current). description: New description. category: New category. enabled: ``True`` to enable, ``False`` to pause. config: New full graph dict. Replaces the existing graph wholesale - for granular edits use the helpers above.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `name` | No | string / null | See the schema below for constraints and defaults. |
| `description` | No | string / null | See the schema below for constraints and defaults. |
| `category` | No | string / null | See the schema below for constraints and defaults. |
| `enabled` | No | boolean / null | See the schema below for constraints and defaults. |
| `config` | No | object / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "name": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Name"
    },
    "description": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Description"
    },
    "category": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Category"
    },
    "enabled": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Enabled"
    },
    "config": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Config"
    }
  },
  "required": [
    "action_id"
  ],
  "title": "update_workflowArguments",
  "type": "object"
}
```

</details>

## g8_workflow_update_node

> Update one node's config / label / position / connections in place. Pass only the fields you want to change. The node's ``type`` is NOT updatable here - switching types requires remove + re-add so the new config schema validates cleanly. ``connections`` and ``conditional_connections`` drive how the executor traverses: use ``connections`` for sequential nodes and ``conditional_connections`` (a dict ``&#123;path_id: target_node_id&#125;`` or ``&#123;"true": target, "false": target&#125;``) for branching ``condition`` / ``loop`` / ``human_approval`` nodes. Most callers let ``add_node`` / ``connect_nodes`` keep these in sync; touch them here only when rewiring a condition node by hand. Args: action_id: Workflow id. node_id: Existing node's id. config: New full per-node config dict (replaces, not merges). label: New display label. position: New ``&#123;"x":..., "y":...&#125;``. connections: New outgoing connections list (replaces). Empty list clears; omit to leave unchanged. conditional_connections: New conditional connections dict (replaces). Empty dict clears; omit to leave unchanged.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `action_id` | Yes | string | See the schema below for constraints and defaults. |
| `node_id` | Yes | string | See the schema below for constraints and defaults. |
| `config` | No | object / null | See the schema below for constraints and defaults. |
| `label` | No | string / null | See the schema below for constraints and defaults. |
| `position` | No | object / null | See the schema below for constraints and defaults. |
| `connections` | No | array / null | See the schema below for constraints and defaults. |
| `conditional_connections` | No | object / null | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "action_id": {
      "title": "Action Id",
      "type": "string"
    },
    "node_id": {
      "title": "Node Id",
      "type": "string"
    },
    "config": {
      "anyOf": [
        {
          "additionalProperties": true,
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Config"
    },
    "label": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Label"
    },
    "position": {
      "anyOf": [
        {
          "additionalProperties": {
            "type": "number"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Position"
    },
    "connections": {
      "anyOf": [
        {
          "items": {
            "type": "string"
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Connections"
    },
    "conditional_connections": {
      "anyOf": [
        {
          "additionalProperties": {
            "type": "string"
          },
          "type": "object"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "title": "Conditional Connections"
    }
  },
  "required": [
    "action_id",
    "node_id"
  ],
  "title": "update_nodeArguments",
  "type": "object"
}
```

</details>

## g8_workflow_validate

> Validate a workflow graph WITHOUT saving it. Returns ``&#123;errors: [...], warnings: [...], missing_references: [...]&#125;``. Call before ``g8_workflow_create`` or after a granular edit to confirm the graph is sound and every templated reference (``&#123;&#123;node1.output&#125;&#125;``) resolves. A workbench node whose ``workbench_id`` does not exist in the org is an error (``ref_type="workbench"`` in ``missing_references``). Args: config: The graph dict ``&#123;metadata?, settings?, nodes, edges, start_node_id, trigger?&#125;`` - same shape ``g8_workflow_get`` returns under ``response.config``.

### Inputs

| Input | Required | Type | Description |
|---|---|---|---|
| `config` | Yes | object | See the schema below for constraints and defaults. |

<details>
<summary>Complete input schema</summary>

```json
{
  "properties": {
    "config": {
      "additionalProperties": true,
      "title": "Config",
      "type": "object"
    }
  },
  "required": [
    "config"
  ],
  "title": "validate_workflowArguments",
  "type": "object"
}
```

</details>
