Skip to main content
Open In Colab

Prerequisites

Before we begin, you’ll need:

Anthropic API Key

Get your API key from Anthropic Console

Klavis AI API Key

Get your API key from Klavis AI

Installation

First, install the required packages:
pip install anthropic klavis
npm install @anthropic-ai/sdk klavis

Setup Environment Variables

import os

os.environ["ANTHROPIC_API_KEY"] = "YOUR_ANTHROPIC_API_KEY"  # Replace with your actual Anthropic API key
os.environ["KLAVIS_API_KEY"] = "YOUR_KLAVIS_API_KEY"  # Replace with your actual Klavis API key
import Anthropic from '@anthropic-ai/sdk';
import { KlavisClient, Klavis } from 'klavis';

// Set environment variables
process.env.ANTHROPIC_API_KEY = "YOUR_ANTHROPIC_API_KEY";  // Replace with your actual Anthropic 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

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}")
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);
        });
    }
}

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.
import json
from anthropic import Anthropic

def claude_with_mcp_server(mcp_server_url: str, user_query: str):
    claude_client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))

    messages = [
        {"role": "user", "content": f"{user_query}"}
    ]

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

    max_iterations = 10
    iteration = 0

    while iteration < max_iterations:
        iteration += 1

        response = claude_client.messages.create(
            model="claude-sonnet-4-5-20250929",
            max_tokens=4000,
            system="You are a helpful assistant. Use the available tools to answer the user's question.",
            messages=messages,
            tools=mcp_server_tools.tools
        )

        messages.append({"role": "assistant", "content": response.content})

        if response.stop_reason == "tool_use":
            tool_results = []

            for content_block in response.content:
                if content_block.type == "tool_use":
                    function_name = content_block.name
                    function_args = content_block.input

                    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
                    )

                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": content_block.id,
                        "content": str(result)
                    })

            messages.append({"role": "user", "content": tool_results})
            continue
        else:
            return response.content[0].text

    return "Max iterations reached without final response"
async function claudeWithMcpServer(mcpServerUrl: string, userQuery: string) {
    const claudeClient = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

    const messages = [
        { role: "user", content: userQuery }
    ];

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

    const maxIterations = 10;
    let iteration = 0;

    while (iteration < maxIterations) {
        iteration++;

        const response = await claudeClient.messages.create({
            model: "claude-sonnet-4-5-20250929",
            max_tokens: 4000,
            system: "You are a helpful assistant. Use the available tools to answer the user's question.",
            messages: messages,
            tools: mcpServerTools.tools
        });

        messages.push({ role: "assistant", content: response.content });

        if (response.stop_reason === "tool_use") {
            const toolResults = [];

            for (const contentBlock of response.content) {
                if (contentBlock.type === "tool_use") {
                    const functionName = contentBlock.name;
                    const functionArgs = contentBlock.input;

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

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

                    toolResults.push({
                        type: "tool_result",
                        tool_use_id: contentBlock.id,
                        content: JSON.stringify(result)
                    });
                }
            }

            messages.push({ role: "user", content: toolResults });
            continue;
        } else {
            return response.content[0].text;
        }
    }

    return "Max iterations reached without final response";
}

Step 3 - Run!

result = claude_with_mcp_server(
    mcp_server_url=response.strata_server_url, 
    user_query="Check my latest 5 emails and summarize them in a Slack message to #general"
)

print(f"\n🤖 Final Response: {result}")
result = await claudeWithMcpServer(
    response.strataServerUrl, 
    "Check my latest emails and summarize them in a Slack message to #updates"
);

console.log(`\n🤖 Final Response: ${result}`);
Perfect! You’ve integrated Claude with Klavis MCP servers.

Next Steps

Integrations

Explore available MCP servers

API Reference

REST endpoints and schemas

Useful Resources

Happy building! 🚀