Skip to main content

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.

TamboTool

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

name
string
required
Unique identifier for the tool. Must be unique across all registered tools.
name: 'get_weather'
description
string
required
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'
title
string
Human-readable display name. Used in UI when showing tool status.
title: 'Weather Lookup'
maxCalls
number
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
annotations
ToolAnnotations
Metadata about tool behavior. See ToolAnnotations below.
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 } }
]

ToolAnnotations

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

tamboStreamableHint
boolean
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

defineTool

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

Build docs developers (and LLMs) love