Built-in Tools
Pre-registered tools any agent, classify, or guardrails node — or any Skill — can call.
Set a node's tools config field to a list of tool names to grant it these capabilities. The LLM decides when to call a tool during its turn; the platform executes it and returns the result.
{
"tools": ["web_search", "trigger_workflow"]
}Available tools
| Tool | Purpose |
|---|---|
web_search | Search the internet for current information |
code_executor | Run Python, Bash, or sh in a sandboxed subprocess |
sql_query | Read-only SQL SELECT against the internal DB or an external datasource |
api_caller | Generic HTTP client for calling external REST APIs |
file_reader | Semantic search over a Knowledge base |
email_draft | Compose an email draft (does not send) |
calendar_read | Read calendar events in a date range |
data_transform | Filter, map, sort, aggregate, or project JSON data |
trigger_workflow | Invoke another published workflow at runtime |
create_meeting | Start a meeting (Jitsi/Zoom) or schedule one on the built-in Calendar, and return the join URL |
emit_event | Publish a business event to the Event Bus to trigger downstream workflows or advance a Saga |
web_search
Search the internet. Returns titles, URLs, and text snippets.
| Param | Required | Description |
|---|---|---|
query | yes | The search query string |
max_results | no | 1–10, default 5 |
language | no | ISO 639-1 code, default en |
code_executor
Execute code in a sandboxed subprocess. stdout/stderr are each capped at 32 KB.
| Param | Required | Description |
|---|---|---|
code | yes | Source code to execute |
language | no | python (default), bash, or sh |
timeout_seconds | no | 1–120, default 30 |
sql_query
Execute a read-only SELECT (or WITH … SELECT). Omit datasource to query the internal hrida database.
| Param | Required | Description |
|---|---|---|
query | yes | A SQL SELECT statement |
max_rows | no | 1–1000, default 100 |
timeout_seconds | no | 1–120, default 30 |
datasource | no | Catalog secret name holding an external DB connection URL |
catalog_id | no | Catalog to scope the secret lookup |
api_caller
Make an HTTP request to an external REST API. Response body is capped at 8 KB. Automatically retries on 429/503.
| Param | Required | Description |
|---|---|---|
url | yes | Full URL to call |
method | no | GET (default), POST, PUT, PATCH, DELETE |
headers | no | Object of HTTP headers |
body | no | Request body (JSON auto-sets Content-Type) |
query_params | no | URL query parameters as key-value pairs |
auth_secret | no | Catalog secret name holding the credential |
auth_type | no | bearer (default), basic, or api_key |
timeout_seconds | no | 1–120, default 30 |
Security:
urlis validated against an SSRF allowlist before the request is sent — the same check used formcpnodeserver_url. Private/internal IP ranges (10.x,192.168.x,169.254.x,127.x,::1, etc.) and the cloud metadata address (169.254.169.254) are blocked by default, sinceapi_callercan be reached by any agent_developer's skill, not just admins.- To intentionally allow calls to internal services in a trusted deployment, set
API_CALLER_ALLOW_PRIVATE_URLS=true. This disables the check for allapi_callercalls platform-wide — scope it narrowly and only enable it if you understand the tradeoff.
file_reader
Retrieve relevant text chunks from a knowledge base via semantic search.
| Param | Required | Description |
|---|---|---|
knowledge_id | yes | Knowledge base ID to search within |
query | yes | Natural language query |
limit | no | 1–50, default 5 |
min_score | no | 0.0–1.0, default 0.0 |
email_draft
Compose a professional email and return it for review. Does not send.
| Param | Required | Description |
|---|---|---|
to | yes | Recipient address |
subject | yes | Subject line |
body | yes | Body content |
cc, bcc, reply_to | no | Optional address fields |
format | no | text (default) or html |
calendar_read
Read calendar events within a date range.
| Param | Required | Description |
|---|---|---|
start_date | yes | ISO 8601 date |
end_date | no | Defaults to start_date + 7 days |
calendar_id | no | Filter to a specific calendar |
include_attendees | no | Include each event's attendee list |
search | no | Keyword filter on event title |
max_events | no | 1–500, default 100 |
data_transform
Apply a transformation to structured JSON data. Output capped at 200 KB.
| Param | Required | Description |
|---|---|---|
data | yes | JSON array or object, as a string |
operation | yes | filter, map, sort, aggregate, or select_fields |
expression | no | Python expression — item for per-item ops, data for aggregate |
reverse | no | For sort: descending order |
fields | no | For select_fields: comma-separated field names |
trigger_workflow
Invoke another published workflow by ID or exact name and return its final output. Unlike a sub_workflow node — which is wired into the graph ahead of time by the workflow author — this lets the agent decide dynamically, at runtime, whether and which workflow to delegate to, based on its own reasoning.
| Param | Required | Description |
|---|---|---|
workflow | yes | Target workflow ID or exact name |
input | yes | Text input passed to the child workflow |
wait_for_result | no | true (default) blocks for the final output; false fires asynchronously and returns a run_id |
Blocking example — the agent waits for the child workflow to finish and gets its output back directly:
{ "workflow": "Daily Summary", "input": "Summarize today's tickets", "wait_for_result": true }Fire-and-forget example — the agent kicks off a long-running workflow and continues without waiting:
{ "workflow": "wf-abc123", "input": "Process the uploaded batch", "wait_for_result": false }Returns a run_id; poll GET /api/v1/agent-workflows/runs/{run_id} for status. Either way, the child run is linked back to the calling run (parent_run_id/parent_node_id) and can be walked as part of a call-chain tree — see Traceability & Audit Log → chain correlation.
Safety guarantees:
- Not-published rejection — refuses to invoke a
draftorstagedworkflow. - Recursion guard — a workflow cannot trigger itself, directly or via a longer chain (A → B → A is blocked), and chains deeper than 5 hops are rejected. This prevents an LLM-driven decision loop from recursing indefinitely.
- Errors are surfaced, not swallowed — if the child workflow fails, the tool returns the failure as a tool error rather than silently reporting "no output."
Use a sub_workflow node when the workflow author already knows, at build time, that this graph should always call a specific child workflow at this point.
Use trigger_workflow when the decision of whether and which workflow to invoke should be made by the LLM itself — e.g. a triage agent that decides, based on ticket content, whether to delegate to a "Billing Escalation" workflow, an "IT Support" workflow, or neither.
create_meeting
Create a meeting and return the join URL. Uses the first enabled meeting plugin unless plugin_type is given.
| Param | Required | Description |
|---|---|---|
title | yes | Meeting title |
plugin_type | no | jitsi, zoom, or calendar (schedules on the built-in Calendar). Omit to use the first enabled plugin |
participants | no | User IDs or emails to invite |
{ "title": "Engineering Standup", "participants": ["alice@example.com", "bob@example.com"] }Cannot start a Multi-Agent Room (plugin_type="agents") — those require backing-channel creation not exposed through this tool; use the Meetings UI for that plugin type instead.
The meeting is attributed to whoever's chat or workflow run actually triggered the calling agent — this is the only built-in tool that needs real caller identity (MeetingSessions.created_by must be a real user, since it drives the "My Sessions" list and access control). If called from a context with no real triggering user (e.g. an isolated skill test), it returns an error rather than guessing or using a placeholder identity.
For broader meeting capabilities (listing sessions, joining existing rooms, reading notes, posting to a Multi-Agent Room), see Meetings → Agent Integration for the hrida-mcpo-meetings MCP tool server, which exposes the full meetings REST API instead of just creation.
emit_event
Publish a business event to the Event Bus. The event is written durably to the database and fanned out to all workflows subscribed to that event type. Used to:
- Signal saga step completion (success or failure) so the Saga Coordinator advances or compensates
- Trigger downstream autonomous workflows without hard-coding a direct call
- Notify external systems that something happened inside a workflow
| Param | Required | Description |
|---|---|---|
event_type | yes | Snake_case event name, e.g. hr_record_created, invoice_approved |
payload | yes | JSON-encoded string with event data, e.g. "{\"employee_id\": \"EMP001\"}" |
correlation_id | no | Business key linking related events across workflows. Always pass this when participating in a Saga or multi-step process. |
source | no | Identifier for the publisher. Defaults to the workflow run ID. |
Usage in a saga step:
{
"event_type": "hr_record_created",
"payload": "{\"employee_id\": \"EMP001\", \"hr_record_id\": \"HR-123\"}",
"correlation_id": "EMP001"
}Usage to signal failure:
{
"event_type": "hr_record_failed",
"payload": "{\"employee_id\": \"EMP001\", \"error\": \"Duplicate email\"}",
"correlation_id": "EMP001"
}Key rule: emit exactly one terminal event per workflow run (either success or failure — never both). The Saga Coordinator uses the first matching event it receives; a second one may cause state inconsistency.
Returns the event_id of the published event.
A compensation workflow (the one that undoes a saga step) must emit comp_{step_id}_done (or the configured compensation_done_event) when its undo work is complete. Without this, the saga instance stays in compensating state.
{
"event_type": "hr_record_deleted",
"payload": "{\"employee_id\": \"EMP001\"}",
"correlation_id": "EMP001"
}Granting tools to a Skill
Tools aren't exclusive to agent-builder nodes — any Skill can declare a tools list, and any model with that skill attached gets the same capabilities.
Related
- Node Types — full node reference, including
agent,classify, andguardrailswhich accepttools - Triggers — cron, webhook, and event subscription triggers
- Event-Driven Workflows — how the Event Bus and subscriptions work
- API Builder → Tool Server Publishing — publish an OpenAPI-defined API and it becomes a callable tool server automatically, no manual "Add Tool Server" step
- Saga Orchestration — coordinating multi-step sagas with emit_event