Tools & Function Tools
The built-in tool catalog, the function_tool decorator for wrapping Python functions, and custom tool nodes.
Tools are workflow nodes the agent can call during its reasoning loop. Pass any tool node in the agent's tools list — the agent reads each tool's name, description, and input schema to decide when and how to call it. This page tours the built-in tools in dynamiq.nodes.tools, then shows the two ways to build your own: the function_tool decorator and a custom Node subclass.
Built-in tools
All classes below are importable from dynamiq.nodes.tools unless noted otherwise.
Web search
| Tool | Service |
|---|---|
ExaTool | Exa neural search |
TavilyTool | Tavily |
ScaleSerpTool | Scale SERP (Google results) |
FirecrawlSearchTool | Firecrawl search |
JinaSearchTool | Jina search |
Web scraping
| Tool | Service |
|---|---|
FirecrawlTool | Firecrawl scrape/crawl |
JinaScrapeTool | Jina reader |
ZenRowsTool | ZenRows |
Code execution
| Tool | Where code runs |
|---|---|
E2BInterpreterTool | E2B cloud sandbox (Python + shell) |
DaytonaInterpreterTool | Daytona sandbox |
Python | Predefined Python code you author, executed as a node |
PythonCodeExecutor | Executes code the agent supplies at run time |
PythonMonty | Restricted local Python interpreter |
Browser and desktop automation
| Tool | What it drives |
|---|---|
Stagehand | Headless browser sessions |
E2BDesktopTool | E2B desktop VM |
CuaDesktopTool | Computer-use desktop automation |
Files and data
| Tool | Purpose |
|---|---|
FileReadTool, FileWriteTool, FileListTool | Read, write, and list files in the agent's file store |
SQLExecutor | Run SQL against a configured database connection |
CypherExecutor | Run Cypher against Neo4j |
HttpApiCall | Call arbitrary HTTP APIs |
Pipedream | Invoke Pipedream-connected apps |
MCPServer / MCPTool | Expose tools from an MCP server to the agent |
RAG
| Tool | Purpose |
|---|---|
VectorStoreRetriever (dynamiq.nodes.retrievers) | Semantic search over a vector store: embeds the query, retrieves, optionally re-ranks |
VectorStoreWriter (dynamiq.nodes.writers) | Lets the agent embed and upsert documents into a vector store |
See Retrievers & Rankers for configuration.
Agent utilities
| Tool | Purpose |
|---|---|
HumanFeedbackTool | Pause and ask a human for input |
ThinkingTool | A scratchpad action for extended reasoning |
TodoWriteTool | Maintain a todo list across loop iterations |
SummarizerTool | LLM summarization of long content |
SkillsTool | Load and execute reusable skills |
ParallelToolCallsTool | Batch several tool calls into one step |
SubAgentTool | Wraps a child agent so a parent can call it as a tool |
Any Agent instance can also be passed directly in another agent's tools list — the SDK wraps it as a sub-agent automatically. See Orchestrators for multi-agent patterns.
Wrapping a function with function_tool
The fastest path from a Python function to a tool. The decorator builds a FunctionTool subclass whose input schema is generated from the function signature, and whose description comes from the docstring:
from dynamiq.connections import OpenAI as OpenAIConnection
from dynamiq.nodes.agents import Agent
from dynamiq.nodes.llms import OpenAI
from dynamiq.nodes.tools.function_tool import function_tool
@function_tool
def multiply_numbers(a: int, b: int, **kwargs) -> int:
"""Multiply two numbers together."""
return a * b
llm = OpenAI(connection=OpenAIConnection(), model="gpt-4o")
agent = Agent(
name="math-agent",
llm=llm,
tools=[multiply_numbers()], # call the decorated function to instantiate the tool
max_loops=4,
)
result = agent.run(input_data={"input": "What is 6 times 7?"})
print(result.output["content"])Notes on the generated tool:
- Type hints become the validated input schema (
a: int,b: intabove). Parameters namedkwargsorconfigare excluded from the schema. - The tool's
namedefaults to the function name and itsdescriptionto the docstring plus the function signature — write docstrings the LLM can act on. - The function's return value is wrapped as
{"content": result}.
You can also subclass FunctionTool directly when you want explicit naming and a hand-written schema:
from pydantic import BaseModel
from dynamiq.nodes.tools.function_tool import FunctionTool
class AddNumbersInputSchema(BaseModel):
a: int = -1
b: int = -1
class AddNumbersTool(FunctionTool):
name: str = "Add Numbers Tool"
description: str = "A tool that adds two numbers together."
def run_func(self, input_data: AddNumbersInputSchema, **kwargs) -> int:
"""Add two numbers together."""
return input_data.a + input_data.bCustom tool nodes
For tools that need connections, state, or full control over execution, subclass Node with group = NodeGroup.TOOLS and implement execute:
from typing import Any, Literal
import sympy as sp
from pydantic import ConfigDict
from dynamiq.nodes import NodeGroup
from dynamiq.nodes.node import Node, ensure_config
from dynamiq.runnables import RunnableConfig
class CalculatorTool(Node):
group: Literal[NodeGroup.TOOLS] = NodeGroup.TOOLS
name: str = "Calculator"
description: str = (
"Tool to evaluate mathematical expressions. "
"Provide a raw string of the math operation to parse and evaluate."
)
model_config = ConfigDict(arbitrary_types_allowed=True)
def execute(
self, input_data: dict[str, Any], config: RunnableConfig = None, **kwargs
) -> dict[str, Any]:
config = ensure_config(config)
self.run_on_node_execute_run(config.callbacks, **kwargs)
expression = input_data.get("input", "")
try:
result = sp.sympify(expression)
except Exception as e:
result = str(e)
return {"content": result}Rules for custom tools:
- Return a dict with the result under
"content"— that is what the agent reads as the observation. - Write a
descriptionthat tells the LLM when to use the tool and what input shape it expects; it is the single biggest factor in tool-selection quality. - Call
ensure_configandrun_on_node_execute_runso callbacks and tracing work.
See Custom Nodes for the full node contract, including input schemas and connection handling.
Tool output handling
Two agent-level settings shape what the agent sees from tools:
tool_output_max_length/tool_output_truncate_enabled— long tool outputs are truncated to a token budget before entering the prompt (enabled by default).direct_tool_output_enabled— when true, the agent may return a raw tool output as the final answer without rephrasing it.