Skip to content

Combine several steps — sometimes across different products — into a single tool your agents can call.

Where to find it: Toolboxes → Synthetic tools

Example: look a customer up in the CRM, then open a support ticket for them. One decisive tool usually beats three chained calls the agent has to orchestrate itself.

Synthetic tools are gated by your plan’s synthetic tools feature (included on Gold and Black). Without it, the empty state explains they aren’t in your plan.

Before you start

  • A plan that includes synthetic tools
  • toolbox:create (or equivalent access to build tools)
  • At least one working connection to test against

Design a synthetic tool

  1. Open Toolboxes → Synthetic tools → New synthetic tool.
  2. Name it and describe when an agent should reach for it (this becomes the advertised tool description).
  3. Define the tool’s input schema (what the agent must provide).
  4. Add step for each call. For every step set:
Field Purpose
Step key Stable id other steps and templates refer to
Connection Which account runs this step
Tool Which tool on that connection to call
Depends on Earlier steps that must finish first
Repeat for each (optional) Run this step once per item of a list
Advanced (optional) Parallel items, what to do if a call fails, and pages to read — see below
Arguments template (JSONata) Build arguments from { input, steps, run }
Output template (JSONata) (optional) Shape what later steps see

Independent steps (no dependency between them) run in parallel. Dependent steps wait. Cycles and unknown references are rejected when you save.

Step results are available as steps.<key> for later templates.

  1. Save changes.

Repeat a step for each item

Without Repeat for each, a step calls its tool once. Turn it on and give it a JSONata expression producing a list, and the step calls its tool once per item instead — the agent gets one tool, not one call per item to chain by hand.

Worked example: update every open card and leave a comment, in three steps instead of 3×N calls:

  1. find_cards — no Repeat for each. Finds the open cards.
  2. update_card — Repeat for each set to steps.find_cards.result. Its arguments template can now read item (the current card) and index (0-based), for example { "card_id": item.id, "status": "in_progress" }.
  3. comment_card — Repeat for each set to steps.find_cards.result, arguments { "card_id": item.id, "text": "Picked up" }.

A for_each step's result becomes a list, in item order — steps.update_card.result is every updated card's result, not one. A single item failing fails the step, named as "item 3: …" so you know which one. Repeating stops at 100 items — split the input or narrow the list first if it can run larger than that.

Advanced step settings

Each step has an Advanced disclosure (collapsed unless you've already set something in it) with three controls:

  • Parallel items — only shown when Repeat for each is on. How many items run at once (1–4, default 4). Lower it if the connection's tool rate-limits — running fewer items concurrently trades speed for staying under the vendor's limit.
  • If a call fails — Stop the run (default) or Keep going. Keeping going leaves an empty slot for the failed item (or the failed step, on a step that doesn't repeat) and lists the errors instead of stopping everything for one bad record.
  • Pages to read — for a list tool, how many pages to follow via the tool's own next_cursor (1–10, default 1; list tools only — any other tool is rejected on save) before the step's result is considered complete. A step that repeats over a list reports which items still had more pages (truncated). A single step that stops with pages left reports it as "1 cut short" and keeps the tool's next_cursor. When you use Keep going or read several pages, include the step's errors, truncated and next_cursor in the output template — an assistant that runs the tool over MCP sees only the output, so anything the template leaves out stays hidden. With no output template the raw steps are returned, and they carry all three.

Only what changed

Every synthetic tool tracks run.last_success_at — the timestamp of the caller's last successful real run — and makes it available to every step's arguments template. A template that reads it can ask for just the new or changed records instead of the whole set every time, for example:

run.last_success_at ? { "updated_since": run.last_success_at } : {}

run.last_success_at is empty on the very first run, so the template leaves the filter out then and reads everything.

A test run never moves this timestamp — only a real run (through a toolbox, or the MCP tool itself with test left off) does, so you can test freely without losing your place. A real run also leaves the timestamp where it was when it did not finish the job: a step failed items under Keep going, or a step stopped with pages left unread. The next run then reads a little more, never less.

Test run

After save, use the Test run panel:

  1. Provide sample inputs matching your schema.
  2. Choose Run against live connections.
  3. Confirm Test succeeded, or fix the step where Test stopped.

Test execute runs the synthetic tool without needing it in a toolbox first. Results depend on real account data — use a safe connection when experimenting. A Repeat for each step shows how many times it ran (for example "Ran 12 times") next to its duration, plus how many failed if you set If a call fails to Keep going. If the run retried any calls, the result badge says how many times.

The test run always uses the output template as currently written in the editor, even if you haven't saved yet — change the template, hit Run again, and see the new shape before committing to it.

Add to a toolbox

  1. Open a template or a toolbox → Add tools.
  2. Choose the Synthetic tools tab and pick your tool.
  3. Tune the name and description. Defaults and schema overrides are rejected here — the synthetic tool defines its own schema — and frozen params do nothing on a synthetic entry, because each step supplies its own arguments.

It advertises its own input schema over MCP and executes its steps server-side through the same restriction and audit pipeline as normal tools.

Good to know

  • Each step runs with the access of the connection behind it.
  • If a dependent step fails, the run stops there; independent parallel steps still follow the DAG.
  • Restriction-blocked tools can’t be used as steps for callers who can’t reach them.
  • Agents see one tool — they don’t manage the intermediate steps.