Choose what your agent can do beyond writing text, across built-in toolkits, browser client tools, and MCP servers.
Tools are how an agent moves from describing to doing. An agent with no tools can only answer from its instructions and its training. An agent with tools can search your documents, read your application state, call your APIs, and act on the results.
HeroUI Agent has three kinds, and the difference that matters is where each one runs.
| Kind | Runs in | Configured in | Best for |
|---|---|---|---|
| Built-in toolkits | HeroUI's hosted runtime | Dashboard | Capabilities we host for you |
| Client tools | The visitor's browser | Your code | Your application state and authenticated APIs |
| MCP servers | A server you point us at | Dashboard | Third-party systems that speak MCP |
Client tools are the ones to reach for first. Because they execute in the page with the signed-in person's own session, they inherit your existing permissions automatically — the hosted runtime only ever learns each tool's name, description, and schema, never its implementation or its results' path to your backend.
Toolkits are capabilities the hosted runtime provides. Switch them on per project; they apply to the next message with no deploy.
| Toolkit | What the agent can do | Requires |
|---|---|---|
| Search knowledge | Query the project's knowledge base and quote relevant passages | At least one Ready, enabled document |
| Web search | Search the public web for current information | — |
| Image search | Find images matching a description | Web search |
| News search | Search recent news coverage with publication dates | Web search |
| Create report | Produce structured reports and summaries | A browser implementation, see below |
Search knowledge needs both halves. The toolkit switch alone does nothing if the project has no document that is both Ready and enabled — the tool is not offered to the agent at all.
Image search and News search remain visible but disabled while Web search is off. Turning web search back on restores the preferences you chose previously. News search is off by default.
Create report is different from the others: enabling it scaffolds a client tool named createReport in the generated embed code, which you then implement. The runtime does not host it. Treat the switch as a starting point for your own reporting logic rather than a finished capability.
Web results and knowledge excerpts are both handled as untrusted external content. The agent quotes them in prose and keeps them separate from the datasets your client tools return.
Client tools are declared in code, not the dashboard, because their implementations are yours:
import {HeroUIAgent, createToolHelper} from "@heroui/agent";
import {z} from "zod";
const tool = createToolHelper<AppContext>();
const tools = [
tool({
name: "search_orders",
displayName: "Search orders",
description: "Find orders for the signed-in customer by status or date",
parameters: z.object({status: z.string().optional()}),
execute: ({status}, context) => context.apiClient.searchOrders({status}),
}),
];
<HeroUIAgent
getAuthToken={getAuthToken}
agentId={process.env.NEXT_PUBLIC_HEROUI_AGENT_ID!}
tools={tools}
/>;A project can declare up to 20 client tools, and the manifest sent to the runtime is capped at 16 KB — keep descriptions purposeful rather than exhaustive.
See Client tools for the full API, typed context, and tool states.
The runtime owns these names, and a client tool that uses one is rejected:
callMcpTool, composeUI, executeSandbox, getComponentSchema, renderComponent, searchKnowledge, searchMcpTools, searchWeb
The mcp_ prefix is reserved wholesale, so no client tool can impersonate a tool borrowed from an MCP server.
Connecting an MCP server borrows its tools into your agent. Each one is exposed as mcp_{server}_{tool}, so the agent can tell which integration a tool came from, and results are labeled as untrusted data from that server.
Servers are added in the dashboard with an optional per-server allowlist, so you can connect a server that exposes twenty tools and permit only the three you want. See MCP servers for setup, authentication, and security guidance.
Tools that change something should ask first. Client tools declare needsApproval, and the embed's permission mode decides how that flag is honored:
| Mode | Behavior |
|---|---|
ask | Confirm every tool call, whether or not it declares approval |
auto | Confirm only tools that declare needsApproval |
full | Run every declared tool without confirmation |
auto is the default and the right choice for most products: reads run immediately, writes prompt. Set the mode with permissions.defaultMode, and use permissions.showPicker to let people change it themselves. The picker only appears once you declare client tools — with nothing to approve, there is nothing to pick.
Allowing full lets a visitor bypass every needsApproval flag you set. Only enable showPicker
when no declared tool can do something irreversible.