> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcp-use.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> Register and type MCP tools on an MCPServer API Documentation

**Source Code**

View the source code for this module on GitHub: [[https://github.com/mcp-use/mcp-use/blob/main/libraries/typescript/packages/mcp-use/src/server/mcp-server.ts](https://github.com/mcp-use/mcp-use/blob/main/libraries/typescript/packages/mcp-use/src/server/mcp-server.ts)](https://github.com/mcp-use/mcp-use/blob/main/libraries/typescript/packages/mcp-use/src/server/mcp-server.ts)

Tools are the executable actions an MCP server exposes to clients and models. You register a tool with `server.tool()`, passing a `ToolDefinition` (name, optional Zod `schema`, optional `outputSchema`, `annotations`, and `widget` config) plus a `ToolCallback` that runs when the tool is invoked. This page documents the registration method and the related types: `ToolDefinition`, `ToolCallback`, `ToolAnnotations`, `InputDefinition`, and the per-tool widget config.

## Methods

Registers a tool on the server and returns the server instance for chaining.

```ts theme={null}
import { MCPServer } from "mcp-use/server"
```

### tool

Registers a tool that MCP clients and models can invoke to perform actions such as reading files, calling APIs, running commands, or rendering widgets. Each tool has a name, an optional input schema, an optional output schema, and a callback.

The callback may be supplied either as the `cb` field inside the definition or as the second `callback` argument. When both are present, the second argument wins (`callback || toolDefinition.cb`). If neither is supplied, the tool is still registered with the MCP SDK but without a handler. Calling `tool()` again with the same `name` re-registers (overwrites) that tool, which is how hot module reloading updates a tool during `mcp-use dev`.

The input type passed to the callback is inferred from the definition's `schema` via `InferToolInput`, and the structured output type is inferred from `outputSchema` via `InferToolOutput`, so destructured parameters and `structuredContent` are fully typed. The `HasOAuth` type parameter on the server controls whether `ctx.auth` is available in the callback.

If the definition includes a `widget` config, `tool()` automatically attaches widget metadata (for example `openai/outputTemplate`, `openai/toolInvocation/invoking`, `openai/toolInvocation/invoked`, `openai/widgetAccessible`, and `openai/resultCanProduceWidget`) to the tool's `_meta`, and wraps the callback so an empty text content entry is backfilled with `Displaying {widgetName}`. See the per-tool widget config below for defaults.

```ts theme={null}
import { MCPServer, text } from "mcp-use/server"
import { z } from "zod"

const server = new MCPServer({
  name: "simple-example-server",
  version: "1.0.0",
  description: "A simple MCP server example",
})

server.tool(
  {
    name: "hello-world",
    description: "A simple tool that returns hello world",
  },
  async () => text("Hello World!"),
)
```

**Type Parameters**

> **T** `ToolDefinition\<any, any, HasOAuth\>`
>
> The tool definition type. Its `schema` and `outputSchema` drive input/output inference for the callback.

**Parameters**

> **toolDefinition** `T & ToolDefinition\<any, any, HasOAuth\>` *required*
>
> The tool configuration object. See `ToolDefinition` for every field.
>
> **callback** `ToolCallback\<InferToolInput\<T\>, InferToolOutput\<T\>, HasOAuth\>`
>
> Optional handler invoked when the tool is called. Alternative to `toolDefinition.cb`; if provided it takes precedence over `cb`.

**Returns**

> **returns** `this`
>
> The server instance, enabling method chaining.

**Signature**

```ts wrap theme={null}
public tool: <T extends ToolDefinition<any, any, HasOAuth>>(toolDefinition: T & ToolDefinition<any, any, HasOAuth>, callback?: ToolCallback<InferToolInput<T>, InferToolOutput<T>, HasOAuth>) => this
```

## Types

### ToolDefinition

Describes a single tool: its identity, schemas, callback, annotations, metadata, and optional widget config. This is the object passed as the first argument to `server.tool()`. Both `schema` and `outputSchema` are Zod schemas, and the type parameters `TInput`, `TOutput`, and `HasOAuth` flow into the `cb` callback so its parameters and structured output are typed.

```ts theme={null}
import type { ToolDefinition } from "mcp-use/server"
```

**Fields**

> **name** `string` *required*
>
> Unique identifier for the tool. Must match the name passed to `useCallTool("name")` in widget components. Example: `"search-products"`.
>
> **title** `string`
>
> Human-readable title displayed in clients and the inspector. If omitted, `name` is used.
>
> **description** `string`
>
> LLM-facing description of what the tool does. Helps the model decide when to invoke it.
>
> **inputs** `InputDefinition[]`
>
> Deprecated. Legacy input parameter definitions. Use `schema` instead.
>
> **schema** `z.ZodTypeAny`
>
> Zod schema for input validation. Use `.describe()` on each field for model hints. Preferred over `inputs` for type safety.
>
> **outputSchema** `z.ZodTypeAny`
>
> Zod schema for structured output. Enables output type inference in `useCallTool()`; types are generated to `.mcp-use/tool-registry.d.ts` when running `mcp-use dev`.
>
> **cb** `ToolCallback\<TInput, TOutput, HasOAuth\>`
>
> Async callback that executes the tool. May be omitted here and passed as the second argument to `server.tool()` instead.
>
> **annotations** `ToolAnnotations`
>
> Behavior hints for clients (read-only, destructive, etc.). See `ToolAnnotations`.
>
> **\_meta** `Record\<string, unknown\>`
>
> Arbitrary metadata for the tool. When a `widget` config is present, `server.tool()` augments this with widget-related keys.
>
> **widget** `ToolWidgetConfig`
>
> Configuration for tools that return a widget via the `widget()` helper. Sets up widget metadata at registration time. See the per-tool widget config below.

**Signature**

```ts wrap theme={null}
interface ToolDefinition<TInput = Record<string, any>, TOutput extends Record<string, unknown> = Record<string, unknown>, HasOAuth extends boolean = false> {
  name: string
  title?: string
  description?: string
  inputs?: InputDefinition[]
  schema?: z.ZodTypeAny
  outputSchema?: z.ZodTypeAny
  cb?: ToolCallback<TInput, TOutput, HasOAuth>
  annotations?: ToolAnnotations
  _meta?: Record<string, unknown>
  widget?: ToolWidgetConfig
}
```

A definition using `schema`, `outputSchema`, and `annotations` together (lifted from the `everything` example):

```ts wrap theme={null}
import { object, error } from "mcp-use/server"
import { z } from "zod"

server.tool(
  {
    name: "calculate-stats",
    description: "Calculate statistics with validated output structure",
    schema: z.object({
      numbers: z.array(z.number()).min(1).describe("Numbers to analyze"),
    }),
    outputSchema: z.object({
      count: z.number(),
      sum: z.number(),
      mean: z.number(),
      min: z.number(),
      max: z.number(),
    }),
  },
  async ({ numbers }) => {
    if (numbers.length === 0) {
      return error("Cannot calculate statistics on empty array")
    }
    const sorted = [...numbers].sort((a, b) => a - b)
    const sum = numbers.reduce((a, b) => a + b, 0)
    return object({
      count: numbers.length,
      sum,
      mean: sum / numbers.length,
      min: sorted[0],
      max: sorted[sorted.length - 1],
    })
  },
)
```

### ToolCallback

The async handler that runs when a tool is invoked. It receives the validated input parameters as its first argument and an enhanced context object as its second, and must resolve to a tool result. The result may be a `TypedCallToolResult<TOutput>` (produced by helpers like `object()` when `outputSchema` is set) or a plain `CallToolResult` (produced by helpers like `text()`, `markdown()`, `mix()`, `error()`), since the SDK validates `structuredContent` at runtime only when present.

The context exposes LLM sampling via `ctx.sample()`, progress reporting via `ctx.reportProgress()`, elicitation via `ctx.elicit()`, authentication info via `ctx.auth` (when OAuth is configured, gated by the `HasOAuth` type parameter), the HTTP request via `ctx.req`, and all other Hono `Context` properties. The type is defined through a method-signature helper to enable bivariant parameter checking, which lets callbacks destructure optional fields without explicitly marking them optional.

```ts theme={null}
import type { ToolCallback } from "mcp-use/server"
```

**Type Parameters**

> **TInput** `Record\<string, any\>` (default: Record\<string, any>)
>
> Input parameters type, normally inferred from the definition's `schema`.
>
> **TOutput** `Record\<string, unknown\>` (default: Record\<string, unknown>)
>
> Output type that constrains `structuredContent` when `outputSchema` is defined.
>
> **HasOAuth** `boolean` (default: false)
>
> Whether OAuth is configured, which controls availability of `ctx.auth`.

**Parameters (of the callback)**

> **params** `TInput` *required*
>
> The validated tool input.
>
> **ctx** `EnhancedToolContext\<HasOAuth\>` *required*
>
> The enhanced context combining `ToolContext` (sampling, progress, elicitation) with the Hono request context.

**Returns**

> **returns** `Promise\<TypedCallToolResult\<TOutput\> | CallToolResult\>`
>
> The tool result, typically built with a response helper from `mcp-use/server`.

**Signature**

```ts wrap theme={null}
type ToolCallback<TInput = Record<string, any>, TOutput extends Record<string, unknown> = Record<string, unknown>, HasOAuth extends boolean = false> = (params: TInput, ctx: EnhancedToolContext<HasOAuth>) => Promise<TypedCallToolResult<TOutput> | CallToolResult>
```

### ToolAnnotations

Behavior hints that describe a tool to clients so they can decide how to present or guard it (for example, marking a tool read-only or warning before a destructive call). `ToolAnnotations` is re-exported from `@modelcontextprotocol/sdk/types.js` for convenience and assigned to `ToolDefinition.annotations`. All fields are optional and act as hints only; they do not change server-side behavior.

```ts theme={null}
import type { ToolAnnotations } from "mcp-use/server"
```

**Fields**

> **title** `string`
>
> Human-readable title for the tool, for display purposes.
>
> **readOnlyHint** `boolean`
>
> If true, the tool does not modify its environment.
>
> **destructiveHint** `boolean`
>
> If true, the tool may perform destructive updates (only meaningful when `readOnlyHint` is false).
>
> **idempotentHint** `boolean`
>
> If true, repeated calls with the same arguments have no additional effect (only meaningful when `readOnlyHint` is false).
>
> **openWorldHint** `boolean`
>
> If true, the tool may interact with an open, external set of entities (for example, the web).

**Usage** (lifted from the `everything` example):

```ts wrap theme={null}
import { error, text } from "mcp-use/server"
import { z } from "zod"

server.tool(
  {
    name: "delete-item",
    description: "Delete an item permanently",
    schema: z.object({
      itemId: z.string().describe("Item ID to delete"),
    }),
    annotations: {
      destructiveHint: true,
      readOnlyHint: false,
      openWorldHint: false,
    },
  },
  async ({ itemId }) => {
    if (!items.has(itemId)) {
      return error(`Item not found: ${itemId}`)
    }
    const item = items.get(itemId)
    items.delete(itemId)
    return text(`Deleted: ${item?.name}`)
  },
)
```

### InputDefinition

A single legacy input parameter definition, used by `ToolDefinition.inputs` (and by prompt args). It predates Zod schema support. Prefer a Zod `schema` with `.describe()` on the `ToolDefinition` instead, which gives full type inference and richer model guidance. `InputDefinition` remains available for cases that build parameter lists dynamically.

```ts theme={null}
import type { InputDefinition } from "mcp-use/server"
```

**Fields**

> **name** `string` *required*
>
> Parameter name (camelCase or kebab-case). Example: `"maxResults"`.
>
> **type** `"string" | "number" | "boolean" | "object" | "array"` *required*
>
> Parameter type.
>
> **description** `string`
>
> Human-readable description that helps the model understand the parameter.
>
> **required** `boolean`
>
> Whether the parameter is required. Defaults to `false`.
>
> **default** `unknown`
>
> Default value used when the parameter is omitted. Example: `10`.

**Signature**

```ts wrap theme={null}
interface InputDefinition {
  name: string
  type: "string" | "number" | "boolean" | "object" | "array"
  description?: string
  required?: boolean
  default?: unknown
}
```

### ToolWidgetConfig

The per-tool widget configuration, set as the `widget` field of a `ToolDefinition`. It configures the metadata the server emits so a tool's result renders as a widget in the inspector and in clients such as ChatGPT. When this config is present and has a `name`, `server.tool()` resolves the widget output template (`ui://widget/{name}.html`, with the server build id appended when set), attaches widget keys to the tool's `_meta`, and wraps the callback to backfill an empty text content entry.

```ts theme={null}
import type { ToolDefinition } from "mcp-use/server"
// The widget field type is ToolDefinition["widget"].
```

> [!NOTE]
>
> This shape is the type of `ToolDefinition.widget`. A separate exported `WidgetConfig` type exists in `mcp-use/server`, but that one describes a discovered widget directory (its `name`, `path`, `manifest`, and `component`) and is not the per-tool config used here.

**Fields**

> **name** `string` *required*
>
> Widget name. Must match a file in `resources/` (for example `resources/weather-display.tsx`). Example: `"weather-display"`.
>
> **invoking** `string` (default: "Loading \{name}...")
>
> Status text shown while the tool is running. Defaults to `Loading {name}...` when omitted.
>
> **invoked** `string` (default: "\{name} ready")
>
> Status text shown after the tool completes. Defaults to `{name} ready` when omitted.
>
> **widgetAccessible** `boolean` (default: true)
>
> Whether the widget can initiate tool calls (for example via `useCallTool`). Defaults to `true`.
>
> **resultCanProduceWidget** `boolean` (default: true)
>
> Whether this tool result can produce a widget. Defaults to `true`.

**Signature**

```ts wrap theme={null}
interface ToolWidgetConfig {
  name: string
  invoking?: string
  invoked?: string
  widgetAccessible?: boolean
  resultCanProduceWidget?: boolean
}
```

**Usage** (lifted from the `everything` example):

```ts wrap theme={null}
import { widget, text } from "mcp-use/server"
import { z } from "zod"

server.tool(
  {
    name: "browse-items",
    description: "Browse items with a visual widget interface",
    schema: z.object({
      query: z.string().optional().describe("Optional search query"),
    }),
    widget: {
      name: "everything-widget",
      invoking: "Loading items...",
      invoked: "Items loaded",
    },
  },
  async ({ query }) => {
    let results = Array.from(items.values())
    if (query) {
      const q = query.toLowerCase()
      results = results.filter((i) => i.name.toLowerCase().includes(q))
    }
    const categories = [...new Set(results.map((i) => i.category))]
    return widget({
      props: { items: results, categories, totalCount: results.length },
      output: text(
        `Found ${results.length} items across ${categories.length} categories`,
      ),
    })
  },
)
```

## See also

> [card] [Server](https://docs.mcp-use.com/v1/typescript/api-reference/server/mcp-server.md)
>
> The `MCPServer` class that hosts these tools, plus its constructor and lifecycle methods.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.