mirror of
https://github.com/Shubhamsaboo/awesome-llm-apps.git
synced 2026-03-11 17:48:31 -05:00
Merge pull request #181 from priyanshm07/ai-travel-planner-mcp-team
Added new demo: AI Travel Planning agent
This commit is contained in:
118
mcp_ai_agents/ai_travel_planner_mcp_agent_team/README.md
Normal file
118
mcp_ai_agents/ai_travel_planner_mcp_agent_team/README.md
Normal file
@@ -0,0 +1,118 @@
|
||||
## 🌍 AI Travel Planner Agent
|
||||
|
||||
This is a Streamlit-based application that helps users plan their travel itineraries using AI. The app integrates with various mcp servers to provide a comprehensive travel planning experience, including weather forecasts, maps, and calendar integration.
|
||||
|
||||
## Features
|
||||
## MCP Servers Integration
|
||||
|
||||
This project utilizes several MCP (Model Context Protocol) servers to provide a comprehensive travel planning experience:
|
||||
|
||||
### 1. Weather MCP Server
|
||||
- **Functionality**: Provides real-time weather data and forecasts
|
||||
|
||||
### 2. Maps MCP Server
|
||||
- **Functionality**: Handles location-based services and navigation
|
||||
- **Features**:
|
||||
- Search for places and points of interest
|
||||
- Get detailed place information
|
||||
- Retrieve driving/walking directions
|
||||
|
||||
### 3. Calendar MCP Server
|
||||
- **Functionality**: Manages calendar events and scheduling
|
||||
- **Features**:
|
||||
- Create and manage calendar events
|
||||
- Handle time zone conversions
|
||||
- Schedule reminders and notifications
|
||||
- **Integration**: Implemented in `calendar_mcp.py`
|
||||
|
||||
### 4. Booking MCP Server
|
||||
- **Functionality**: Airbnb MCP server used
|
||||
|
||||
|
||||
## Setup
|
||||
|
||||
### Requirements
|
||||
|
||||
1. **API Keys and Credentials**:
|
||||
- **Google Maps API Key**: Set up a Google Maps API Key from Google Cloud Console
|
||||
- **Google Calendar API**: Enable and configure the Calendar API Key
|
||||
- **Google OAuth Credentials**: Client ID and Client Secret and Refresh Token for authentication
|
||||
- **AccuWeather API KEY**: Get AccuWeather API key https://developer.accuweather.com/
|
||||
- **OpenAI API Key**: Sign up at OpenAI to obtain your API key.
|
||||
|
||||
2. **Python 3.8+**: Ensure you have Python 3.8 or higher installed.
|
||||
|
||||
### Installation
|
||||
|
||||
1. Clone this repository:
|
||||
```bash
|
||||
git clone https://github.com/yourusername/ai_travel_planner_mcp_agent_team
|
||||
cd ai_travel_planner_mcp_agent_team
|
||||
```
|
||||
|
||||
2. Install the required Python packages:
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. Set up environment variables:
|
||||
Create a `.env` file in the project root with the following variables:
|
||||
```
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
GOOGLE_REFRESH_TOKEN=
|
||||
GOOGLE_MAPS_API_KEY=
|
||||
OPENAI_API_KEY=
|
||||
ACCUWEATHER_API_KEY=
|
||||
```
|
||||
|
||||
### Running the App
|
||||
|
||||
1. Generate OAuth token for Google Calendar
|
||||
|
||||
2. Start the Streamlit app:
|
||||
```bash
|
||||
streamlit run app.py
|
||||
```
|
||||
|
||||
3. In the app interface:
|
||||
- Use the sidebar to configure your preferences
|
||||
- Enter your travel details
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `app.py`: Main Streamlit application
|
||||
- `calendar_mcp.py`: Calendar mcp integration functionality
|
||||
- `requirements.txt`: Project dependencies
|
||||
- `.env`: Environment variables
|
||||
|
||||
## Calendar MCP Integration
|
||||
|
||||
The `calendar_mcp.py` module provides seamless integration with Google Calendar through the MCP (Model Context Protocol) framework. This integration allows the travel planner to:
|
||||
|
||||
- **Create Events**: Automatically create calendar events for travel activities, flights, and accommodations
|
||||
- **Schedule Management**: Handle time zone conversions and scheduling conflicts
|
||||
- **Event Details**: Include comprehensive event information such as:
|
||||
- Location details with Google Maps links
|
||||
- Weather forecasts for the event time
|
||||
- Travel duration and transportation details
|
||||
- Notes and reminders
|
||||
|
||||
### Calendar Setup
|
||||
|
||||
1. **OAuth Authentication**:
|
||||
- The application uses OAuth 2.0 for secure authentication with Google Calendar
|
||||
- First-time setup requires generating refresh token
|
||||
- Refresh tokens are stored securely in the `.env` file
|
||||
|
||||
2. **Event Creation**:
|
||||
```python
|
||||
# Example of creating a calendar event
|
||||
event = {
|
||||
'summary': 'Flight to Paris',
|
||||
'location': 'Charles de Gaulle Airport',
|
||||
'description': 'Flight details and weather forecast',
|
||||
'start': {'dateTime': '2024-04-20T10:00:00', 'timeZone': 'Europe/Paris'},
|
||||
'end': {'dateTime': '2024-04-20T12:00:00', 'timeZone': 'Europe/Paris'}
|
||||
}
|
||||
```
|
||||
356
mcp_ai_agents/ai_travel_planner_mcp_agent_team/app.py
Normal file
356
mcp_ai_agents/ai_travel_planner_mcp_agent_team/app.py
Normal file
@@ -0,0 +1,356 @@
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agno.agent import Agent
|
||||
from agno.team.team import Team
|
||||
from agno.tools.mcp import MultiMCPTools
|
||||
from agno.models.openai import OpenAIChat
|
||||
import streamlit as st
|
||||
from datetime import date
|
||||
|
||||
# Remove dotenv import and loading since we'll use sidebar
|
||||
# from dotenv import load_dotenv
|
||||
# load_dotenv()
|
||||
|
||||
async def run_agent(message: str):
|
||||
"""Run the Airbnb, Google Maps, Weather and Calendar agent with the given message."""
|
||||
|
||||
# Get API keys from session state
|
||||
google_maps_key = st.session_state.get('google_maps_key')
|
||||
accuweather_key = st.session_state.get('accuweather_key')
|
||||
openai_key = st.session_state.get('openai_key')
|
||||
google_client_id = st.session_state.get('google_client_id')
|
||||
google_client_secret = st.session_state.get('google_client_secret')
|
||||
google_refresh_token = st.session_state.get('google_refresh_token')
|
||||
|
||||
if not google_maps_key:
|
||||
raise ValueError("🚨 Missing Google Maps API Key. Please enter it in the sidebar.")
|
||||
elif not accuweather_key:
|
||||
raise ValueError("🚨 Missing AccuWeather API Key. Please enter it in the sidebar.")
|
||||
elif not openai_key:
|
||||
raise ValueError("🚨 Missing OpenAI API Key. Please enter it in the sidebar.")
|
||||
elif not google_client_id:
|
||||
raise ValueError("🚨 Missing Google Client ID. Please enter it in the sidebar.")
|
||||
elif not google_client_secret:
|
||||
raise ValueError("🚨 Missing Google Client Secret. Please enter it in the sidebar.")
|
||||
elif not google_refresh_token:
|
||||
raise ValueError("🚨 Missing Google Refresh Token. Please enter it in the sidebar.")
|
||||
|
||||
# 👉 Set OPENAI_API_KEY globally
|
||||
os.environ["OPENAI_API_KEY"] = openai_key
|
||||
|
||||
env = {
|
||||
**os.environ,
|
||||
"GOOGLE_MAPS_API_KEY": google_maps_key,
|
||||
"ACCUWEATHER_API_KEY": accuweather_key,
|
||||
"OPENAI_API_KEY": openai_key,
|
||||
"GOOGLE_CLIENT_ID": google_client_id,
|
||||
"GOOGLE_CLIENT_SECRET": google_client_secret,
|
||||
"GOOGLE_REFRESH_TOKEN": google_refresh_token
|
||||
}
|
||||
|
||||
async with MultiMCPTools(
|
||||
[
|
||||
"npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt", # ✅ Airbnb mcp added
|
||||
"npx -y @modelcontextprotocol/server-google-maps", # ✅ Google Maps mcp added
|
||||
"uvx --from git+https://github.com/adhikasp/mcp-weather.git mcp-weather", # ✅ Weather mcp added
|
||||
"./calendar_mcp.py"
|
||||
],
|
||||
env=env,
|
||||
) as mcp_tools:
|
||||
|
||||
#Define specialized agents with enhanced instructions
|
||||
maps_agent = Agent(
|
||||
tools=[mcp_tools],
|
||||
model=OpenAIChat(id="gpt-4o-mini", api_key=openai_key),
|
||||
name="Maps Agent",
|
||||
goal="""As a Maps Agent, your responsibilities include:
|
||||
1. Finding optimal routes between locations
|
||||
2. Identifying points of interest near destinations
|
||||
3. Calculating travel times and distances
|
||||
4. Suggesting transportation options
|
||||
5. Finding nearby amenities and services
|
||||
6. Providing location-based recommendations
|
||||
|
||||
Always consider:
|
||||
- Traffic conditions and peak hours
|
||||
- Alternative routes and transportation modes
|
||||
- Accessibility and convenience
|
||||
- Safety and well-lit areas
|
||||
- Proximity to other planned activities"""
|
||||
)
|
||||
|
||||
weather_agent = Agent(
|
||||
tools=[mcp_tools],
|
||||
name="Weather Agent",
|
||||
model=OpenAIChat(id="gpt-4o-mini", api_key=openai_key),
|
||||
goal="""As a Weather Agent, your responsibilities include:
|
||||
1. Providing detailed weather forecasts for destinations
|
||||
2. Alerting about severe weather conditions
|
||||
3. Suggesting weather-appropriate activities
|
||||
4. Recommending the best travel times based on the weather conditions.
|
||||
5. Providing seasonal travel recommendations
|
||||
|
||||
Always consider:
|
||||
- Temperature ranges and comfort levels
|
||||
- Precipitation probability
|
||||
- Wind conditions
|
||||
- UV index and sun protection
|
||||
- Seasonal variations
|
||||
- Weather alerts and warnings"""
|
||||
)
|
||||
|
||||
booking_agent = Agent(
|
||||
tools=[mcp_tools],
|
||||
name="Booking Agent",
|
||||
model=OpenAIChat(id="gpt-4o-mini", api_key=openai_key),
|
||||
goal="""As a Booking Agent, your responsibilities include:
|
||||
1. Finding accommodations within budget on airbnb
|
||||
2. Comparing prices across platforms
|
||||
3. Checking availability for specific dates
|
||||
4. Verifying amenities and policies
|
||||
5. Finding last-minute deals when applicable
|
||||
|
||||
Always consider:
|
||||
- Location convenience
|
||||
- Price competitiveness
|
||||
- Cancellation policies
|
||||
- Guest reviews and ratings
|
||||
- Amenities matching preferences
|
||||
- Special requirements or accessibility needs"""
|
||||
)
|
||||
|
||||
calendar_agent = Agent(
|
||||
tools=[mcp_tools],
|
||||
name="Calendar Agent",
|
||||
model=OpenAIChat(id="gpt-4o-mini", api_key=openai_key),
|
||||
goal="""As a Calendar Agent, your responsibilities include:
|
||||
1. Creating detailed travel itineraries
|
||||
2. Setting reminders for bookings and check-ins
|
||||
3. Scheduling activities and reservations
|
||||
4. Adding reminders for booking deadlines, check-ins, and other important events.
|
||||
5. Coordinating with other team members' schedules
|
||||
|
||||
Always consider:
|
||||
- Time zone differences
|
||||
- Travel duration between activities
|
||||
- Buffer time for unexpected delays
|
||||
- Important deadlines and check-in times
|
||||
- Synchronization with other team members"""
|
||||
)
|
||||
|
||||
team = Team(
|
||||
members=[maps_agent, weather_agent, booking_agent, calendar_agent],
|
||||
name="Travel Planning Team",
|
||||
markdown=True,
|
||||
show_tool_calls=True,
|
||||
instructions="""As a Travel Planning Team, coordinate to create comprehensive travel plans:
|
||||
1. Share information between agents to ensure consistency
|
||||
2. Consider dependencies between different aspects of the trip
|
||||
3. Prioritize user preferences and constraints
|
||||
4. Provide backup options when primary choices are unavailable
|
||||
5. Maintain a balance between planned activities and free time
|
||||
6. Consider local events and seasonal factors
|
||||
7. Ensure all recommendations align with the user's budget
|
||||
8. Provide a detailed breakdown of the trip, including bookings, routes, weather, and planned activities.
|
||||
9. Add the journey start date in the user calendar"""
|
||||
)
|
||||
|
||||
result = await team.arun(message)
|
||||
output = result.messages[-1].content
|
||||
return output
|
||||
|
||||
# -------------------- Streamlit App --------------------
|
||||
|
||||
# Configure the page
|
||||
st.set_page_config(
|
||||
page_title="AI Travel Planner",
|
||||
page_icon="✈️",
|
||||
layout="wide"
|
||||
)
|
||||
|
||||
# Add sidebar for API keys
|
||||
with st.sidebar:
|
||||
st.header("🔑 API Keys Configuration")
|
||||
st.markdown("Please enter your API keys to use the travel planner.")
|
||||
|
||||
# Initialize session state for API keys if not exists
|
||||
if 'google_maps_key' not in st.session_state:
|
||||
st.session_state.google_maps_key = ""
|
||||
if 'accuweather_key' not in st.session_state:
|
||||
st.session_state.accuweather_key = ""
|
||||
if 'openai_key' not in st.session_state:
|
||||
st.session_state.openai_key = ""
|
||||
if 'google_client_id' not in st.session_state:
|
||||
st.session_state.google_client_id = ""
|
||||
if 'google_client_secret' not in st.session_state:
|
||||
st.session_state.google_client_secret = ""
|
||||
if 'google_refresh_token' not in st.session_state:
|
||||
st.session_state.google_refresh_token = ""
|
||||
|
||||
# API key input fields
|
||||
st.session_state.google_maps_key = st.text_input(
|
||||
"Google Maps API Key",
|
||||
value=st.session_state.google_maps_key,
|
||||
type="password"
|
||||
)
|
||||
st.session_state.accuweather_key = st.text_input(
|
||||
"AccuWeather API Key",
|
||||
value=st.session_state.accuweather_key,
|
||||
type="password"
|
||||
)
|
||||
st.session_state.openai_key = st.text_input(
|
||||
"OpenAI API Key",
|
||||
value=st.session_state.openai_key,
|
||||
type="password"
|
||||
)
|
||||
st.session_state.google_client_id = st.text_input(
|
||||
"Google Client ID",
|
||||
value=st.session_state.google_client_id,
|
||||
type="password"
|
||||
)
|
||||
st.session_state.google_client_secret = st.text_input(
|
||||
"Google Client Secret",
|
||||
value=st.session_state.google_client_secret,
|
||||
type="password"
|
||||
)
|
||||
st.session_state.google_refresh_token = st.text_input(
|
||||
"Google Refresh Token",
|
||||
value=st.session_state.google_refresh_token,
|
||||
type="password"
|
||||
)
|
||||
|
||||
# Check if all API keys are filled
|
||||
all_keys_filled = all([
|
||||
st.session_state.google_maps_key,
|
||||
st.session_state.accuweather_key,
|
||||
st.session_state.openai_key,
|
||||
st.session_state.google_client_id,
|
||||
st.session_state.google_client_secret,
|
||||
st.session_state.google_refresh_token
|
||||
])
|
||||
|
||||
if not all_keys_filled:
|
||||
st.warning("⚠️ Please fill in all API keys to use the travel planner.")
|
||||
else:
|
||||
st.success("✅ All API keys are configured!")
|
||||
|
||||
# Title and description
|
||||
st.title("✈️ AI Travel Planner")
|
||||
st.markdown("""
|
||||
This AI-powered travel planner helps you create personalized travel itineraries using:
|
||||
- 🗺️ Maps and navigation
|
||||
- 🌤️ Weather forecasts
|
||||
- 🏨 Accommodation booking
|
||||
- 📅 Calendar management
|
||||
""")
|
||||
|
||||
# Create two columns for input
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
# Source and Destination
|
||||
source = st.text_input("Source", placeholder="Enter your departure city")
|
||||
destination = st.text_input("Destination", placeholder= "Enter your destination city")
|
||||
|
||||
# Travel Dates
|
||||
travel_dates = st.date_input(
|
||||
"Travel Dates",
|
||||
[date.today(), date.today()],
|
||||
min_value=date.today(),
|
||||
help="Select your travel dates"
|
||||
)
|
||||
|
||||
with col2:
|
||||
# Budget
|
||||
budget = st.number_input(
|
||||
"Budget (in USD)",
|
||||
min_value=0,
|
||||
max_value=10000,
|
||||
step=100,
|
||||
help="Enter your total budget for the trip"
|
||||
)
|
||||
|
||||
# Travel Preferences
|
||||
travel_preferences = st.multiselect(
|
||||
"Travel Preferences",
|
||||
["Adventure", "Relaxation", "Sightseeing", "Cultural Experiences",
|
||||
"Beach", "Mountain", "Luxury", "Budget-Friendly", "Food & Dining",
|
||||
"Shopping", "Nightlife", "Family-Friendly"],
|
||||
help="Select your travel preferences"
|
||||
)
|
||||
|
||||
# Additional preferences
|
||||
st.subheader("Additional Preferences")
|
||||
col3, col4 = st.columns(2)
|
||||
|
||||
with col3:
|
||||
accommodation_type = st.selectbox(
|
||||
"Preferred Accommodation",
|
||||
["Any", "Hotel", "Hostel", "Apartment", "Resort"],
|
||||
help="Select your preferred type of accommodation"
|
||||
)
|
||||
|
||||
transportation_mode = st.multiselect(
|
||||
"Preferred Transportation",
|
||||
["Train", "Bus", "Flight", "Rental Car"],
|
||||
help="Select your preferred modes of transportation"
|
||||
)
|
||||
|
||||
with col4:
|
||||
dietary_restrictions = st.multiselect(
|
||||
"Dietary Restrictions",
|
||||
["None", "Vegetarian", "Vegan", "Gluten-Free", "Halal", "Kosher"],
|
||||
help="Select any dietary restrictions"
|
||||
)
|
||||
|
||||
# Submit Button
|
||||
if st.button("Plan My Trip", type="primary", disabled=not all_keys_filled):
|
||||
if not source or not destination:
|
||||
st.error("Please enter both source and destination cities.")
|
||||
elif not travel_preferences:
|
||||
st.warning("Consider selecting some travel preferences for better recommendations.")
|
||||
else:
|
||||
# Create a loading spinner
|
||||
with st.spinner("🤖 AI Agents are planning your perfect trip..."):
|
||||
try:
|
||||
# Construct the message for the agents
|
||||
message = f"""
|
||||
Plan a trip with the following details:
|
||||
- From: {source}
|
||||
- To: {destination}
|
||||
- Dates: {travel_dates[0]} to {travel_dates[1]}
|
||||
- Budget in USD: ${budget}
|
||||
- Preferences: {', '.join(travel_preferences)}
|
||||
- Accommodation: {accommodation_type}
|
||||
- Transportation: {', '.join(transportation_mode)}
|
||||
- Dietary Restrictions: {', '.join(dietary_restrictions)}
|
||||
|
||||
Please provide a comprehensive travel plan including:
|
||||
1. Recommended accommodations
|
||||
2. Daily itinerary with activities
|
||||
3. Transportation options
|
||||
4. The Expected Day Weather
|
||||
5. Estimated cost of the Trip
|
||||
6. Add the Departure Date to the calendar
|
||||
"""
|
||||
|
||||
# Run the agents
|
||||
response = asyncio.run(run_agent(message))
|
||||
|
||||
# Display the response
|
||||
st.success("✅ Your travel plan is ready!")
|
||||
st.markdown(response)
|
||||
|
||||
except Exception as e:
|
||||
st.error(f"An error occurred while planning your trip: {str(e)}")
|
||||
st.info("Please try again or contact support if the issue persists.")
|
||||
|
||||
# Add a footer
|
||||
st.markdown("---")
|
||||
st.markdown("""
|
||||
<div style='text-align: center'>
|
||||
<p>Powered by AI Travel Planning Agents</p>
|
||||
<p>Your personal travel assistant for creating memorable experiences</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
132
mcp_ai_agents/ai_travel_planner_mcp_agent_team/calendar_mcp.py
Executable file
132
mcp_ai_agents/ai_travel_planner_mcp_agent_team/calendar_mcp.py
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python
|
||||
import os
|
||||
import json
|
||||
import sys
|
||||
import logging
|
||||
from dotenv import load_dotenv
|
||||
from google.oauth2.credentials import Credentials
|
||||
from googleapiclient.discovery import build
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
|
||||
load_dotenv()
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format='DEBUG: %(asctime)s - %(message)s',
|
||||
stream=sys.stderr
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
mcp = FastMCP("Google Calendar MCP", dependencies=["python-dotenv", "google-api-python-client", "google-auth", "google-auth-oauthlib"])
|
||||
|
||||
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
|
||||
GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
|
||||
GOOGLE_REFRESH_TOKEN = os.getenv("GOOGLE_REFRESH_TOKEN")
|
||||
|
||||
if not GOOGLE_CLIENT_ID or not GOOGLE_CLIENT_SECRET or not GOOGLE_REFRESH_TOKEN:
|
||||
logger.error("Error: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and GOOGLE_REFRESH_TOKEN environment variables are required")
|
||||
sys.exit(1)
|
||||
|
||||
@mcp.tool()
|
||||
async def create_event(
|
||||
summary: str,
|
||||
start_time: str,
|
||||
end_time: str,
|
||||
description: str = None,
|
||||
location: str = None,
|
||||
attendees: list = None,
|
||||
reminders: dict = None
|
||||
) -> str:
|
||||
"""Create a calendar event with specified details
|
||||
|
||||
Args:
|
||||
summary: Event title
|
||||
start_time: Start time (ISO format)
|
||||
end_time: End time (ISO format)
|
||||
description: Event description
|
||||
location: Event location
|
||||
attendees: List of attendee emails
|
||||
reminders: Reminder settings for the event
|
||||
|
||||
Returns:
|
||||
String with event creation confirmation and link
|
||||
"""
|
||||
logger.debug(f'Creating calendar event with args: {locals()}')
|
||||
|
||||
try:
|
||||
logger.debug('Creating OAuth2 client')
|
||||
# Google OAuth2
|
||||
creds = Credentials(
|
||||
None,
|
||||
refresh_token=GOOGLE_REFRESH_TOKEN,
|
||||
token_uri="https://oauth2.googleapis.com/token",
|
||||
client_id=GOOGLE_CLIENT_ID,
|
||||
client_secret=GOOGLE_CLIENT_SECRET
|
||||
)
|
||||
logger.debug('OAuth2 client created')
|
||||
|
||||
logger.debug('Creating calendar service')
|
||||
calendar_service = build('calendar', 'v3', credentials=creds)
|
||||
logger.debug('Calendar service created')
|
||||
|
||||
event = {
|
||||
'summary': summary,
|
||||
'start': {
|
||||
'dateTime': start_time,
|
||||
'timeZone': 'Asia/Seoul'
|
||||
},
|
||||
'end': {
|
||||
'dateTime': end_time,
|
||||
'timeZone': 'Asia/Seoul'
|
||||
}
|
||||
}
|
||||
|
||||
if description:
|
||||
event['description'] = description
|
||||
|
||||
if location:
|
||||
event['location'] = location
|
||||
logger.debug(f'Location added: {location}')
|
||||
|
||||
if attendees:
|
||||
event['attendees'] = [{'email': email} for email in attendees]
|
||||
logger.debug(f'Attendees added: {event["attendees"]}')
|
||||
|
||||
if reminders:
|
||||
event['reminders'] = reminders
|
||||
logger.debug(f'Custom reminders set: {json.dumps(reminders)}')
|
||||
else:
|
||||
event['reminders'] = {
|
||||
'useDefault': False,
|
||||
'overrides': [
|
||||
{'method': 'popup', 'minutes': 10}
|
||||
]
|
||||
}
|
||||
logger.debug(f'Default reminders set: {json.dumps(event["reminders"])}')
|
||||
|
||||
logger.debug('Attempting to insert event')
|
||||
response = calendar_service.events().insert(calendarId='primary', body=event).execute()
|
||||
logger.debug(f'Event insert response: {json.dumps(response)}')
|
||||
|
||||
return f"Event created: {response.get('htmlLink', 'No link available')}"
|
||||
|
||||
except Exception as error:
|
||||
logger.debug(f'ERROR OCCURRED:')
|
||||
logger.debug(f'Error type: {type(error).__name__}')
|
||||
logger.debug(f'Error message: {str(error)}')
|
||||
import traceback
|
||||
logger.debug(f'Error traceback: {traceback.format_exc()}')
|
||||
raise Exception(f"Failed to create event: {str(error)}")
|
||||
|
||||
def main():
|
||||
"""Run the MCP calendar server."""
|
||||
try:
|
||||
mcp.run()
|
||||
except KeyboardInterrupt:
|
||||
logger.info("Server stopped by user")
|
||||
except Exception as e:
|
||||
logger.error(f"Fatal error running server: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,9 @@
|
||||
agno==1.2.13
|
||||
mcp==1.6.0
|
||||
streamlit==1.44.1
|
||||
google-api-python-client==2.118.0
|
||||
google-auth==2.28.1
|
||||
google-auth-oauthlib==1.2.0
|
||||
python-dotenv==1.0.1
|
||||
requests==2.31.0
|
||||
openai==1.12.0
|
||||
Reference in New Issue
Block a user