---
title: Tools | Developer Documentation
---

A “tool” is a utility that can be called by an agent on behalf of an LLM. A tool can be called to perform custom actions, or retrieve extra information based on the LLM-generated input. A result from a tool call can be used by subsequent steps in a workflow, or to compute a final answer. For example, a “weather tool” could fetch some live weather information from a geographical location.

## Tool Function

The `tool` function is a utility provided to define a tool that can be used by an agent. It takes a function and a configuration object as arguments. The configuration object includes the tool’s name, description, and parameters.

### Parameters with Zod

The `parameters` field in the tool configuration is defined using `zod`, a TypeScript-first schema declaration and validation library. `zod` allows you to specify the expected structure and types of the input parameters, ensuring that the data passed to the tool is valid.

Example:

```
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";
import { z } from "zod";


// first arg is LLM input, second is bound arg
const queryKnowledgeBase = async ({ question }, { userToken }) => {
  const response = await fetch(`https://knowledge-base.com?token=${userToken}&query=${question}`);
  // ...
};


// define tool with zod validation
const kbTool = tool(queryKnowledgeBase, {
  name: 'queryKnowledgeBase',
  description: 'Query knowledge base',
  parameters: z.object({
    question: z.string({
      description: 'The user question',
    }),
  }),
});
```

In this example, `z.object` is used to define a schema for the `parameters` where `question` is expected to be a string. This ensures that any input to the tool adheres to the specified structure, providing a layer of type safety and validation.

## Built-in tools

You can import built-in tools from the `@llamaindex/tools` package.

```
import { agent } from "@llamaindex/workflow";
import { wiki } from "@llamaindex/tools";


const researchAgent = agent({
  name: "WikiAgent",
  description: "Gathering information from the internet",
  systemPrompt: `You are a research agent. Your role is to gather information from the internet using the provided tools.`,
  tools: [wiki()],
});
```

## MCP tools

If you have a MCP server running, you can fetch tools from the server and use them in your agents.

```
// 1. Import MCP tools adapter
import { mcp } from "@llamaindex/tools";
import { agent } from "@llamaindex/workflow";


// 2. Initialize a MCP client
// by npx
const server = mcp({
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
  verbose: true,
});
// or by StreamableHTTP transport
const server = mcp({
  url: "http://localhost:8000/mcp",
  verbose: true,
});


// if your MCP server is not using StreamableHTTP transport, you can also use SSE transport
// by setting useSSETransport to true.
// See: https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse-deprecated
const server = mcp({
  url: "http://localhost:8000/mcp",
  useSSETransport: true,
  verbose: true,
});


// 3. Get tools from MCP server
const tools = await server.tools();


// Now you can create an agent with the tools
const agent = agent({
  name: "My Agent",
  systemPrompt: "You are a helpful assistant that can use the provided tools to answer questions.",
  llm: openai({ model: "gpt-4o" }),
  tools: tools,
});
```

You can also use [MCP Toolbox for Databases](/typescript/framework/integration/mcp-toolbox/index.md) to interact with MCP tools.

## Function tool

You can still use the `FunctionTool` class to define a tool. A `FunctionTool` is constructed from a function with signature

```
(input: T, additionalArg?: AdditionalToolArgument) => R
```

where

- `input` is generated by the LLM, `T` is the type defined by the tool `parameters`
- `additionalArg` is an optional extra argument, see “Binding” below
- `R` is the return type

### Binding

An additional argument can be bound to a tool, each tool call will be passed

- the input provided by the LLM
- the additional argument (extends object)

Note: calling the `bind` method will return a new `FunctionTool` instance, without modifying the tool which `bind` is called on.

Example to pass a `userToken` as additional argument:

```
import { tool } from "llamaindex";
import { agent } from "@llamaindex/workflow";


// first arg is LLM input, second is bound arg
const queryKnowledgeBase = async ({ question }, { userToken }) => {
  const response = await fetch(`https://knowledge-base.com?token=${userToken}&query=${question}`);
  // ...
};


// define tool as usual
const kbTool = tool(queryKnowledgeBase, {
  name: 'queryKnowledgeBase',
  description: 'Query knowledge base',
  parameters: z.object({
    question: z.string({
      description: 'The user question',
    }),
  }),
});


// create an agent
const additionalArg = { userToken: 'abcd1234' };
const workflow = agent({
  tools: [kbTool.bind(additionalArg)],
  // llm, systemPrompt etc
})
```
