> ## 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.

# OpenAI

> This tutorial demonstrates how to integrate OpenAI's function calling capabilities with Strata MCP servers to build AI agents that can interact with Gmail and Slack.

## Prerequisites

Before we begin, you'll need [OpenAI API key](\(https://platform.openai.com/api-keys\)) and [Klavis API key](https://www.klavis.ai/home/api-keys).

## Installation

First, install the required packages:

<CodeGroup>
  ```bash Python theme={null}
  pip install openai klavis
  ```

  ```bash TypeScript theme={null}
  npm install openai klavis
  ```
</CodeGroup>

## Setup Environment Variables

<CodeGroup>
  ```python Python theme={null}
  import os

  os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY"  # Replace
  os.environ["KLAVIS_API_KEY"] = "YOUR_KLAVIS_API_KEY"  # Replace
  ```

  ```typescript TypeScript theme={null}
  import OpenAI from 'openai';
  import { KlavisClient, Klavis } from 'klavis';

  // Set environment variables
  process.env.OPENAI_API_KEY = "YOUR_OPENAI_API_KEY";  // Replace with your actual OpenAI API key
  process.env.KLAVIS_API_KEY = "YOUR_KLAVIS_API_KEY";   // Replace with your actual Klavis API key
  ```
</CodeGroup>

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

<CodeGroup>
  ```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);
          });
      }
  }

  ```
</CodeGroup>

<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.
</Note>

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

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

<CodeGroup>
  ```python Python theme={null}
  import json
  from openai import OpenAI

  def openai_with_mcp_server(mcp_server_url: str, user_query: str):
      openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

      messages = [
          {"role": "system", "content": "You are a helpful assistant. Use the available tools to answer the user's question."},
          {"role": "user", "content": f"{user_query}"}
      ]
      
      tools_info = klavis_client.mcp_server.list_tools(
          server_url=mcp_server_url,
          format=ToolFormat.OPENAI
      )
      
      max_iterations = 10
      iteration = 0
      
      while iteration < max_iterations:
          iteration += 1
          
          response = openai_client.chat.completions.create(
              model="gpt-4o-mini",
              messages=messages,
              tools=tools_info.tools,
              tool_choice="auto",
          )
          
          assistant_message = response.choices[0].message
          
          if assistant_message.tool_calls:
              messages.append({
                  "role": "assistant",
                  "content": assistant_message.content,
                  "tool_calls": [
                      {
                          "id": tc.id,
                          "type": "function",
                          "function": {
                              "name": tc.function.name,
                              "arguments": tc.function.arguments
                          }
                      }
                      for tc in assistant_message.tool_calls
                  ]
              })
              
              for tool_call in assistant_message.tool_calls:
                  tool_name = tool_call.function.name
                  tool_args = json.loads(tool_call.function.arguments)
                  
                  print(f"Calling: {tool_name}")
                  print(f"Arguments: {json.dumps(tool_args, indent=2)}")
                  
                  function_result = klavis_client.mcp_server.call_tools(
                      server_url=mcp_server_url,
                      tool_name=tool_name,
                      tool_args=tool_args
                  )
                                  
                  messages.append({
                      "role": "tool",
                      "tool_call_id": tool_call.id,
                      "content": str(function_result)
                  })
              continue
          else:
              messages.append({"role": "assistant", "content": assistant_message.content})
              return assistant_message.content
      
      return "Max iterations reached without final response"
  ```

  ```typescript TypeScript theme={null}
  async function openaiWithMcpServer(mcpServerUrl: string, userQuery: string) {
      const openaiClient = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

      const messages = [
          { role: "system", content: "You are a helpful assistant. Use the available tools to answer the user's question." },
          { role: "user", content: userQuery }
      ];
      
      const toolsInfo = await klavisClient.mcpServer.listTools({
          serverUrl: mcpServerUrl,
          format: Klavis.ToolFormat.Openai
      });
      
      const maxIterations = 10;
      let iteration = 0;
      
      while (iteration < maxIterations) {
          iteration++;
          
          const response = await openaiClient.chat.completions.create({
              model: "gpt-4o-mini",
              messages: messages,
              tools: toolsInfo.tools,
              tool_choice: "auto"
          });
          
          const assistantMessage = response.choices[0].message;
          
          if (assistantMessage.tool_calls) {
              messages.push({
                  role: "assistant",
                  content: assistantMessage.content,
                  tool_calls: assistantMessage.tool_calls.map(tc => ({
                      id: tc.id,
                      type: "function",
                      function: {
                          name: tc.function.name,
                          arguments: tc.function.arguments
                      }
                  }))
              });
              
              for (const toolCall of assistantMessage.tool_calls) {
                  const toolName = toolCall.function.name;
                  const toolArgs = JSON.parse(toolCall.function.arguments);
                  
                  console.log(`🔧 Calling: ${toolName}`);
                  console.log(`   Arguments:`, JSON.stringify(toolArgs, null, 2));
                  
                  const functionResult = await klavisClient.mcpServer.callTools({
                      serverUrl: mcpServerUrl,
                      toolName: toolName,
                      toolArgs: toolArgs
                  });
                                  
                  messages.push({
                      role: "tool",
                      tool_call_id: toolCall.id,
                      content: JSON.stringify(functionResult)
                  });
              }
              continue;
          } else {
              messages.push({ role: "assistant", content: assistantMessage.content });
              return assistantMessage.content;
          }
      }
      
      return "Max iterations reached without final response";
  }
  ```
</CodeGroup>

### Step 3 - Run!

<CodeGroup>
  ```python Python theme={null}
  result = openai_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}")
  ```

  ```typescript TypeScript theme={null}
  result = await openaiWithMcpServer(
      response.strataServerUrl, 
      "Check my latest emails and summarize them in a Slack message to #updates"
  );

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

<Check>
  Perfect! You've integrated OpenAI with Klavis MCP servers.
</Check>

## Next Steps

<CardGroup cols={2}>
  <Card title="Integrations" icon="server" href="/mcp-server/github">
    Explore available MCP servers
  </Card>

  <Card title="API Reference" icon="magnifying-glass" href="/api-reference/introduction">
    REST endpoints and schemas
  </Card>
</CardGroup>

## Useful Resources

* [OpenAI API Documentation](https://platform.openai.com/docs)
* [OpenAI Function Calling Guide](https://platform.openai.com/docs/guides/function-calling)
* [MCP Protocol Specification](https://modelcontextprotocol.io/)

**Happy building!** 🚀
