From cae82dc8b88bf5e07629eff4cce39c992c51a728 Mon Sep 17 00:00:00 2001 From: priyanshm07 Date: Sun, 20 Apr 2025 07:08:20 +0530 Subject: [PATCH] Update : Streamlit app created --- .../README.md | 149 +++++--- .../ai_travel_planner_mcp_agent_team/app.py | 336 ++++++++++++++++-- .../generate_token.py | 21 -- .../requirements.txt | 9 +- 4 files changed, 398 insertions(+), 117 deletions(-) delete mode 100644 mcp_ai_agents/ai_travel_planner_mcp_agent_team/generate_token.py diff --git a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/README.md b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/README.md index 30d924e..9b56b3e 100644 --- a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/README.md +++ b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/README.md @@ -1,83 +1,118 @@ -# 🌍 AI Travel Planner β€” MCP Agent Team (Airbnb, Google Maps, Weather) +## 🌍 AI Travel Planner Agent -This project is a *multi-agent travel planning assistant* built using [Agno](https://github.com/agnodice/agno), powered by multiple [Model Context Protocol (MCP)](https://modelcontextprotocol.org/) tools. It integrates: +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. -‒⁠ ⁠🏠 *Airbnb Listings* -‒⁠ β πŸ—ΊοΈ *Google Maps for routing and places* -‒⁠ ⁠🌦️ *Weather information via AccuWeather* -‒⁠ β πŸ“… (Optional) *Google Calendar integration via Gumloop MCP* +## Features +## MCP Servers Integration -All handled through a simple terminal interface powered by Python + asyncio. +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 -## βš™οΈ Requirements +### 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 -‒⁠ ⁠Python 3.10+ -‒⁠ ⁠Node.js + ⁠ npx ⁠ -‒⁠ ⁠[uvx](https://github.com/uvx/cli) for running MCP servers from Git -‒⁠ ⁠Internet access for MCP calls +### 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` ---- - -## πŸ“¦ Installation - -1.⁠ ⁠*Clone the repo* - -⁠ bash -git clone https://github.com/yourusername/ai-travel-planner.git -cd ai-travel-planner - ⁠ - -2.⁠ ⁠*Create Virtual Env* - -conda create -n env_name python=3.10 -y -conda activate env_name -pip install -r requirements.txt +### 4. Booking MCP Server +- **Functionality**: Airbnb MCP server used -3.⁠ ⁠*Create env file* +## Setup -GOOGLE_MAPS_API_KEY=your_google_maps_api_key -ACCUWEATHER_API_KEY=your_accuweather_api_key -OPENAI_API_KEY=your_openai_api_key ---- +### Requirements -## 🧠 Built With --- Agno +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. --- FastMCP +2. **Python 3.8+**: Ensure you have Python 3.8 or higher installed. --- OpenAI +### Installation --- Google Maps Platform +1. Clone this repository: + ```bash + git clone https://github.com/yourusername/ai_travel_planner_mcp_agent_team + cd ai_travel_planner_mcp_agent_team + ``` --- Airbnb MCP +2. Install the required Python packages: + ```bash + pip install -r requirements.txt + ``` --- Accuweather +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 -## πŸ“… Calendar MCP Server (`calendar_mcp.py`) +1. Generate OAuth token for Google Calendar -This script is a dedicated MCP (Modular Cognitive Process) server that integrates with **Google Calendar** to create events via API calls. It works seamlessly with the rest of the multi-agent system built with Agno and FastMCP. +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 -### πŸ›  Features +## Project Structure -- Creates Google Calendar events using the `create_event` tool -- Accepts event title, description, date/time, location, attendees, and reminders -- Uses a refresh token for persistent access (no re-authentication needed) +- `app.py`: Main Streamlit application +- `calendar_mcp.py`: Calendar mcp integration functionality +- `requirements.txt`: Project dependencies +- `.env`: Environment variables ---- +## Calendar MCP Integration -### 🌱 Setup +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: -Add the following to your `.env` file in the root directory: +- **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 -```env -GOOGLE_CLIENT_ID=your_google_client_id -GOOGLE_CLIENT_SECRET=your_google_client_secret -GOOGLE_REFRESH_TOKEN=your_refresh_token -``` \ No newline at end of file +### 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'} + } + ``` diff --git a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/app.py b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/app.py index bdcd985..585360a 100644 --- a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/app.py +++ b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/app.py @@ -4,31 +4,49 @@ 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 -from dotenv import load_dotenv -load_dotenv() +# Remove dotenv import and loading since we'll use sidebar +# from dotenv import load_dotenv +# load_dotenv() -async def run_agent(message: str) -> None: +async def run_agent(message: str): """Run the Airbnb, Google Maps, Weather and Calendar agent with the given message.""" - google_maps_key = os.getenv("GOOGLE_MAPS_API_KEY") - accuweather_key = os.getenv("ACCUWEATHER_API_KEY") - openai_key = os.getenv("OPENAI_API_KEY") - google_maps_key = os.getenv("GOOGLE_CLIENT_ID") + # 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 in environment variables.") + raise ValueError("🚨 Missing Google Maps API Key. Please enter it in the sidebar.") elif not accuweather_key: - raise ValueError("🚨 Missing ACCUWEATHER_API_KEY in environment variables.") + raise ValueError("🚨 Missing AccuWeather API Key. Please enter it in the sidebar.") elif not openai_key: - raise ValueError("🚨 Missing OPENAI_API_KEY in environment variables.") - elif not google_maps_key: - raise ValueError("🚨 Missing GOOGLE_CLIENT_ID in environment variables.") + 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": os.getenv("GOOGLE_MAPS_API_KEY"), - "ACCUWEATHER_API_KEY": os.getenv("ACCUWEATHER_API_KEY"), - "OPENAI_API_KEY": os.getenv("OPENAI_API_KEY") + "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( @@ -36,57 +54,303 @@ async def run_agent(message: str) -> None: "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 - "/Users/priyanshmaheshwari/Desktop/EchovibeLabs/awesome-llm-apps/mcp_ai_agents/ai_travel_planner_mcp_agent_team/calendar_mcp.py" # βœ… Calendar mcp added - + "./calendar_mcp.py" ], env=env, ) as mcp_tools: - #Define sepcialized agents + #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="Integrates with Google Maps server to provide routing information, travel time estimates, and points of interest proximity analysis" + 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", - goal="Pulls data from OpenWeatherMap to provide weather forecasts for planned dates and locations, allowing for weather-appropriate activity planning." + 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", - goal="Connects to Booking.com and Airbnb APIs to search and filter accommodations based on user preferences (price range, amenities, location)" + 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", - goal="Creates calendar events for travel plans, including reminders and location details." + 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 + 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""" ) - await team.aprint_response(message, stream=True) + 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" +) -# -------------------- Terminal Interaction Loop -------------------- +# 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 = "" -if __name__ == "__main__": # βœ… correct + # 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" + ) - print("🌍 Travel Planning Agent β€” Airbnb, Maps, Weather, Calendar (type 'exit' to quit)\n") - try: - while True: - user_input = input("You: ") - if user_input.lower() in ["exit", "quit"]: - print("πŸ‘‹ Bye!") - break - asyncio.run(run_agent(user_input)) - except KeyboardInterrupt: - print("\nπŸ‘‹ Interrupted. Exiting...") \ No newline at end of file + # 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(""" +
+

Powered by AI Travel Planning Agents

+

Your personal travel assistant for creating memorable experiences

+
+""", unsafe_allow_html=True) \ No newline at end of file diff --git a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/generate_token.py b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/generate_token.py deleted file mode 100644 index 6fe9f83..0000000 --- a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/generate_token.py +++ /dev/null @@ -1,21 +0,0 @@ -from google_auth_oauthlib.flow import InstalledAppFlow -from dotenv import load_dotenv -import os - -load_dotenv() # Loads from .env - -SCOPES = ['https://www.googleapis.com/auth/calendar'] - -flow = InstalledAppFlow.from_client_config({ - "installed": { - "client_id": os.getenv("GOOGLE_CLIENT_ID"), - "client_secret": os.getenv("GOOGLE_CLIENT_SECRET"), - "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob"], - "auth_uri": "https://accounts.google.com/o/oauth2/auth", - "token_uri": "https://oauth2.googleapis.com/token" - } -}, SCOPES) - -creds = flow.run_local_server(port=0) -print("\n=== REFRESH TOKEN ===\n") -print(creds.refresh_token) diff --git a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/requirements.txt b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/requirements.txt index 75b6922..c4b42ce 100644 --- a/mcp_ai_agents/ai_travel_planner_mcp_agent_team/requirements.txt +++ b/mcp_ai_agents/ai_travel_planner_mcp_agent_team/requirements.txt @@ -1,6 +1,9 @@ agno==1.2.13 mcp==1.6.0 streamlit==1.44.1 -google-api-python-client -google-auth -google-auth-oauthlib \ No newline at end of file +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 \ No newline at end of file