Tools
Agents interact with external APIs through a fixed set of 4 built-in tools. Every outbound HTTP request passes through multiple security layers before leaving the executor. Tools are explicitly enabled per task -- an agent cannot invoke a tool that is not listed in its task configuration.
Tool Summary
api_call
Yes (credential required)
GET, POST, PUT, DELETE
Authenticated API calls with auto-injected credentials
http_get
No
GET
Unauthenticated data retrieval from approved domains
http_post
No
POST
Unauthenticated POST requests for webhook-style calls
webhook
No
POST
POST to task-registered webhook URLs
api_call
The primary tool for authenticated API interactions. Supports all standard HTTP methods and automatically injects credentials based on the referenced credential's auth_type. The agent specifies which credential to use by name, and the executor resolves the actual secret value at runtime.
Schema
{
"name": "api_call",
"description": "Make an authenticated HTTP request to an external API. The credential is injected automatically into the auth header -- never include API keys in the URL, body, or custom headers.",
"input_schema": {
"type": "object",
"properties": {
"method": {
"type": "string",
"enum": ["GET", "POST", "PUT", "DELETE"],
"description": "HTTP method"
},
"url": {
"type": "string",
"description": "The API endpoint URL (HTTPS only)"
},
"credential": {
"type": "string",
"description": "Name of the credential to use (e.g., LUNARCRUSH_API_KEY)"
},
"headers": {
"type": "object",
"description": "Additional request headers (do NOT include auth headers)"
},
"body": {
"type": "object",
"description": "Request body for POST/PUT (JSON)"
},
"query_params": {
"type": "object",
"description": "URL query parameters"
}
},
"required": ["method", "url", "credential"]
}
}Credential Injection
The executor resolves the credential parameter to a decrypted credential from the task's credential subcollection and injects it based on auth_type:
bearer
Authorization: Bearer <value> header
Slack, Notion, Airtable, LunarCrush
header
Custom header specified by auth_header_name
CoinMarketCap (X-CMC_PRO_API_KEY), NewsAPI (X-Api-Key)
query_param
Appended as ?api_key=<value> query parameter
Alpha Vantage, OpenWeather
The LLM never sees credential values. It references credentials by name only. The safety preamble instructs the LLM to never include API keys in URLs, request bodies, or custom headers.
Execution Flow
Credential name validation -- the
credentialfield is required; requests without it are rejected.URL validation -- domain checked against the task's approved integrations (default-deny).
Credential resolution -- the named credential is looked up in the decrypted credential map.
Credential leak scan -- the outbound URL, body, and custom headers are scanned for credential values in plaintext, base64, and URL-encoded forms.
Header construction -- the credential is injected into the appropriate header or query parameter based on
auth_type.DNS pinning -- the hostname is resolved, the IP is validated against private ranges, and the URL is rewritten to the resolved IP.
HTTP request -- the request is sent with the
Hostheader and TLS SNI set to the original hostname.Response sanitization -- the response is truncated to the plan's maximum response size and wrapped in
<tool_response>tags.
Example
http_get
Unauthenticated GET requests for fetching public data from approved integration domains. Useful for APIs that do not require authentication or when the data is publicly accessible.
Schema
Behavior
URL must be HTTPS and must match an approved integration domain for the task.
DNS pinning is applied (resolve, validate IP, rewrite URL).
No credential injection. Use
api_callif authentication is needed.Response is truncated to the plan's max response size and sanitized before returning to the LLM.
Only GET method is supported.
Example
http_post
Unauthenticated POST requests, primarily for webhook-style interactions where the receiving endpoint does not require separate authentication (e.g., Slack incoming webhooks where the secret is embedded in the URL path).
Schema
Behavior
URL must be HTTPS and must match an approved integration domain.
DNS pinning is applied.
The body is sent as JSON (
Content-Type: application/json).No credential injection.
Response is truncated and sanitized before returning to the LLM.
Example
webhook
A specialized tool for posting data to pre-registered webhook URLs. Unlike the other tools, webhook validates the target URL against the task's webhook_urls list rather than the integration domain registry.
Schema
Requirements
The
webhookintegration must be included in the task'sintegrationsarray.The target URL's hostname must match one of the task's registered
webhook_urls.Maximum of 3 webhook URLs per task.
All webhook URLs must be HTTPS.
Webhook URLs are validated at task creation time: HTTPS only, no private IPs.
DNS pinning is applied at execution time.
Task Configuration Example
Tool Call Example
DNS Pinning Security
All 4 tools apply DNS pinning to prevent DNS rebinding (TOCTOU) attacks. This is a critical security measure that closes the window between DNS resolution and HTTP connection establishment.
The Problem: DNS Rebinding
Without DNS pinning, an attacker could:
Register a domain that resolves to a public IP during validation.
Change the DNS record to resolve to a private IP (e.g.,
169.254.169.254for GCP metadata) between validation and connection.The HTTP client connects to the private IP, bypassing the private IP check.
The Solution: Resolve-Validate-Rewrite
The process:
Resolve -- the hostname is resolved to an IP address via
socket.getaddrinfo().Validate -- the resolved IP is checked against all blocked private and reserved ranges.
Rewrite -- the URL's netloc is replaced with the resolved IP address (IPv6 addresses are wrapped in brackets).
Host header -- the original hostname is set as the
Hostheader so the destination server routes the request correctly.TLS SNI -- the
sni_hostnameextension is set to the original hostname so TLS certificate validation and virtual hosting work correctly.
This ensures that the IP address validated by the security layer is the exact same IP address the HTTP client connects to.
URL Whitelist (Default-Deny)
Every tool validates the target URL against the platform's integration registry before making any HTTP request:
The URL must use the
https://scheme. Plain HTTP is rejected.The URL's hostname must not resolve to a private IP range.
The URL's hostname must match an
allowed_domainentry in one of the task's approved integrations.
If any check fails, the tool returns an error to the LLM with a descriptive reason. The LLM can then adjust its approach or produce output with the data it has already gathered.
For the webhook tool, URL validation checks against the task's webhook_urls list instead of the integration domain registry.
See Integrations for the full list of approved domains per integration.
Private IP Blocking
Resolved IP addresses are checked against the following blocked ranges:
10.0.0.0/8
RFC 1918 private
172.16.0.0/12
RFC 1918 private
192.168.0.0/16
RFC 1918 private
100.64.0.0/10
Carrier-grade NAT (RFC 6598)
169.254.0.0/16
Link-local (includes GCP metadata at 169.254.169.254)
127.0.0.0/8
Loopback
::1/128
IPv6 loopback
fc00::/7
IPv6 unique local address
fe80::/10
IPv6 link-local
If a hostname fails DNS resolution entirely, it is also blocked (fail-closed behavior).
Rate Limiting
Tool calls are rate-limited per execution based on the user's subscription plan:
API calls per execution
20
50
API calls per minute
10
20
Max response size
500 KB
2 MB
Rate limits are checked before every tool call by the ExecutionRateState tracker. If the per-execution limit or per-minute limit is reached, the tool returns an error to the LLM. The LLM can then choose to produce its final output with the data it has already gathered.
Per-minute rate limiting uses a sliding window: if more than 60 seconds have elapsed since the first call in the current window, the counter resets.
Tool Registration and Execution
Registration
Tools are registered in the ToolRegistry at executor startup via _register_builtins(). Each registration provides:
Name -- the tool identifier used by the LLM.
Handler -- the async function that executes the tool.
Description -- human-readable description sent to the LLM.
Schema -- JSON Schema defining the tool's input parameters.
Requires -- optional service name for pre-built tools that need specific credentials.
The registry exposes get_definitions() which returns Anthropic-format tool schemas filtered to the tools enabled in the task's tools array.
Execution During the Agentic Loop
When the LLM responds with tool use blocks, the executor processes them through ToolRegistry.execute():
Tool calls within a single iteration are executed sequentially. Each produces a ToolCallResult that is logged in the execution record and returned to the LLM as a tool_result message.
Tool Call Billing
Authenticated API calls (api_call with a credential that is not blocked) incur a per-call fee of 0.5 credits in addition to the LLM token costs. Unauthenticated tools (http_get, http_post, webhook) do not have a per-call fee.
Tool Call Results
Every tool call produces a ToolCallResult dataclass with metadata for audit logging:
tool
string
Tool name
content
string
Response body (sanitized) or error message
url
string
Target URL
method
string
HTTP method used
credential_used
string
Credential name, if applicable
response_status
int
HTTP status code from target API
response_size_bytes
int
Size of the raw response body
latency_ms
float
Round-trip time in milliseconds
blocked
bool
Whether the call was blocked by a security layer
block_reason
string
Reason for blocking (e.g., credential_leak, dns_validation_failed, rate_limited)
Tool call results are recorded in the execution document's tool_calls array (up to 50 per execution) for debugging and auditing.
Response Handling
Tool responses are processed before being returned to the LLM:
Size truncation -- responses exceeding the plan's max response size (500 KB for Guru, 2 MB for Pro) are truncated.
Sanitization -- responses are wrapped in
<tool_response>tags to instruct the LLM to treat the content as external data, not as instructions. This mitigates prompt injection via API responses.Context window management -- individual tool results exceeding 50,000 characters are truncated with a
... (truncated)marker to prevent context window overflow.
Error Handling
When a tool call fails, the error message is returned to the LLM as the tool result. The agentic loop continues -- the LLM can decide to retry with different parameters, try a different approach, or produce its final output.
URL blocked
Domain not in approved integrations
Error: URL blocked -- Domain X not in any approved integration for this task. Approved: [...]
Missing credential field
api_call invoked without credential
Error: 'credential' field required for api_call
Credential not found
Named credential missing from task
Error: credential 'MY_KEY' not found. Check your task's credential configuration.
Credential leak detected
LLM placed credential value in body/URL/headers
Error: Blocked -- Credential X detected in outbound request. This has been logged.
DNS validation failed
Hostname unresolvable or resolves to private IP
Error: DNS resolution failed or blocked for hostname
Rate limit exceeded
Per-execution or per-minute cap reached
Error: Execution limit reached (20 API calls)
Request timeout
HTTP request took longer than 30 seconds
Error: request timed out (30s)
Unknown tool
Tool name not in registry
Error: unknown tool 'tool_name'
Webhook not enabled
webhook integration not in task
Error: webhook integration not enabled for this task
Webhook not registered
URL not in task's webhook_urls
Error: webhook URL not registered for this task. Register it in your task settings.
HTTP error
Target API returned an error
The HTTP response body is returned as-is (sanitized and wrapped in <tool_response> tags)
Last updated
