Python Custom Tools
Python custom tools let you write full Python code that runs inside a Docker sandbox. Unlike HTTP custom tools that call external APIs, Python tools can perform complex logic, data transformations, calculations, and multi-step operations — all within an isolated container.
Creating a Python Tool
Navigate to Tools in the sidebar and click New Custom Tool. The creation wizard offers three paths:
- HTTP Request — Create a tool that calls an external API via HTTP (existing flow).
- Tool Builder — Describe what you need and a specialised assistant writes the code for you.
- Write Python — Start from a template and write the tool code yourself in a code editor.
Write Python
Click Write Python to open the code editor. The form has these sections:
Basic Info
- Display Name — A human-friendly name shown in the UI.
- Tool Name Suffix — The tool identifier in
snake_case. Automatically prefixed withcustom_(e.g.fetch_pricebecomescustom_fetch_price). - Description — Describe what the tool does. This is shown to the AI assistant.
- Category — Optional grouping for the tools list.
Source Code
Write a Python class that inherits from BaseTool. The editor includes syntax highlighting and starts with a working template:
from typing import Any
from base import BaseTool, SandboxToolContext
class MyTool(BaseTool):
"""Description of what this tool does."""
name = "custom_example"
description = "What this tool does, explained to the AI assistant."
category = "Custom"
input_schema: dict[str, Any] = {
"type": "object",
"properties": {
"param1": {
"type": "string",
"description": "Description of param1.",
},
},
"required": ["param1"],
}
def execute(self, params: dict[str, Any], ctx: SandboxToolContext) -> str:
"""Execute the tool.
Args:
params: Tool input parameters matching input_schema.
ctx: Sandbox execution context.
Returns:
Result string.
"""
return f"Result: {params['param1']}"base, not app.plugins.base. The sandbox provides its own minimal base module with BaseTool and SandboxToolContext.Requirements
Your class must have:
| Attribute | Description |
|---|---|
name | String starting with custom_ in snake_case |
description | String describing the tool for the AI assistant |
input_schema | JSON Schema dict defining the input parameters |
execute() | Method that takes params and ctx, returns a string |
The source code is validated before saving. The validator checks syntax, class structure, and rejects obviously dangerous patterns (like subprocess calls). The Docker sandbox is the real security boundary — validation provides defense-in-depth and better error messages.
Settings
- Allow Network Access — Enable this if the tool needs to call external APIs. Disabled by default.
- Timeout — Maximum execution time (1–120 seconds, default 30).
- Active — Toggle the tool on or off.
Tool Builder
The Tool Builder is a specialised assistant that writes Python tools for you. Click Tool Builder in the creation wizard to open a dedicated split-pane interface for AI-assisted tool creation. No setup is required; the Tool Builder assistant is created automatically on first use.
The Tool Builder Interface
The Tool Builder has two panes:
- Left pane — A multi-turn chat with the Tool Builder. Describe the tool you need, ask for changes, and iterate until you’re happy.
- Right pane — A code editor (with syntax highlighting) that shows the latest AI-generated code, plus an Info tab with extracted metadata like the tool name, description, and input schema.
Workflow
Click Tool Builder in the creation wizard (or navigate to Tools → Tool Builder).
Describe the tool you need. For example:
“Create a tool called
fetch_stock_pricethat takes atickerparameter and returns the current stock price using the Alpha Vantage API. It needs network access.”The Tool Builder writes the Python code, tests it in the sandbox, and displays it in the editor pane.
You can edit the code directly in the editor. When you send another message, the Tool Builder sees your changes and responds accordingly.
Continue the conversation to iterate — ask for new parameters, better error handling, or different behaviour.
When the code passes testing, the Tool Builder saves it automatically. The session is marked Complete and a link to the saved tool appears in the status bar.
The new tool appears immediately in the tools list and can be enabled for any assistant.
Sessions
Each Tool Builder conversation is tracked as a session. Navigate to Tools → Tool Builder to see your recent sessions and resume any previous conversation. Sessions show their current status:
- In Progress — The conversation is ongoing.
- Complete — The tool has been saved successfully.
SandboxToolContext
The ctx parameter passed to execute() provides context about the current execution:
| Field | Type | Description |
|---|---|---|
project | dict or None | {"id": ..., "name": ...} |
conversation_id | int or None | Current conversation ID |
assistant | dict or None | {"id": ..., "name": ...} |
user | dict or None | {"id": ..., "email": ...} |
plugin_config | dict | Always {} for custom tools |
app_config | dict | Always {} for custom tools |
Available Packages
The sandbox image includes these pre-installed packages:
requests, beautifulsoup4, lxml, pandas, numpy, openpyxl, Pillow, pyyaml, python-dateutil, chardet, html2text, markdown, jinja2, pydantic, httpx, feedparser
Plus the full Python standard library.
Testing
From the Python tool’s detail page, use the Test panel to run the tool in the sandbox. Enter parameters as JSON and click Run Test to see the result. Test results (output and timestamp) are saved for reference.
Sandbox Execution
Python custom tools always run in a Docker sandbox. This provides:
- Isolation — Tools cannot access the host file system, database, or other containers.
- Network control — Network access is disabled by default and enabled per-tool.
- Timeouts — Each execution has a configurable time limit.
- No persistent state — Each execution starts fresh.
For more about sandbox configuration, see the Sandbox documentation.