---
title: "Tools | Micdrop"
description: "The Agent system supports adding and removing custom tools to extend its capabilities."
url: "https://micdrop.dev/docs/server/tools"
---

*   [Getting Started](/docs/getting-started)
*   [Client (Browser)](/docs/client)
    
    *   [Installation](/docs/client/installation)
    *   [React Hooks](/docs/client/react-hooks)
    *   [Start/Stop Call](/docs/client/start-stop-call)
    *   [Pause/Resume Call](/docs/client/pause-resume-call)
    *   [Mute/Unmute Call](/docs/client/mute-unmute-call)
    *   [Call State](/docs/client/call-state)
    *   [Display Conversation Messages](/docs/client/display-conversation-messages)
    *   [Handling Tool Calls](/docs/client/handling-tool-calls)
    *   [Device Management](/docs/client/devices-management)
    *   [Voice Activity Detection (VAD)](/docs/client/vad)
    *   [Turn Detection](/docs/client/turn-detection)
    *   [Reducing Latency](/docs/client/latency)
    *   [Error Handling](/docs/client/error-handling)
    *   Utility Classes
        
        *   [Mic](/docs/client/utility-classes/mic)
        *   [MicdropClient](/docs/client/utility-classes/micdrop-client)
        *   [MicRecorder](/docs/client/utility-classes/mic-recorder)
        *   [Speaker](/docs/client/utility-classes/speaker)
        
    
*   [Client (React Native)](/docs/react-native)
    
    *   [Installation](/docs/react-native/installation)
    *   [Hooks and Call State](/docs/react-native/hooks)
    *   [Audio Output and Devices](/docs/react-native/audio-output)
    *   [Voice Activity Detection (VAD)](/docs/react-native/vad)
    *   [Turn Detection](/docs/react-native/turn-detection)
    *   [Using Another Audio Library](/docs/react-native/custom-audio)
    
*   [Server (Node.js)](/docs/server)
    
    *   [Installation](/docs/server/installation)
    *   [With Fastify](/docs/server/with-fastify)
    *   [With NestJS](/docs/server/with-nestjs)
    *   [Auth and Parameters](/docs/server/auth-and-parameters)
    *   [First Message](/docs/server/first-message)
    *   [Dictation and Text-Only Calls](/docs/server/dictation)
    *   [Partial Messages](/docs/server/partial-messages)
    *   [Save Messages](/docs/server/save-messages)
    *   [Resume a Conversation](/docs/server/resume-conversation)
    *   [Recording Audio](/docs/server/recording-audio)
    *   [Error Handling](/docs/server/error-handling)
    *   [Tools](/docs/server/tools)
    *   [Extract Value from Answer](/docs/server/extract)
    *   [Auto End Call](/docs/server/auto-end-call)
    *   [Semantic Turn Detection](/docs/server/semantic-turn-detection)
    *   [Noise Filtering](/docs/server/noise-filtering)
    *   [Micdrop Protocol](/docs/server/protocol)
    
*   [AI Integrations](/docs/ai-integration)
    
    *   Provided Integrations
        
        *   [AI SDK](/docs/ai-integration/provided-integrations/ai-sdk)
        *   [Cartesia](/docs/ai-integration/provided-integrations/cartesia)
        *   [ElevenLabs](/docs/ai-integration/provided-integrations/elevenlabs)
        *   [Gladia](/docs/ai-integration/provided-integrations/gladia)
        *   [Gradium](/docs/ai-integration/provided-integrations/gradium)
        *   [Kokoro](/docs/ai-integration/provided-integrations/kokoro)
        *   [Mistral](/docs/ai-integration/provided-integrations/mistral)
        *   [OpenAI](/docs/ai-integration/provided-integrations/openai)
        *   [Piper](/docs/ai-integration/provided-integrations/piper)
        *   [Pocket TTS](/docs/ai-integration/provided-integrations/pocket-tts)
        *   [Qwen3-TTS](/docs/ai-integration/provided-integrations/qwen-tts)
        *   [Whisper](/docs/ai-integration/provided-integrations/whisper)
        
    *   Custom Integrations
        
        *   [Agent (LLM)](/docs/ai-integration/custom-integrations/custom-agent)
        *   [Speech-to-Text (STT)](/docs/ai-integration/custom-integrations/custom-stt)
        *   [Text-to-Speech (TTS)](/docs/ai-integration/custom-integrations/custom-tts)
        
    *   Fallback Strategies
        
        *   [FallbackAgent](/docs/ai-integration/fallback-strategies/agent-fallback)
        *   [FallbackSTT](/docs/ai-integration/fallback-strategies/stt-fallback)
        *   [FallbackTTS](/docs/ai-integration/fallback-strategies/tts-fallback)
        
    *   [Local Models](/docs/ai-integration/local-models)
        
        *   [Local LLM](/docs/ai-integration/local-models/agent)
        *   [Local STT](/docs/ai-integration/local-models/speech-to-text)
        *   [Local TTS](/docs/ai-integration/local-models/text-to-speech)
        *   [Latency and Memory](/docs/ai-integration/local-models/performance)
        *   [Explorations](/docs/ai-integration/local-models/explorations)
            
            *   [MiniCPM5-2B](/docs/ai-integration/local-models/explorations/minicpm)
            *   [Mistral 7B](/docs/ai-integration/local-models/explorations/mistral-7b)
            *   [Voxtral Mini 3B](/docs/ai-integration/local-models/explorations/voxtral-stt)
            *   [Voxtral TTS 4B](/docs/ai-integration/local-models/explorations/voxtral-tts)
            *   [AuK and AuK-Flash](/docs/ai-integration/local-models/explorations/auk)
            
        
    *   [IA Vocale Souveraine 🇫🇷🇪🇺](/docs/ai-integration/sovereign-voice-ai)
    
*   [Migration](/docs/migration)
    
    *   [Upgrade to v3](/docs/migration/v3)
    

[Micdrop](/) › [Documentation](/docs/getting-started) › [Server (Node.js)](/docs/server)

# Tools

The Agent system supports adding and removing custom tools to extend its capabilities.

## Adding Tools

Use `addTool(tool: Tool)` to add custom functions that the agent can call during conversations:

```
import { z } from 'zod'import { OpenaiAgent } from '@micdrop/openai'import { MicdropServer } from '@micdrop/server'
const agent = new OpenaiAgent({  apiKey: process.env.OPENAI_API_KEY || '',  systemPrompt: 'You are a helpful assistant that can manage user information.',})
// Add a simple tool without parametersagent.addTool({  name: 'get_time',  description: 'Get the current time',  execute: () => new Date().toLocaleTimeString(),})
// Add a tool with typed parameters using Zod schemaagent.addTool({  name: 'set_user_info',  description: 'Save user information to the database',  inputSchema: z.object({    city: z.string().describe('City'),    jobTitle: z.string().describe('Job title').nullable(),    experience: z      .number()      .describe('Number of years of experience of the user')      .nullable(),  }),  execute: ({ city, jobTitle, experience }) => {    // Your implementation here    console.log('Saving user:', { city, jobTitle, experience })    return { success: true, message: 'User information saved' }  },})
// Add a tool that returns data for the conversationagent.addTool({  name: 'search_database',  description: 'Search for items in the database',  parameters: z.object({    query: z.string().describe('Search query'),    limit: z.number().default(10).describe('Maximum number of results'),  }),  execute: async ({ query, limit }) => {    // Your search implementation    const results = await searchDatabase(query, limit)    return { results, total: results.length }  },  emitOutput: true, // Enable tool call events})
// Add a tool that can interact with the server (e.g., delayed responses)function addTools(server: MicdropServer, agent: OpenaiAgent) {  agent.addTool({    name: 'say_something_later',    description:      'Say something later (can be used as an alarm clock or reminder)',    inputSchema: z.object({      message: z.string().describe('The message to say'),      delay: z.number().describe('The delay in seconds'),    }),    execute: async ({ message, delay }) => {      setTimeout(() => {        agent.addAssistantMessage(message)        server.speak(message)      }, delay * 1000)      return { success: true }    },  })}
```

## Tool Options

Option

Type

Default

Description

`name`

`string`

Required

Unique name for the tool

`description`

`string`

Required

Description of what the tool does

`inputSchema`

`z.ZodObject`

Optional

Zod schema for parameter validation

`execute`

`(input, agent) => any | Promise<any>`

Required

Function to execute when tool is called

`skipAnswer`

`boolean`

`false`

Skip assistant response after tool call

`emitOutput`

`boolean`

`false`

Emit ToolCall events for monitoring

💡 Tip

If `emitOutput` is true, the tool call output is also sent to the client and available with the `ToolCall` event.

## The `agent` context

The `execute` function receives the executing agent as a second argument. Use it instead of capturing a specific agent in a closure, so tools stay portable and can be shared between agents (this is what lets [FallbackAgent](/docs/ai-integration/fallback-strategies/agent-fallback) hand the same tools to every provider it switches to):

```
agent.addTool({  name: 'count_messages',  description: 'Count the messages exchanged so far',  execute: (input, agent) => ({ count: agent.conversation.length }),})
```

The first `input` argument is always present; the `agent` argument is optional, so simple tools can keep ignoring it. The built-in `autoEndCall`, `autoSemanticTurn` and `autoIgnoreUserNoise` tools use this same mechanism internally.

## Removing Tools

Use `removeTool(name: string)` to remove tools by name:

```
// Remove a specific toolagent.removeTool('get_time')
```

## Getting Tools

Use `getTool(name: string)` to retrieve a tool by name:

```
// Get a specific tool (undefined if not found)const tool = agent.getTool('get_time')
```

## Tool Call Events

Monitor tool executions in real-time by enabling the `emitOutput` option and listening for `ToolCall` events:

```
import { OpenaiAgent } from '@micdrop/openai'
const agent = new OpenaiAgent({  apiKey: process.env.OPENAI_API_KEY || '',  systemPrompt: 'You are a helpful assistant with access to tools.',})
// Add tool with emitOutput enabledagent.addTool({  name: 'save_user_data',  description: 'Save user data to the system',  inputSchema: z.object({    name: z.string(),    email: z.string().email(),  }),  emitOutput: true, // Enable events for this tool})
// Listen for tool call eventagent.on('ToolCall', (toolCall) => {  console.log(`Tool called: ${toolCall.name}`)  console.log('Parameters:', toolCall.parameters)  console.log('Output:', toolCall.output)
  if (toolCall.name === 'save_user_data') {    // Sync data to external systems    syncToDatabase(toolCall.output)  }})
```

💡 Tip

It may be easier and safer to use tool `execute` option if you don’t need to emit the output to the client.

## Tool Call Event Structure

The `ToolCall` event provides complete information about tool execution:

```
interface ToolCall {  name: string // Tool name that was called  parameters: any // Parameters passed to the tool  output: any // Result returned by the tool execute function}
```

[Previous← Error Handling](/docs/server/error-handling)[NextExtract Value from Answer →](/docs/server/extract)

On this page

*   [Adding Tools](#adding-tools)
*   [Tool Options](#tool-options)
*   [The agent context](#the-agent-context)
*   [Removing Tools](#removing-tools)
*   [Getting Tools](#getting-tools)
*   [Tool Call Events](#tool-call-events)
*   [Tool Call Event Structure](#tool-call-event-structure)
