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

Tool
Auth
Method(s)
Use Case

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:

Auth Type
Injection Method
Example APIs

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

  1. Credential name validation -- the credential field is required; requests without it are rejected.

  2. URL validation -- domain checked against the task's approved integrations (default-deny).

  3. Credential resolution -- the named credential is looked up in the decrypted credential map.

  4. Credential leak scan -- the outbound URL, body, and custom headers are scanned for credential values in plaintext, base64, and URL-encoded forms.

  5. Header construction -- the credential is injected into the appropriate header or query parameter based on auth_type.

  6. DNS pinning -- the hostname is resolved, the IP is validated against private ranges, and the URL is rewritten to the resolved IP.

  7. HTTP request -- the request is sent with the Host header and TLS SNI set to the original hostname.

  8. 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

  1. URL must be HTTPS and must match an approved integration domain for the task.

  2. DNS pinning is applied (resolve, validate IP, rewrite URL).

  3. No credential injection. Use api_call if authentication is needed.

  4. Response is truncated to the plan's max response size and sanitized before returning to the LLM.

  5. 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

  1. URL must be HTTPS and must match an approved integration domain.

  2. DNS pinning is applied.

  3. The body is sent as JSON (Content-Type: application/json).

  4. No credential injection.

  5. 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 webhook integration must be included in the task's integrations array.

  • 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:

  1. Register a domain that resolves to a public IP during validation.

  2. Change the DNS record to resolve to a private IP (e.g., 169.254.169.254 for GCP metadata) between validation and connection.

  3. The HTTP client connects to the private IP, bypassing the private IP check.

The Solution: Resolve-Validate-Rewrite

The process:

  1. Resolve -- the hostname is resolved to an IP address via socket.getaddrinfo().

  2. Validate -- the resolved IP is checked against all blocked private and reserved ranges.

  3. Rewrite -- the URL's netloc is replaced with the resolved IP address (IPv6 addresses are wrapped in brackets).

  4. Host header -- the original hostname is set as the Host header so the destination server routes the request correctly.

  5. TLS SNI -- the sni_hostname extension 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:

  1. The URL must use the https:// scheme. Plain HTTP is rejected.

  2. The URL's hostname must not resolve to a private IP range.

  3. The URL's hostname must match an allowed_domain entry 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:

Range
Type

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:

Limit
Guru
Pro

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:

Field
Type
Description

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:

  1. Size truncation -- responses exceeding the plan's max response size (500 KB for Guru, 2 MB for Pro) are truncated.

  2. 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.

  3. 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.

Error
Cause
LLM Receives

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