
# Call Tools

Some models allow developers to provide a list of tools that can be called at any time during a generation. This is useful for extending the capabilities of a language model to either use logic or data to interact with systems external to the model.

<Browser>
  <ChatGeneration
    history={[
      { role: 'User', content: 'How is it going?' },
      { role: 'Assistant', content: 'All good, how may I help you?' },
    ]}
    inputMessage={{
      role: 'User',
      content: 'What is the weather in Paris and New York?',
    }}
    outputMessage={{
      role: 'Assistant',
      content:
        'The weather is 24°C in New York and 25°C in Paris. It is sunny in both cities.',
    }}
  />
</Browser>

## Client

Let's create a React component that imports the `useChat` hook from the `@ai-sdk/react` module. The `useChat` hook will call the `/api/chat` endpoint when the user sends a message. The endpoint will generate the assistant's response based on the conversation history and stream it to the client. If the assistant responds with a tool call, the hook will automatically display them as well.

```tsx filename='app/page.tsx'
'use client';

import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
import { useState } from 'react';
import type { ChatMessage } from './api/chat/route';

export default function Page() {
  const [input, setInput] = useState('');

  const { messages, sendMessage } = useChat<ChatMessage>({
    transport: new DefaultChatTransport({
      api: '/api/chat',
    }),
  });

  return (
    <div>
      <input
        className="border"
        value={input}
        onChange={event => {
          setInput(event.target.value);
        }}
        onKeyDown={async event => {
          if (event.key === 'Enter') {
            sendMessage({
              text: input,
            });
            setInput('');
          }
        }}
      />

      {messages.map((message, index) => (
        <div key={index}>
          {message.parts.map(part => {
            switch (part.type) {
              case 'text':
                return <div key={`${message.id}-text`}>{part.text}</div>;
              case 'tool-getWeather':
                return (
                  <div key={`${message.id}-weather`}>
                    {JSON.stringify(part, null, 2)}
                  </div>
                );
            }
          })}
        </div>
      ))}
    </div>
  );
}
```

## Server

You will create a new route at `/api/chat` that will use the `streamText` function from the `ai` module to generate the assistant's response based on the conversation history.

You will use the [`tools`](/docs/reference/ai-sdk-core/generate-text#tools) parameter to specify a tool called `celsiusToFahrenheit` that will convert a user given value in celsius to fahrenheit.

You will also use zod to specify the schema for the `celsiusToFahrenheit` function's parameters.

```tsx filename='app/api/chat/route.ts'
import {
  type InferUITools,
  type ToolSet,
  type UIDataTypes,
  type UIMessage,
  convertToModelMessages,
  stepCountIs,
  streamText,
  tool,
} from 'ai';
import { z } from 'zod';

const tools = {
  getWeather: tool({
    description: 'Get the weather for a location',
    inputSchema: z.object({
      city: z.string().describe('The city to get the weather for'),
      unit: z
        .enum(['C', 'F'])
        .describe('The unit to display the temperature in'),
    }),
    execute: async ({ city, unit }) => {
      const weather = {
        value: 24,
        description: 'Sunny',
      };

      return `It is currently ${weather.value}°${unit} and ${weather.description} in ${city}!`;
    },
  }),
} satisfies ToolSet;

export type ChatTools = InferUITools<typeof tools>;

export type ChatMessage = UIMessage<never, UIDataTypes, ChatTools>;

export async function POST(req: Request) {
  const { messages }: { messages: ChatMessage[] } = await req.json();

  const result = streamText({
    model: 'openai/gpt-4o',
    system: 'You are a helpful assistant.',
    messages: convertToModelMessages(messages),
    stopWhen: stepCountIs(5),
    tools,
  });

  return result.toUIMessageStreamResponse();
}
```

---

<GithubLink link="https://github.com/vercel/ai/blob/main/examples/next-openai-pages/pages/tools/call-tool/index.tsx" />


## Navigation

- [Generate Text](/v5/cookbook/next/generate-text)
- [Generate Text with Chat Prompt](/v5/cookbook/next/generate-text-with-chat-prompt)
- [Generate Image with Chat Prompt](/v5/cookbook/next/generate-image-with-chat-prompt)
- [Caching Middleware](/v5/cookbook/next/caching-middleware)
- [Stream Text](/v5/cookbook/next/stream-text)
- [Stream Text with Chat Prompt](/v5/cookbook/next/stream-text-with-chat-prompt)
- [Stream Text with Image Prompt](/v5/cookbook/next/stream-text-with-image-prompt)
- [Chat with PDFs](/v5/cookbook/next/chat-with-pdf)
- [streamText Multi-Step Cookbook](/v5/cookbook/next/stream-text-multistep)
- [Markdown Chatbot with Memoization](/v5/cookbook/next/markdown-chatbot-with-memoization)
- [Generate Object](/v5/cookbook/next/generate-object)
- [Generate Object with File Prompt through Form Submission](/v5/cookbook/next/generate-object-with-file-prompt)
- [Stream Object](/v5/cookbook/next/stream-object)
- [Call Tools](/v5/cookbook/next/call-tools)
- [Call Tools in Multiple Steps](/v5/cookbook/next/call-tools-multiple-steps)
- [Model Context Protocol (MCP) Tools](/v5/cookbook/next/mcp-tools)
- [Share useChat State Across Components](/v5/cookbook/next/use-shared-chat-context)
- [Human-in-the-Loop Agent with Next.js](/v5/cookbook/next/human-in-the-loop)
- [Send Custom Body from useChat](/v5/cookbook/next/send-custom-body-from-use-chat)
- [Streaming with Custom Format](/v5/cookbook/next/custom-stream-format)
- [Render Visual Interface in Chat](/v5/cookbook/next/render-visual-interface-in-chat)


[Full Sitemap](/sitemap.md)
