---
title: "Gemini | Micdrop"
description: "Run a voice agent on Google Gemini from your Node server: Gemini models as the agent, Gemini Transcribe and Gemini TTS, or Gemini Live for the whole call."
url: "https://micdrop.dev/docs/ai-integration/provided-integrations/gemini"
---

*   [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)
    *   [Realtime Models](/docs/server/realtime)
    *   [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)
        *   [Gemini](/docs/ai-integration/provided-integrations/gemini)
        *   [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) › [AI Integrations](/docs/ai-integration) › Provided Integrations

# Gemini

Google Gemini implementation for [@micdrop/server](/docs/server).

This package provides an agent, a speech-to-text and a text-to-speech running on the Gemini API. Each one can be combined with any other provider. `GeminiLive` goes further: it is a [realtime model](/docs/server/realtime) that hears the user and answers with its own voice, in place of the three.

## Installation

Terminal window

```
npm install @micdrop/gemini
```

## Gemini Agent

Answers with Gemini models through the Interactions API. The conversation is sent on every turn, nothing is stored on Google’s side.

### Usage with MicdropServer

```
import { GeminiAgent } from '@micdrop/gemini'import { MicdropServer } from '@micdrop/server'
const agent = new GeminiAgent({  apiKey: process.env.GEMINI_API_KEY || '',  model: 'gemini-3.8-flash', // Default model  thinkingLevel: 'low', // Optional, the lower the sooner the first word  systemPrompt: 'You are a helpful assistant',
  // Advanced features (optional)  autoEndCall: true, // Automatically end call when user requests  autoSemanticTurn: true, // Handle incomplete sentences  autoIgnoreUserNoise: true, // Filter out meaningless sounds})
new MicdropServer(socket, {  agent,  // ... other options})
```

### Usage without MicdropServer

```
import { GeminiAgent } from '@micdrop/gemini'
const agent = new GeminiAgent({  apiKey: process.env.GEMINI_API_KEY || '',  systemPrompt: 'You are a helpful assistant',})
agent.on('Message', (message) => console.log('Message:', message))
agent.addUserMessage('Hello, what can you do?')
// The answer is a text stream, written as the model generates itagent.answer().on('data', (chunk) => process.stdout.write(chunk))
```

### Events

Event

Payload

Description

`Message`

`MicdropConversationItem`

A message, a tool call or a tool result was added to the conversation.

`ToolCall`

`MicdropToolCall`

A tool declared with `emitOutput` ran, with its parameters and output.

`CancelLastUserMessage`

none

The last user message was dropped because it carried no intent.

`SkipAnswer`

none

The agent stays silent and waits for the user to finish their sentence.

`EndCall`

none

The agent decided that the call is over.

`Failed`

none

The agent gave up generating an answer after its retries.

See the [Agent interface](/docs/ai-integration/custom-integrations/custom-agent) for the full contract.

### Options

Option

Type

Default

Description

`apiKey`

`string`

Required\*

Your Gemini API key (required if `genai` not provided)

`genai`

`GoogleGenAI`

Optional

Client of `@google/genai` (alternative to `apiKey`)

`model`

`string`

`'gemini-3.8-flash'`

Model to use (`gemini-3.8-flash`, `gemini-3.5-flash-lite`…)

`thinkingLevel`

`string`

Model default

How long the model thinks (`low`, `medium`, `high`)

`settings`

`Record<string, unknown>`

`undefined`

Other generation settings, such as `temperature`

`maxRetry`

`number`

`3`

Attempts after a failed request

`retryDelay`

`number`

`1000`

Delay between two attempts, in milliseconds

`maxSteps`

`number`

`5`

Requests in a row when the model keeps calling tools

For a voice call, the delay before the first word matters most. `gemini-3.5-flash-lite` answers in about a second, and `gemini-3.8-flash`, more capable, takes several seconds even with `thinkingLevel: 'low'`.

## Gemini STT (Speech-to-Text)

Streams the voice of the user to Gemini Transcribe over the Live API, and emits the transcript of each utterance a fraction of a second after it ends.

### Usage with MicdropServer

```
import { GeminiSTT } from '@micdrop/gemini'import { MicdropServer } from '@micdrop/server'
const stt = new GeminiSTT({  apiKey: process.env.GEMINI_API_KEY || '',  language: 'en-US', // Optional, detected when left out  vocabulary: ['Micdrop'], // Optional, words to recognize})
new MicdropServer(socket, {  stt,  // ... other options})
```

### Usage without MicdropServer

```
import { GeminiSTT } from '@micdrop/gemini'import { createReadStream } from 'fs'
const stt = new GeminiSTT({ apiKey: process.env.GEMINI_API_KEY || '' })
stt.on('Transcript', (transcript) => console.log('Transcript:', transcript))
// Audio is raw PCM, 16 bits, 16 kHz, monostt.transcribe(createReadStream('speech.pcm'))
```

### Events

Event

Payload

Description

`Transcript`

`string`

The transcript of an utterance, empty when nothing was understood.

`Failed`

`Buffer[]`

The connection could not be restored, with the audio of the utterance left.

See the [STT interface](/docs/ai-integration/custom-integrations/custom-stt) for the full contract.

### Options

Option

Type

Default

Description

`apiKey`

`string`

Required

Your Gemini API key

`model`

`string`

`'gemini-3.5-transcribe-live'`

Transcription model

`language`

`string`

`undefined`

Language of the user, as a BCP-47 code like `fr-FR`

`vocabulary`

`string[]`

`undefined`

Words to recognize, up to 1,000

`mode`

`'SMART' | 'VERBATIM'`

Model default

Cleans up hesitations, or keeps every word as said

`transcriptionTimeout`

`number`

`4000`

How long to wait for a transcript, in milliseconds

`connectionTimeout`

`number`

`5000`

Time to open the connection, in milliseconds

`retryDelay`

`number`

`1000`

Delay before reconnecting, in milliseconds

`maxRetry`

`number`

`3`

Reconnection attempts before giving up

## Gemini TTS (Text-to-Speech)

Gives the answers a Gemini voice. The model reads a whole text at once, so the answer is cut into sentences, and the audio of each one is sent as the model streams it.

### Usage with MicdropServer

```
import { GeminiTTS } from '@micdrop/gemini'import { MicdropServer } from '@micdrop/server'
const tts = new GeminiTTS({  apiKey: process.env.GEMINI_API_KEY || '',  model: 'gemini-2.5-flash-preview-tts', // Default model  voice: 'Kore', // Default voice
  // Direction put before each sentence (optional)  instructions: 'Say in a calm and friendly tone',})
new MicdropServer(socket, {  tts,  // ... other options})
```

### Usage without MicdropServer

```
import { GeminiTTS } from '@micdrop/gemini'import { Readable } from 'stream'
const tts = new GeminiTTS({ apiKey: process.env.GEMINI_API_KEY || '' })
// Audio is raw PCM, 16 bits, 16 kHz, monotts.on('Audio', (chunk) => console.log('Audio:', chunk.length, 'bytes'))tts.on('Failed', (texts) => console.error('Failed:', texts))
tts.speak(Readable.from(['Hello! ', 'What can I do for you?']))
```

### Events

Event

Payload

Description

`Audio`

`Buffer`

A chunk of audio, PCM 16 bits, 16 kHz, mono, ready to be played.

`Failed`

`string[]`

Synthesis gave up after an error, with the text that stayed unspoken.

See the [TTS interface](/docs/ai-integration/custom-integrations/custom-tts) for the full contract.

### Options

Option

Type

Default

Description

`apiKey`

`string`

Required\*

Your Gemini API key (required if `genai` not provided)

`genai`

`GoogleGenAI`

Optional

Client of `@google/genai` (alternative to `apiKey`)

`model`

`string`

`'gemini-2.5-flash-preview-tts'`

Speech model to use

`voice`

`string`

`'Kore'`

One of the 30 prebuilt voices, such as `Puck` or `Aoede`

`instructions`

`string`

`undefined`

How to say the text, such as `Say cheerfully`

`maxRetry`

`number`

`2`

Attempts after Gemini blocked a sentence by mistake

The voice follows the language of the text, in about ninety languages.

Gemini now and then blocks an ordinary sentence as if its content were forbidden, then accepts the very same sentence on the next request. `GeminiTTS` asks again, up to `maxRetry` times, as long as no audio of that sentence has been played.

`gemini-3.1-flash-tts-preview` starts speaking after about a second, then streams the rest slower than it is spoken, which leaves gaps in a long sentence. `gemini-2.5-flash-preview-tts` takes about three seconds and sends each sentence whole, so it plays without a gap.

## Gemini Live

A [realtime model](/docs/server/realtime) running on the Gemini Live API. It hears the user and answers with its own voice, in place of a speech to text, an agent and a text to speech.

### Usage with MicdropServer

```
import { GeminiLive } from '@micdrop/gemini'import { MicdropServer } from '@micdrop/server'
const realtime = new GeminiLive({  apiKey: process.env.GEMINI_API_KEY || '',  model: 'gemini-3.8-live', // Default model  systemPrompt: 'You are a helpful assistant',  voice: 'Kore', // Optional, a prebuilt voice
  // Advanced features (optional)  autoEndCall: true, // Automatically end call when user requests})
new MicdropServer(socket, {  realtime,  generateFirstMessage: true,})
```

The Micdrop client detects when the user speaks, so the automatic activity detection of Gemini is turned off. Each turn is sent between an `activityStart` and an `activityEnd`, and the model answers once the turn ends.

### Tools

Tools are added as with any agent, and run on your server:

```
import { z } from 'zod'
realtime.addTool({  name: 'get_weather',  description: 'Get the current weather in a city',  inputSchema: z.object({ city: z.string() }),  execute: async ({ city }) => fetchWeather(city),})
```

Gemini ends its turn when it calls a tool, then speaks about the result once it has it. The client keeps waiting for the answer in between. A tool declared with `skipAnswer` gives its result to the model silently.

Gemini reads the tools when the session opens, so add them right after creating the model, before the connection is established.

### Events

`GeminiLive` emits the events of an agent, and two of its own.

Event

Payload

Description

`Audio`

`Buffer`

A chunk of the voice of the model, PCM 16 bits, 16 kHz, mono.

`PartialMessage`

`string`

The transcript of the answer so far.

`Message`

`MicdropConversationItem`

A message, a tool call or a tool result was added to the conversation.

`ToolCall`

`MicdropToolCall`

A tool declared with `emitOutput` ran, with its parameters and output.

`CancelLastUserMessage`

none

The last user message was dropped because it carried no intent.

`SkipAnswer`

none

The model gave no spoken answer.

`EndCall`

none

The model decided that the call is over.

`Failed`

none

The connection could not be restored after its retries.

### Options

Option

Type

Default

Description

`apiKey`

`string`

Required

Your Gemini API key

`systemPrompt`

`string`

Required

Instructions of the model

`model`

`string`

`'gemini-3.8-live'`

Live model to use

`voice`

`string`

`undefined`

Name of a prebuilt voice, such as `Kore` or `Puck`

`thinkingLevel`

`string`

`undefined`

Reasoning level, required by `gemini-3.8-live-extended-thinking`

`autoEndCall`

`boolean | string`

`false`

Ends the call when the user asks for it

`autoSemanticTurn`

`boolean | string`

`false`

Lets the model wait silently when the user did not finish their sentence

`autoIgnoreUserNoise`

`boolean | string`

`false`

Drops the turn when it carries no meaning

`connectionTimeout`

`number`

`5000`

Time to open the connection, in milliseconds

`retryDelay`

`number`

`1000`

Delay before reconnecting, in milliseconds

`maxRetry`

`number`

`3`

Reconnection attempts before giving up

`gemini-3.8-live-extended-thinking` reasons before answering, for questions that take several steps. It refuses to start without a `thinkingLevel`, such as `'low'`, while `gemini-3.8-live` refuses any.

### Long calls

A Gemini connection lasts a few minutes. `GeminiLive` keeps the handle Gemini sends to resume the session, and moves to a new connection at the first silence once Gemini announces the end of the current one. Context window compression is on, which lifts the fifteen minutes limit of an audio session.

[Previous← ElevenLabs](/docs/ai-integration/provided-integrations/elevenlabs)[NextGladia →](/docs/ai-integration/provided-integrations/gladia)

On this page

*   [Installation](#installation)
*   [Gemini Agent](#gemini-agent)
*   [Usage with MicdropServer](#usage-with-micdropserver)
*   [Usage without MicdropServer](#usage-without-micdropserver)
*   [Events](#events)
*   [Options](#options)
*   [Gemini STT (Speech-to-Text)](#gemini-stt-speech-to-text)
*   [Usage with MicdropServer](#usage-with-micdropserver-1)
*   [Usage without MicdropServer](#usage-without-micdropserver-1)
*   [Events](#events-1)
*   [Options](#options-1)
*   [Gemini TTS (Text-to-Speech)](#gemini-tts-text-to-speech)
*   [Usage with MicdropServer](#usage-with-micdropserver-2)
*   [Usage without MicdropServer](#usage-without-micdropserver-2)
*   [Events](#events-2)
*   [Options](#options-2)
*   [Gemini Live](#gemini-live)
*   [Usage with MicdropServer](#usage-with-micdropserver-3)
*   [Tools](#tools)
*   [Events](#events-3)
*   [Options](#options-3)
*   [Long calls](#long-calls)
