Designing tools for agents
An Agent chooses and calls a Tool using only three things: the Tool name, the description, and the parameter schema. A Tool that returns correct data still fails in production when the model can’t tell when to call it, what to pass, or what to do with the result. This page shows how to pick a Tool type, write the interface, shape results and errors, set timeouts, and test the Tool the way an Agent uses it.
Pick a tool type
Choose the type by where the work runs and how long it takes. On the Tools page, click Create Tool and select one of the following types in the Type list:
Custom code has no network access unless the Tool sets networkAccess, so use an External API Tool or a Flow Tool for HTTP calls, or turn on network access for the one host the code calls. For the setup of each type, see What are Tools?.
Saved subagent tools
A saved Subagent Tool runs one of your saved Agents as a child. The parent receives only the child’s final result. To configure one, open the Tool and set the following fields in Tool Configuration:
- Agent: the saved Agent that runs when the Tool is called.
- Allowed Tools: the Tools, from the child Agent’s own Tools, that the child can use. When you select an Agent, this list starts empty, and an empty list runs the child without Tools.
- Output Format: Text returns the final assistant message, JSON returns the parsed JSON payload, and Last message returns the raw last assistant message.
- Max Turns: the child’s turn limit. Leave it blank to keep the child Agent’s own limit.
- Timeout (ms): the time limit for the child. The default is 300,000 milliseconds.
- Task Template (Optional): a message template, such as
Research {{topic}} and return a summary.Leave it empty to pass thetaskparameter through unchanged. - Inherit parent messages: turn this on to give the child the parent’s current conversation. It’s off by default, so write the
taskparameter as a self-contained instruction.
To run the child in the background instead, set config.execution.mode to detached with the API. For the detached fields, see Run a subagent in the background.
GraphQL APIs
The API accepts graphql as a toolType, and the Tools page labels such a Tool GraphQL. Runtype has no runner for this type, so every call to a graphql Tool fails with an unsupported tool type error.
To call a GraphQL API, create an External API Tool with the POST method and send the query in the body template. The following definition looks up an order by ID:
In this definition, SHOP_API_KEY is the name of a managed secret in your account. Leave {{order_id}} unquoted, because Runtype encodes each value as JSON before it inserts it. To create the Tool, run the following command:
Write the name and description
Name each Tool as a verb and an object in lowercase snake_case, such as lookup_order or create_ticket. Before the model sees a name, Runtype lowercases it and replaces every character other than letters, digits, and underscores with _. A camelCase name such as sendEmail reaches the model as sendemail.
Write the description as instructions to the model. The description can be at most 500 characters on create, so include these parts in this order:
- What the Tool does.
- When to use it, and when to use a different Tool instead.
- What the Agent must call or know first.
- What the Tool returns.
The following description covers all four parts:
State side effects in the first sentence of a Tool that changes data, for example “Permanently deletes the ticket.” Keep each Tool to one responsibility. Two Tools with overlapping descriptions make selection less reliable.
Design the parameters
The parameter schema is part of the prompt. Apply these rules to each parameter:
- Use an
enumfor any string that has a fixed set of valid values, and list the values in the description too. - Keep required parameters to the minimum. Every required parameter is a value that the model must produce correctly.
- Accept the identifier that a person has, such as an email address, rather than only an internal ID.
- Use type
objectorarrayfor structured input, not astringthat holds JSON. Models often drop the escape characters in a JSON string. - Handle a missing optional value in the Tool. Runtype doesn’t fill in a parameter’s default value when the Agent omits it.
Never ask the model for a credential. Put credentials in managed secrets and reference them as {{secret:NAME}} in the Tool configuration.
When you create or update a Tool with the API, read validation.warnings and validation.recommendations in the response. The save succeeds even when they are present. For example, a string parameter that looks like a JSON payload returns a TOOL_PARAM_EMBEDDED_JSON_STRING recommendation.
Shape the result
Every Tool result becomes part of the model’s next input, so return only the fields that the Agent needs for its next step. Use the same field names in every Tool, such as createdAt everywhere rather than created in one Tool and ts in another.
An External API Tool returns the API response unchanged. To trim or rename fields, wrap the request in a Flow, use a transform step to shape the response, and expose the Flow as a Flow Tool. In the Flow Tool configuration, set Output variable (optional) to the name of the variable that holds the shaped result. Otherwise, the Tool returns the output of the Flow’s last step.
For a list, return a count and a flag such as hasMore, so that the Agent can tell a complete list from a partial one.
Write errors that the Agent can act on
When a Tool fails, the Agent receives the error message and a failure class, such as timeout or invalid_args, and can retry, correct its arguments, or choose another Tool. Write each error message so that it states what went wrong and what to do next.
The following custom Tool code returns an error that names the valid values:
For the full list of failure classes, see Error handling.
Set timeouts
Each Tool type has its own time limit. When a call reaches the limit, the call fails and the Agent receives a timeout error. The following table lists the limits for saved Tools:
A custom Tool that you create with the API and without a timeout gets a fallback that depends on its execution environment. For the fallbacks, see Set execution limits. For MCP servers, see Limits.
A Tool call also runs inside the time limits of the step or Agent turn that makes the call. If the work takes minutes, don’t raise the Tool timeout. Run it as a detached subagent or as a separate Flow run instead. For these patterns, see Timeouts and long-running work.
Guard Tools that change data
Put rules that protect data in the Tool configuration and the Agent configuration, not in the system prompt. Use these controls:
- Require approval for a Tool that deletes data, sends messages, or spends money. The run pauses until a person approves or denies the call. For setup, see Require approval for tool calls.
- Keep credentials in managed secrets. Runtype resolves
{{secret:NAME}}references when the Tool runs and doesn’t return the secret value to the Agent. - For runtime Tools, hide parameters that come from context, such as a tenant ID, so the model can’t supply them. For instructions, see Hide parameters from the model.
Test the Tool as an Agent uses it
To confirm that an Agent selects and calls the Tool correctly, follow these steps:
- Open the Tool, enter sample values in the Test Tool panel, and click Run Test. Include the inputs that a model plausibly sends, such as a name where the Tool expects an ID. Read each error as though you knew only the description.
- Attach the Tool to an Agent and run a realistic prompt.
- Open the run in Logs and check which Tools the Agent called, the parameters, and the results.
- If the Agent picks the wrong Tool or sends the wrong parameters, change the description or the schema first, then run the prompt again.
- Optional: Add the run to an eval suite, so that each later description or schema change is checked against it. For more information, see What are Evals?.
To test from the command line, run runtype tools execute <tool-id> --input '{"order_id": "ord_1042"}'. Replace <tool-id> with the ID of the Tool.
Next steps
- Agent tools: attach Tools and set tool call limits and strategy.
- Creating custom tools: write code that an Agent can run.
- Creating external tools: configure HTTP requests and body templates.
- Runtime tools: define Tools, including subagents, inline in a request.
- Manage tools as code: keep Tool definitions in your repository.