Skip to main content

Custom tool ctx

Every custom code tool runs in a sandbox and receives two parameters: input (your declared parameters) and ctx (the platform’s tool context). Through ctx.tools.<name>(...) your code can call any built-in toolsend_email, web_search, calculate, surface_file, and the rest — without re-implementing them. This page covers the ctx object itself. For the result-shape contract (what your handle() return value does — what the agent sees, what the user sees, _render / _interactive / _llm), see Custom tools → Tool results.

Handler shape

Every code tool must export a handle(input, ctx) function.

JavaScript

Either export async function handle(...) or plain async function handle(...) works — the sandbox accepts both.

Python

Sync def handle(input, ctx): also works; coroutines are awaited.

The ctx object

Calling a built-in tool

Each ctx.tools.<name> call is dispatched server-side with the same validation, allowlists, recipient checks and audit logging that apply when the LLM calls the tool — all of it applies identically whether the LLM or your code is the caller.

Errors

If a built-in tool returns an error envelope ({ error, details }), ctx.tools.<name>(...) resolves with that envelope — it does not throw. Treat any object with an error field as failure:
If the platform connection itself fails (for example a transient network problem, or the call could not be dispatched) the call does throw — wrap in try/catch if you need resilience.

Limits

  • 30-second wall-clock for the whole sandbox execution.
  • 50 cross-tool calls per invocation. Recursion (a tool calling itself directly or indirectly) hits this guard quickly and aborts with a structured error.
  • Each invocation is isolated and any credentials do not outlive the call.
  • Call built-in tools via ctx.tools so the platform handles audit logging and cost accounting for you.

Why this exists

Without ctx, every custom tool would need to re-implement what the platform already does — send email, sign download URLs, validate render specs, manage interaction rows. With ctx, your code composes the platform’s primitives the same way the LLM does — and inherits the same guardrails for free.