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

# Gemini

> Learn how to build AI agents that integrate Google's Gemini with Strata MCP servers to build AI agents that can interact with Gmail and Slack.

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/klavis-ai/klavis/blob/main/examples/google-genai/Use_Klavis_with_Gemini.ipynb)

# Gemini + Klavis AI Integration

This tutorial demonstrates how to use Google's Gemini with function calling with Klavis MCP (Model Context Protocol) servers.

## Prerequisites

Before we begin, you'll need:

> [card] [Google AI API Key](https://ai.google.dev/)
>
> Get your API key from Google AI Studio

> [card] [Klavis AI API Key](https://klavis.ai/)
>
> Get your API key from Klavis AI

## Installation

First, install the required packages:

```bash Python theme={null}
pip install google-genai klavis
```

```bash TypeScript theme={null}
npm install @google/genai klavis
```

## Full Code Examples

For complete working examples, check out the source code:

> [card] [Python Example](https://github.com/Klavis-AI/klavis/blob/main/examples/google-genai/python/main.py)

> [card] [TypeScript Example](https://github.com/Klavis-AI/klavis/blob/main/examples/google-genai/typescript/main.ts)

## Setup Environment Variables

```python Python theme={null}
import os

# Set environment variables
os.environ["GEMINI_API_KEY"] = "YOUR_GEMINI_API_KEY"  # Replace with your actual Gemini API key
os.environ["KLAVIS_API_KEY"] = "YOUR_KLAVIS_API_KEY"  # Replace with your actual Klavis API key
```

```typescript TypeScript theme={null}
import { GoogleGenAI } from '@google/genai';
import { KlavisClient, Klavis } from 'klavis';

// Set environment variables
process.env.GEMINI_API_KEY = "YOUR_GEMINI_API_KEY";  // Replace with your actual Gemini API key
process.env.KLAVIS_API_KEY = "YOUR_KLAVIS_API_KEY";  // Replace with your actual Klavis API key
```

### Step 1 - Create Strata MCP Server with Gmail and Slack

```python Python theme={null}
from klavis import Klavis
from klavis.types import McpServerName, ToolFormat
import webbrowser

klavis_client = Klavis(api_key=os.getenv("KLAVIS_API_KEY"))

response = klavis_client.mcp_server.create_strata_server(
    servers=[McpServerName.GMAIL, McpServerName.SLACK], 
    user_id="1234"
)

# Handle OAuth authorization for each services
if response.oauth_urls:
    for server_name, oauth_url in response.oauth_urls.items():
        webbrowser.open(oauth_url)
        print(f"Or please open this URL to complete {server_name} OAuth authorization: {oauth_url}")
```

```typescript TypeScript theme={null}
const klavisClient = new KlavisClient({ apiKey: process.env.KLAVIS_API_KEY });

const response = await klavisClient.mcpServer.createStrataServer({
    servers: [Klavis.McpServerName.Gmail, Klavis.McpServerName.Slack],
    userId: "1234"
});

// Handle OAuth authorization for each services
if (response.oauthUrls) {
    for (const [serverName, oauthUrl] of Object.entries(response.oauthUrls)) {
        window.open(oauthUrl);
        // Wait for user to complete OAuth
        await new Promise(resolve => {
            const input = prompt(`Press OK after completing ${serverName} OAuth authorization...`);
            resolve(input);
        });
    }
}

```

> [!NOTE]
>
> **OAuth Authorization Required**: The code above will open browser windows for each service. Click through the OAuth flow to authorize access to your accounts.

### Step 2 - Create method to use MCP Server with Claude

This method handles multiple rounds of tool calls until a final response is ready, allowing the AI to chain tool executions for complex tasks.

```python Python theme={null}
import json
from google import genai
from google.genai import types

def gemini_with_mcp_server(mcp_server_url: str, user_query: str):
    gemini_client = genai.Client(api_key=os.getenv("GEMINI_API_KEY"))

    contents = []
    contents.append(types.Content(role="user", parts=[types.Part(text=user_query)]))

    mcp_server_tools = klavis_client.mcp_server.list_tools(
        server_url=mcp_server_url,
        format=ToolFormat.GEMINI
    )

    max_iterations = 10
    iteration = 0

    while iteration < max_iterations:
        iteration += 1

        response = gemini_client.models.generate_content(
            model='gemini-2.5-flash',
            contents=contents,
            config=types.GenerateContentConfig(tools=mcp_server_tools.tools)
        )

        if response.candidates and response.candidates[0].content.parts:
            contents.append(response.candidates[0].content)

            # Check if there are function calls to execute
            has_function_calls = False
            for part in response.candidates[0].content.parts:
                if hasattr(part, 'function_call') and part.function_call:
                    has_function_calls = True
                    function_name = part.function_call.name
                    function_args = dict(part.function_call.args)

                    print(f"Calling: {function_name}, with args: {function_args}")

                    result = klavis_client.mcp_server.call_tools(
                        server_url=mcp_server_url,
                        tool_name=function_name,
                        tool_args=function_args
                    )

                    function_response_part = types.Part.from_function_response(
                        name=function_name,
                        response={'result': result.result}
                    )
                    function_response_content = types.Content(
                        role='tool',
                        parts=[function_response_part]
                    )
                    contents.append(function_response_content)

            if has_function_calls:
                continue
            else:
                return response.text
        else:
            return "No response generated."

    return "Max iterations reached without final response"
```

```typescript TypeScript theme={null}
async function geminiWithMcpServer(mcpServerUrl: string, userQuery: string) {
    const geminiClient = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });

    const contents = [];
    contents.push({ role: "user", parts: [{ text: userQuery }] });

    const mcpServerTools = await klavisClient.mcpServer.listTools({
        serverUrl: mcpServerUrl,
        format: Klavis.ToolFormat.Gemini
    });

    const maxIterations = 10;
    let iteration = 0;

    while (iteration < maxIterations) {
        iteration++;

        const response = await geminiClient.models.generateContent({
            model: 'gemini-2.5-flash',
            contents: contents,
            config: { tools: mcpServerTools.tools }
        });

        if (response.candidates && response.candidates[0].content.parts) {
            contents.push(response.candidates[0].content);

            // Check if there are function calls to execute
            let hasFunctionCalls = false;
            for (const part of response.candidates[0].content.parts) {
                if (part.functionCall) {
                    hasFunctionCalls = true;
                    const functionName = part.functionCall.name;
                    const functionArgs = part.functionCall.args;

                    console.log(`🔧 Calling: ${functionName}, with args:`, functionArgs);

                    const result = await klavisClient.mcpServer.callTools({
                        serverUrl: mcpServerUrl,
                        toolName: functionName,
                        toolArgs: functionArgs
                    });

                    const functionResponsePart = {
                        functionResponse: {
                            name: functionName,
                            response: { result: result.result }
                        }
                    };
                    const functionResponseContent = {
                        role: 'tool',
                        parts: [functionResponsePart]
                    };
                    contents.push(functionResponseContent);
                }
            }

            if (hasFunctionCalls) {
                continue;
            } else {
                return response.text;
            }
        } else {
            return "No response generated.";
        }
    }

    return "Max iterations reached without final response";
}
```

### Step 3 - Run!

```python Python theme={null}
result = gemini_with_mcp_server(
    mcp_server_url=response.strata_server_url,
    user_query="Check my latest 5 gmails and summarize them in a Slack message to #engineering"
)

print(f"\n🤖 Final Response: {result}")
```

```typescript TypeScript theme={null}
const result = await geminiWithMcpServer(
    response.strataServerUrl,
    "Check my latest 5 gmails and summarize them in a Slack message to #engineering"
);

console.log(`\n🤖 Final Response: ${result}`);
```

> [!TIP]
>
> Perfect! You've integrated Gemini with Klavis MCP servers.

## Next Steps

> [card] Explore More MCP Servers
>
> Try other available servers like Slack, Notion, GitHub, etc.

> [card] Multimodal Workflows
>
> Build workflows that combine text, images, and other media

> [card] Production Deployment
>
> Scale these patterns for production applications

> [card] Custom Integrations
>
> Build custom MCP servers for your specific needs

## Useful Resources

* [Google AI Documentation](https://ai.google.dev/)
* [Gemini API Reference](https://ai.google.dev/api)
* [Klavis AI Documentation](https://www.klavis.ai/docs/)
* [MCP Protocol Specification](https://modelcontextprotocol.io/)
* [Klavis MCP Servers](https://www.klavis.ai/docs/mcp-server)

**Happy building!** 🚀


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