Prerequisites
Before we begin, you’ll need OpenAI API key and Klavis API key.Installation
First, install the required packages:pip install openai klavis
npm install openai klavis
Setup Environment Variables
import os
os.environ["OPENAI_API_KEY"] = "YOUR_OPENAI_API_KEY" # Replace
os.environ["KLAVIS_API_KEY"] = "YOUR_KLAVIS_API_KEY" # Replace
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
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 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.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"
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";
}
Step 3 - Run!
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}")
result = await openaiWithMcpServer(
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 OpenAI with Klavis MCP servers.
Next Steps
Integrations
Explore available MCP servers
API Reference
REST endpoints and schemas
