Tools

Tools are functions that your LLM can actively call and decides when to use based on user requests. They enable AI models to perform actions such as writing to databases, calling external APIs, modifying files, or triggering other logic.

By default, xmcp detects files under the /src/tools/ directory and registers them as tools, but you can specify a custom directory if you prefer. The directory to use can be configured in the xmcp.config.ts file.

A tool file consists of three main exports:

  • Default: The tool handler function.
  • Schema (optional): The input parameters using Zod schemas.
  • Metadata (optional): The tool's identity and behavior hints. If omitted, the name is inferred from the file name and the description defaults to a placeholder.
src/tools/greet.ts

If you're returning a string or number only, you can shortcut the return value to be the string or number directly.

We encourage to use this shortcut for readability, and restrict the usage of the content array type only for complex responses, like images, audio or videos.

Schema Definition

The schema defines your tool's input parameters using Zod. Use .describe() on each parameter to help LLMs understand how to use your tool correctly.

src/tools/create-user.ts

Type Inference

The InferSchema utility automatically infers TypeScript types from your Zod schema, giving you full type safety without manual type definitions:

Clear descriptions are crucial for LLM tool discovery. For comprehensive Zod validation options (regex patterns, constraints, transformations), see the Zod documentation.

Metadata

The metadata export defines your tool's identity and provides behavioral hints to LLMs and clients.

src/tools/delete-user.ts

Core Properties

name (required)

  • Unique identifier for the tool
  • Defaults to the filename if not provided
  • Use kebab-case (e.g., get-user-profile)

description (required)

  • Clear explanation of what the tool does
  • Defaults to placeholder if not provided
  • Critical for LLM tool discovery and selection

Annotations

Behavioral hints that help LLMs and UIs understand how to use your tool:

These hints are advisory only. LLMs may use them to make better decisions about when and how to call your tools, but they don't enforce any behavior.

OpenAI Metadata

For ChatGPT widget integration, add OpenAI-specific metadata under _meta.openai:

Tool-specific properties:

  • widgetAccessible - Enable widget-to-tool communication (required for widgets)
  • toolInvocation.invoking - Message shown while executing (≤64 chars)
  • toolInvocation.invoked - Message shown after completion (≤64 chars)
  • outputTemplate - Custom widget URI (auto-generated if not provided)

Resource-specific properties:

  • widgetDescription - Human-readable widget summary
  • widgetPrefersBorder - UI rendering hint for borders
  • widgetCSP - Content Security Policy for external resources
  • widgetDomain - Optional dedicated subdomain
  • widgetState - Initial state object passed to widget

Handler Types

Tools support three types of handlers, each suited for different use cases:

TypeBest ForReturns
StandardData queries, calculations, API callsUnstructured or structured content
Template LiteralSimple widgets with external scriptsHTML string
React ComponentInteractive, stateful widgetsReact component

1. Standard Handlers

Standard handlers are functions that return text, structured content, or simple data. This is the default approach for most tools.

When to use:

  • Performing calculations or data transformations
  • Calling external APIs and returning results
  • Querying databases
  • Any task that returns text or structured data without UI interaction
src/tools/calculate.ts

2. Template Literal Handlers

Return HTML directly to create interactive widgets in ChatGPT. When you return HTML and include OpenAI metadata, xmcp automatically generates a widget resource.

To enable widgets, you need to add the _meta.openai configuration in your metadata with widgetAccessible: true.

src/tools/show-chart.ts

3. React Component Handlers

Return React components for interactive, composable widgets. xmcp renders the component to HTML and generates a widget resource automatically.

To enable widgets, you need to add the _meta.openai configuration in your metadata with widgetAccessible: true.

src/tools/interactive-todo.tsx

Setup Requirements:

  1. Use .tsx file extension for React component tools
  2. Install React dependencies: npm install react react-dom
  3. Configure tsconfig.json:

Return Values

Tools support multiple return formats depending on your needs:

Simple Values

Return strings or numbers directly - xmcp automatically wraps them in the proper format:

Content Array

Return an object with a content array for rich media responses:

Supported content types:

  • text - Plain text content
  • image - Base64-encoded images with mimeType
  • audio - Base64-encoded audio with mimeType
  • resource_link - Links to MCP resources

Structured Outputs

Return structured data using the structuredContent property:

Combined Response

Return both content and structuredContent for backwards compatibility. If the client cannot process structured outputs, it will fallback to content.

On this page

One framework to rule them all

    Tools | xmcp Documentation