The model never sees your operation tree. It sees three things: the tool’s name, its description, and its json_schema. Everything about whether a tool gets called at the right moment, with the right values, is decided by those three fields. Treat them as prompt engineering, not as bookkeeping.

name

The function name the model is shown. It must match ^[a-zA-Z_][a-zA-Z0-9_]*$ — a save with anything else is rejected — and it must be unique in the workspace. Use snake_case and name the capability, not the implementation: book_appointment, not post_booking_v2. Three names are reserved by the platform, because the runtime injects tools under them: knowledge_fetch, stop_recording and submit_result. Creating a tool with one of those returns 400 '<name>' is reserved by the platform.

description

The description tells the model when to call the tool. This matters as much as the implementation: a correct tool that fires at the wrong moment is worse than no tool. Write the conditions, including the ones that should stop it firing. Weak:
The model has no idea whether to call it when the caller says “what have you got on Tuesday?”, whether to call it again when they change their mind, or what happens if they have not named a time. It will guess, differently, on every call. Strong:
If a tool has a cost the caller can feel — a booking, a charge, an email that reaches a real person — say so in the description, and say what has to be true before it fires. A tool with an empty description is shown to the model with nothing but its name. The dashboard flags it in the tool list as “No description — the model has only the name to go on.”

json_schema

The arguments the model fills in. Two rules do most of the work. Declare only values the agent can know or ask the caller for. An internal account UUID is not one of them: the model will invent a plausible-looking one. Take the order number the caller can read out, and look the UUID up inside the tree. Give every property a description. It is the only instruction the model gets on what to put in that field and how to get it out of the conversation. A bare {"type": "string"} is how a tool ends up called with “next Tuesday” where it needed 2026-09-01. Then: mark as required only what the tool genuinely cannot run without — everything marked required is something the model will invent a value for rather than leave out — and use enum wherever the set of values is closed, so gold, Gold and gold tier cannot all reach your API.
Updating the schema on an existing tool is a patch. Omitted fields are left alone; json_schema is replaced wholesale:

Which JSON Schema is accepted

The schema is checked against JSON Schema Draft 2020-12, and the whole vocabulary of that draft is accepted — enum, required, minimum, maxLength, pattern, format, items, nested properties, $defs, anyOf. Nothing is stripped on the way in. Three rules on top of the draft: One convenience: a schema with no top-level type is read as an object, so {"properties": { … }, "required": [ … ]} is accepted and means the same thing as writing "type": "object" yourself. An empty {} means the tool takes no arguments. Two things about how the schema is used:
  • {{args.NAME}} is checked against the top-level properties keys only. A nested value is read with dots at runtime — {{args.address.city}} — and validation checks address is declared, not city.
  • The model’s arguments are validated against the same schema before the tree runs. A call that violates it never reaches your endpoints; the tool fails with Tool arguments are invalid at <path>: <message> and the model is handed that sentence.
The dashboard’s Arguments table models a flat object of string, number, integer, boolean and enum properties, each with a description and a required flag — and saving from the dashboard rewrites json_schema from that table. A richer schema written through the API survives being read, but the next dashboard save drops whatever the table cannot represent: items on an array, nested properties, minimum, pattern, format, default. Keep tools with hand-written schemas on the API, or keep the schema inside the table’s reach.

Common mistakes

Next

The operation tree

What runs once the model has called the tool.

Templating and data

Reading {{args.…}} and moving values between operations.