Overview
Tool types define executable functions that the AI can call during conversations. Tools enable the AI to fetch data, perform calculations, or interact with external systems.
The primary interface for defining a tool that can be called by the AI.
import type { TamboTool } from '@tambo-ai/react';
Definition
interface TamboTool<Params = any, Returns = any> {
/** Unique identifier for the tool */
name: string;
/** Description of what the tool does - used by AI to determine when to use it */
description: string;
/** Optional human-readable name for display purposes */
title?: string;
/** Optional limit for how many times this tool may be called per response */
maxCalls?: number;
/** Annotations describing the tool's behavior */
annotations?: ToolAnnotations;
/**
* The function that implements the tool's logic.
* Called by Tambo when the model decides to invoke the tool.
*/
tool: (params: Params) => Returns | Promise<Returns>;
/**
* Schema for input parameters. Accepts Standard Schema compliant validators
* (Zod 3.24+, Zod 4.x) or raw JSON Schema objects.
*/
inputSchema: SupportedSchema<Params>;
/**
* Schema for output/return value. Informs the model about the structure
* of the tool's return value.
*/
outputSchema: SupportedSchema<Returns>;
/**
* Optional function to transform tool return value into content parts.
* If not provided, the return value is stringified and wrapped in a text content part.
*/
transformToContent?: (
result: Returns
) => Promise<ChatCompletionContentPart[]> | ChatCompletionContentPart[];
}
Fields
Unique identifier for the tool. Must be unique across all registered tools.
Clear description of what the tool does. This helps the AI decide when to call this tool.description: 'Fetches current weather data for a given city'
Human-readable display name. Used in UI when showing tool status.
Limits how many times this tool can be called while generating a single response. Overrides the project’s global maxToolCallLimit.maxCalls: 1 // Only call once per response
tool
(params: Params) => Returns | Promise<Returns>
required
The function implementing the tool’s logic. Receives validated parameters and returns the result.tool: async ({ city }) => {
const response = await fetch(`https://api.weather.com/${city}`);
return response.json();
}
inputSchema
SupportedSchema<Params>
required
Schema defining input parameters. Parameters are validated against this schema before being passed to the tool.Supports:
- Standard Schema compliant validators (Zod 3.24+, Zod 4.x, Valibot, ArkType)
- Raw JSON Schema objects
import { z } from 'zod';
inputSchema: z.object({
city: z.string().describe('City name'),
units: z.enum(['metric', 'imperial']).optional()
})
outputSchema
SupportedSchema<Returns>
required
Schema describing the tool’s return value. Informs the AI about the structure of the result.outputSchema: z.object({
temperature: z.number(),
condition: z.string(),
humidity: z.number()
})
transformToContent
(result: Returns) => ChatCompletionContentPart[]
Optional function to convert tool results into content parts. Useful for tools that return rich media (images, audio, etc.).By default, results are stringified and wrapped in a text content part.transformToContent: (result) => [
{ type: 'text', text: result.description },
{ type: 'image_url', image_url: { url: result.imageUrl } }
]
Metadata describing a tool’s behavior, aligned with the MCP (Model Context Protocol) specification.
import type { ToolAnnotations } from '@tambo-ai/react';
Definition
interface ToolAnnotations {
/**
* Indicates that the tool is safe to be called repeatedly while a response
* is being streamed. Typically used for read-only tools without side effects.
*/
tamboStreamableHint?: boolean;
}
Fields
When true, indicates the tool is safe for streaming execution. The AI can call this tool multiple times with partial parameters while streaming the response.Use this for:
- Read-only operations
- Tools without side effects
- Tools that can handle partial/incomplete data
const searchTool: TamboTool = {
name: 'search',
description: 'Search the knowledge base',
annotations: {
tamboStreamableHint: true // Safe for streaming
},
tool: async ({ query }) => performSearch(query),
inputSchema: z.object({ query: z.string() }),
outputSchema: z.array(z.object({ title: z.string(), content: z.string() }))
};
Helper Functions
Helper function that provides full type inference when defining tools.
import { defineTool } from '@tambo-ai/react';
import { z } from 'zod';
const weatherTool = defineTool({
name: 'get_weather',
description: 'Fetches weather data',
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
temperature: z.number(),
condition: z.string(),
}),
tool: async ({ city }) => {
// TypeScript knows city is a string
const data = await fetchWeather(city);
// TypeScript enforces return type matches outputSchema
return data;
},
});
Using defineTool is recommended over manually typing TamboTool as it provides better type inference.
SupportedSchema
Union type for schemas that can be used with tools and components.
import type { SupportedSchema } from '@tambo-ai/react';
type SupportedSchema<Input = unknown, Output = Input> =
| StandardSchemaV1<Input, Output> // Zod, Valibot, ArkType, etc.
| JSONSchema7; // Raw JSON Schema
Tambo uses the Standard Schema specification, which provides a unified interface for validation libraries. This allows you to use any compliant validator without depending on a specific library.
Usage Example
Complete example of registering tools:
import { TamboProvider, defineTool } from '@tambo-ai/react';
import { z } from 'zod';
const getWeather = defineTool({
name: 'get_weather',
description: 'Fetches current weather for a city',
inputSchema: z.object({
city: z.string().describe('City name'),
units: z.enum(['metric', 'imperial']).default('metric'),
}),
outputSchema: z.object({
temperature: z.number(),
condition: z.string(),
humidity: z.number(),
}),
tool: async ({ city, units }) => {
const response = await fetch(
`https://api.weather.com/v1/weather?city=${city}&units=${units}`
);
return response.json();
},
});
const searchKnowledgeBase = defineTool({
name: 'search_kb',
description: 'Searches the knowledge base',
annotations: {
tamboStreamableHint: true, // Safe for streaming calls
},
maxCalls: 3, // Limit to 3 calls per response
inputSchema: z.object({
query: z.string().describe('Search query'),
}),
outputSchema: z.array(
z.object({
title: z.string(),
content: z.string(),
relevance: z.number(),
})
),
tool: async ({ query }) => {
return await searchDatabase(query);
},
});
function App() {
return (
<TamboProvider
apiKey={process.env.TAMBO_API_KEY}
userKey="user-123"
tools={[getWeather, searchKnowledgeBase]}
>
{/* Your app */}
</TamboProvider>
);
}
Advanced: Tool Content Transformation
For tools that need to return rich content (images, audio, etc.), use transformToContent:
const generateImage = defineTool({
name: 'generate_image',
description: 'Generates an image from a text prompt',
inputSchema: z.object({
prompt: z.string(),
}),
outputSchema: z.object({
url: z.string(),
alt: z.string(),
}),
tool: async ({ prompt }) => {
const result = await imageAPI.generate(prompt);
return { url: result.url, alt: prompt };
},
transformToContent: (result) => [
{
type: 'image_url',
image_url: { url: result.url },
},
],
});
Type Imports
import type {
TamboTool,
ToolAnnotations,
SupportedSchema,
} from '@tambo-ai/react';
import { defineTool } from '@tambo-ai/react';
See Also