# Call a tool

Call one or more declared tools directly, with the input you map. Several tools in one step run in parallel, and the step continues once every call has an answer.

Tool step, Call a tool:

- Step kind: `ExecuteTool`
- Operations: `IssueRefund`
- Input: `Invoice, Amount`
- Attempts: `2`

## Inputs

- `Operations` (string[], required): The declared tools to call. Several run in parallel.
- `Input` (mapping): What the tools are called with, keyed by the tool’s own field names. Where absent, the previous step’s value is the input. Input: {} calls with nothing.
- `Attempts` (integer, default `1`): How many attempts the step may take. A retry calls again only the tools that failed, and keeps the answers that succeeded.
- `OnExhausted` (policy): What happens when the attempts run out. Values: `Return: <value>`, `Wait`.

## Outputs

- `<payload>` (any): With one tool, the tool’s result. With several, an object keyed by operation name: { Field: Pull.Crm } reads one of them.

## Example

```yaml
Operations:
  - Tool: IssueRefund
    Locator: mcp://4b1e9a52-0f3c-4d2a-9e61-2a7f5c3d8b10/issue_refund

Steps:
  - ExecuteTool: Pay
    Operations: [IssueRefund]
    Input:
      invoice: { Field: Read.Invoice }
      amount: { Field: Read.Amount }
    Attempts: 2
    OnExhausted: Wait
```

The input is checked against the tool’s schema before the call. If every attempt fails, `OnExhausted: Wait` asks the run’s owner whether to try once more; `OnExhausted: { Return: <value> }` continues with the value you give instead. Without a policy the step fails.

## Tools the model chooses

To let the model pick the calls, follow a `ModelCall` whose `Output` is `ToolCall` with `ExecuteModelToolCall`, then `DeliverResults` so the model sees what came back. `ExecuteModelToolCall` runs only calls its own `Operations` allow. A call outside them, or one with arguments the tool refuses, is not run; the failure is returned to the model as that call’s result.

```yaml
- ModelCall: Plan
  Instructions: Look up what the customer is asking about.
  Operations: [Orders, Tickets]
  Output: ToolCall
- ExecuteModelToolCall: Look
  Operations: [Orders, Tickets]
- DeliverResults: HandOver
```

> **Where tools come from**
> A tool is declared once in `Operations` with a locator: `embedded://momor.ai/services/tools/…` for Momor’s own tools, or `mcp://<connection-id>/<tool>` for a [tool server](/docs/workflows/tool-servers/). An upload whose locator matches no registered tool is refused.

## Related steps

- [For each](/docs/workflows/steps/for-each/): Call a tool once per item of a list.
- [Ask the model](/docs/workflows/steps/ask-the-model/): Let the model choose the calls.
- [Run a workflow](/docs/workflows/steps/run-a-workflow/): Call a whole workflow instead of one tool.
