Creating custom tools
Create a custom Tool to run JavaScript, TypeScript, or Python without calling an external API. Use it for validation, data transformation, or business logic. The Tool receives your defined parameters and returns a result to the Agent.
Create a custom Tool
Create and configure a custom Tool with these steps:
- In the sidebar, click Tools.
- Click Create Tool.
- Enter the Tool name and description.
- Select Custom Code.
- Click Create Tool.
After the tool editor opens, configure the code and parameter schema with these steps:
- In Configuration, choose an Execution Environment.
- If you choose Daytona Sandbox, choose a Language.
- Enter the implementation in the language-specific code editor.
- Open Parameters and click Add Parameter.
- Configure each parameter, then click Save.
Pick an execution environment
Choose an execution environment that supports the language and network behavior that your code needs.
Use Cloudflare Worker (Default) for JavaScript that uses async/await, standard built-ins, or the helpers namespace. Runtype captures console.log output in execution logs.
Use Daytona Sandbox for TypeScript or Python. Runtype injects each valid parameter name as a variable in your code. To configure Daytona, open Settings and select Integrations. Under Code Execution, enter the Daytona API key and click Save Key. Runtype can use a platform key when you do not add your own key. Without a Daytona key, the Tool returns an execution error.
Use QuickJS (Legacy) to maintain existing JavaScript tools. QuickJS runs JavaScript synchronously and exposes the helper functions as global functions instead of the helpers namespace.
Custom code cannot use managed secrets through {{secret:NAME}}. In this syntax, NAME is the managed secret name. Use an external Tool when you need managed credentials or an HTTP request.
Write Tool code
The runtime provides input in different ways. Cloudflare Worker and QuickJS code reads the parameters object. Daytona Sandbox injects each valid parameter as a variable. Use this example with Cloudflare Worker or QuickJS:
Use this Python example with Daytona. Define a parameter named numbers with type array before you run the example:
Print one JSON value from Python so Runtype can parse the result. Use the language runtime and packages that Daytona Sandbox provides. Outbound network access follows its sandbox policy.
Runtime behavior
The runtime handles return values and errors as follows:
- Return a value from JavaScript code in Cloudflare Worker or QuickJS. The Tool passes the returned value to the Agent.
- Print a JSON value from Python or TypeScript in Daytona Sandbox. Runtype parses the output as JSON when possible.
- Handle expected failures with a structured error object. An unhandled exception fails the Tool and returns an error to the Agent.
- Use
console.login Cloudflare Worker or QuickJS code when you need output in execution logs.
Available JavaScript features
Cloudflare Worker provides these JavaScript features:
- Standard built-ins such as
Array,Object,Math,Date, andJSON. async/await, arrow functions, destructuring, and template literals.- Regular expressions and string manipulation.
- The
helpersnamespace. - Captured
console.logoutput in execution logs.
QuickJS provides the following JavaScript features:
- Standard built-ins such as
Array,Object,Math,Date, andJSON. - Regular expressions and string manipulation.
- Helper functions such as
parseHTML()andextractEmails()as global functions. - Synchronous JavaScript execution.
Daytona Sandbox provides the language runtime and container capabilities in its configuration. Use the selected language’s standard library and available packages.
Cloudflare Worker helper functions
Cloudflare Worker exposes the following functions in the helpers namespace:
In QuickJS, call these helper functions without the helpers. prefix.
Define parameters
Open Parameters, then click Add Parameter to define the input schema. Configure each field as follows:
Use this parameter schema with the discount example:
Set execution limits
Set Timeout (ms) between 1,000 and 300,000. The default is 30,000 milliseconds. Cloudflare Worker and QuickJS use this value. Daytona Sandbox uses its sandbox execution limit.
The Memory Limit control offers 8 MB, 16 MB, and 32 MB options. The effective memory limit depends on the selected execution environment.
Validate Tool code
Runtype validates custom code before it saves a Tool. JavaScript and TypeScript use syntax and semantic checks. Python uses syntax checks.
Validation errors block a save. The following checks produce errors:
eval()with the error codeUSE_OF_EVAL.new Function()with the error codeUSE_OF_FUNCTION_CTOR.- Syntax errors.
Validation warnings appear in the dashboard but do not block a save. The following checks produce warnings:
- An unbounded
while (true)loop without abreakorawait, with the warning codeINFINITE_LOOP. - A dynamic
import()expression, with the warning codeDYNAMIC_IMPORT. - A missing
returnstatement in JavaScript or TypeScript for Cloudflare Worker and QuickJS, with the warning codeRETURN_UNDEFINED.
Runtype runs the validation again whenever you update the Tool.
Handle errors
Return a structured error object when the Agent can recover from an expected input error. Use this JavaScript example:
Test a Tool
Run a test from the tool editor with these steps:
- Open Test Tool.
- Enter sample values in the Params tab.
- Click Run Test.
- Review the status, result, error, and execution time in the Result tab.
- Open the History tab to review previous tests.
Apply best practices
Use these practices when you create a custom Tool:
- Give each Tool one responsibility.
- Validate parameter values before processing them.
- Name each Tool after its operation, such as
calculate_shipping_cost. - Return structured objects so the Agent can use individual fields.
- Return
{ success: false, error: "..." }for expected errors instead of throwing. - Keep one operation in each Tool so you can isolate failures.
- Describe the Tool purpose, usage condition, output, limitations, and side effects.
Examples
Email validator
Use this JavaScript example to validate an email address:
Define one required email parameter with type string.
Date formatter
Use this JavaScript example to format an ISO date or return the default ISO representation:
Define isoDate as a required string parameter and format as a string parameter with the default value iso.
Array aggregator
Use this Python example with Daytona to aggregate an array of numbers:
Define one required numbers parameter with type array and numeric items.
Next steps
Use these links to continue:
- Creating external tools: call an HTTP API from an Agent.
- Agent tools: attach and configure Tools.
- Built-in tools: add ready-to-use integrations.
- What are Tools?: compare Tool types.
- Integrations (PostHog, Weaviate, Daytona): configure a Daytona API key.