Assivy

Tools

The shared registry — standard, HTTP, function, and built-in tools.

Tools live in one shared registry on the Tools page. An agent links a tool by { id } and uses it exactly as saved: config, description, icon, sharing, hooks, approval, and composer toggle all come from the shared row, and keys written on the agent's entry are ignored. Only enabled is per agent, so editing a shared tool changes every agent that links it.

An agent's tools list can also hold an inline tool, such as { "type": "http_client", "name": "get_order", "url": "…" }. Its entry is its whole definition. Inline tools are mostly an API pattern; the agent editor's Create New Tool saves a shared tool and links it.

Every tool carries a description (what the model reads), an icon, a sharing audience (unset means it inherits the agent's), optional hooks, an optional approval step, and a composer toggle. With Let the user select this tool on, the chat box shows a button for it. Pressing it tells the model the user wants that tool this turn. It is a hint, not a gate: the tool stays available either way.

Names

A custom tool's name is the function name the model calls. It starts with a letter, uses only letters, digits, and underscores (^[a-zA-Z][a-zA-Z0-9_]*$), is at most 64 characters, and is unique in the org. find_tools is reserved. Standard tools are named after their type and can't be renamed.

Standard tools

ToolWhat it doesSettings
web_searchThe model provider's own web search, on OpenAI and Gemini modelssearchContextSize: low, medium, high (OpenAI only)
web_fetchThe provider's own page fetch, on Claude and Gemini modelsmaxUses, allowedDomains, blockedDomains (Claude only)
search_knowledgeSearches the folders you pick and returns citable passagesSee Knowledge
create_record, read_record, update_record, delete_record, list_recordsWork with records of an entitySee Entities

web_search and web_fetch are created for every org and can't be deleted. On a model with no native equivalent they're skipped for that turn. Every other standard tool is a single shared row, created the first time you add it.

Built-in tools

  • run_code is on every turn. The model writes Python (the default), TypeScript, or bash, and it runs in the shared sandbox with no network, no package installs, and a 30-second limit. Files it writes to $OUTPUT_DIR are attached to the reply, up to 10 files of 10 MB each per turn. Python has python-docx, openpyxl, xlsxwriter, python-pptx, reportlab, weasyprint, pandas, matplotlib, and pillow. run_code also reads oversized tool results that were saved as handle:// URIs.
  • find_tools appears when an agent has more than 10 tools outside the core set (MCP tools, app actions, subagents, custom and entity tools). Those tools are then listed by name and description only, and the model loads the ones it needs on demand. Core tools are always loaded: web_search, search_knowledge, run_code, the skill tools, memory, handoff, delegate_task, and connect_<slug>.

Three built-in tools are switched on per agent rather than saved in the registry. memory lets the model write memories. delegate_task starts helper agents (Subagents). handoff hands the conversation to a person. Its strategy is set per agent: record saves the request for your team, and link also shows the user a button to your own case page. The link must be an http(s) URL and can include {{subject}}, {{summary}}, {{reason}}, and {{threadId}}, each URL-encoded. The button text is buttonLabel (up to 40 characters, default "Open a case").

HTTP tools

An http_client tool calls one endpoint. Its URL, headers, query params, and body are templates:

  • {{name}} is filled by the model. Each distinct name becomes one string parameter in the tool's schema.
  • ${user.id}, ${user.email}, ${tenantId}, ${user.accessToken} are filled by the platform, never by the model. The access token is filled only when the request goes to Assivy's own API. For any other host it's empty. {{auth_token}} is an older alias for it.
{
  "url": "https://api.example.com/orders/{{orderId}}",
  "method": "GET",
  "headers": { "X-Customer": "${user.email}" }
}

The method is GET, HEAD, POST, PUT, PATCH, or DELETE. It can also be a single {{var}}, and the model then picks one of those. The body type is json (the default), form_data, x_www_form_urlencoded, or raw. GET and HEAD never send a body, and a JSON body must still parse after substitution. The URL must start with http:// or https://, or be a template.

Each call has a 30-second timeout by default (timeout, in ms). Responses over 256 KB are cut off with a marker. A call follows at most 5 redirects, and private and internal addresses are refused at every hop. A failed call isn't retried. Errors come back to the model as text (HTTP Error 404: …). JSON responses are parsed, and anything else is passed through as is. HTTP tools don't go through Outbound access.

Function tools

A function_call tool runs a TypeScript or Python body in the shared Docker sandbox, with a 30-second limit and no access to the host. TypeScript bodies get fetch through the egress proxy, so they reach only the hosts allowed under Outbound access. Python bodies have no network. A TypeScript tool can run in the user's browser instead. See Function tools for how to write the body, runtime, files, limits, and log().

Approvals

Turn on Require approval before it runs (interruptConfig.interruptBefore) and the turn pauses on every call until the user accepts or rejects it. To replace the default Accept/Reject card, set interruptConfig.approvalWidget to a widget, such as the built-in tool-approval or your own (Widgets). Its state is { toolName, input }. Its buttons use { type: "approve_tool" }, { type: "reject_tool" }, or { type: "request_change" }. A rejection can carry a reason back to the agent, and a reason field the user typed in the form takes priority.

web_search and search_knowledge draw their own results card. These are result widgets, not approvals.

Hooks

Before and after hooks run on HTTP tools, search_knowledge, the entity tools, and Composio apps attached to an agent (Integrations). web_search and web_fetch ignore hooks. Function tools have none, because their logic is already in the body. A hook is a function named after the hook:

async function beforeExecute(data, runtime) {
  // data is the tool's arguments. Return the arguments to use.
  log('order lookup', { user: runtime.user?.email });
  return { ...data, region: 'eu' };
}

afterExecute(data, runtime) receives the tool's result and returns the result to use. Hooks run in the same sandbox as function tools, with the same runtime and log(). App hooks also get runtime.toolName and runtime.appSlug. A hook that returns nothing passes data on, including any edits it made in place. Hooks fail open: a throw, a timeout, a misnamed function, or a result over 128 KB lets the original data through.

On this page