Skip to main content
Glama
BQ31X

Tavily Web Search MCP Server

by BQ31X
get_appointment_weather.py6.34 kB
import os import requests from datetime import datetime from zoneinfo import ZoneInfo from dotenv import load_dotenv def get_upcoming_appointments(api_key): """Fetches upcoming appointments from the Cal.com API.""" print("Retrieving upcoming appointments...") url = f"https://api.cal.com/v1/bookings?apiKey={api_key}&status=upcoming" try: response = requests.get(url) response.raise_for_status() bookings = response.json().get("bookings", []) # Ensure we only process appointments that are not cancelled and sort them. accepted_bookings = sorted( [b for b in bookings if b.get("status") == "ACCEPTED"], key=lambda b: b['startTime'] ) return accepted_bookings except requests.exceptions.RequestException as e: print(f"Error fetching appointments: {e}") return [] def get_lat_lon_for_location(location, api_key): """ Gets latitude and longitude for a location using OpenWeatherMap Geocoding API. It first tries the location as is, then tries again appending ",US" if the first attempt fails. """ base_url = "http://api.openweathermap.org/geo/1.0/direct" # First attempt: query the location as provided try: url = f"{base_url}?q={location}&limit=1&appid={api_key}" response = requests.get(url) response.raise_for_status() data = response.json() if data: return data[0]['lat'], data[0]['lon'] except requests.exceptions.RequestException as e: print(f"Error connecting to geocoding service: {e}") return None, None except (KeyError, IndexError): pass # This will be caught if the location is not found, we'll try again. # Second attempt (fallback): append ",US" and try again print(f"Could not find '{location}'. Trying again with country code 'US'...") try: us_location_query = f"{location},US" url = f"{base_url}?q={us_location_query}&limit=1&appid={api_key}" response = requests.get(url) response.raise_for_status() data = response.json() if data: return data[0]['lat'], data[0]['lon'] except (requests.exceptions.RequestException, KeyError, IndexError): # If this also fails, we give up. pass return None, None def get_weather_forecast(lat, lon, api_key): """Gets the weather forecast for a given lat/lon.""" url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={api_key}&units=imperial" try: response = requests.get(url) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"Error fetching weather data: {e}") return None def display_summary(appointment, weather, location): """Displays a summary of the appointment and weather forecast.""" # Convert UTC time string from API to a local datetime object for display utc_start_time = datetime.fromisoformat(appointment['startTime'].replace('Z', '+00:00')) local_tz = ZoneInfo(appointment.get("user", {}).get("timeZone") or "America/New_York") local_start_time = utc_start_time.astimezone(local_tz) print("\n-----------------------------------------") print("\n--- Appointment and Weather Summary ---") print(f"Appointment: {appointment['title']}") print(f"When: {local_start_time.strftime('%A, %B %d, %Y, at %I:%M %p %Z')}") print(f"Where: {location}") print("\nFetching weather forecast...") if weather: print("\nWeather Forecast:") print(f"Conditions: {weather['weather'][0]['description'].title()}") print(f"Temperature: {weather['main']['temp']}°F") print(f"Wind: {weather['wind']['speed']} mph") else: print("Could not retrieve weather forecast.") print("-----------------------------------------") def main(): """Main function to run the script.""" load_dotenv() cal_api_key = os.getenv("CALCOM_API_KEY") weather_api_key = os.getenv("OPENWEATHERMAP_API_KEY") if not cal_api_key or not weather_api_key: print("Error: API keys not found. Please check your .env file.") return appointments = get_upcoming_appointments(cal_api_key) if not appointments: print("No upcoming appointments found.") return print("\nPlease select an appointment to get the weather for:") for i, appt in enumerate(appointments): # Convert UTC time for display in the menu utc_start = datetime.fromisoformat(appt['startTime'].replace('Z', '+00:00')) local_tz = ZoneInfo(appt.get("user", {}).get("timeZone") or "America/New_York") local_start = utc_start.astimezone(local_tz) print(f" {i+1}: {appt['title']} on {local_start.strftime('%a, %b %d at %I:%M %p %Z')}") try: choice = int(input("Enter the number of the appointment: ")) - 1 if not 0 <= choice < len(appointments): raise ValueError except ValueError: print("Invalid selection.") return selected_appointment = appointments[choice] # --- Revert to the original, working logic for finding location --- # The location data is nested within the 'responses' object. location_response = selected_appointment.get('responses', {}).get('location', {}) # The 'value' can be a simple string or another nested object. location_value = location_response.get('value') if isinstance(location_response, dict) else None if isinstance(location_value, dict): location = location_value.get('value') else: location = location_value if not location or "integrations:" in str(location): print("\n❌ This appointment has no physical location set. Cannot fetch weather.") return lat, lon = get_lat_lon_for_location(location, weather_api_key) if not lat or not lon: print(f"\n❌ Could not find coordinates for location: '{location}'.") print(" Please ensure the location in Cal.com is a recognizable city or address.") return weather = get_weather_forecast(lat, lon, weather_api_key) display_summary(selected_appointment, weather, location) if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/BQ31X/MCP-Session-Code'

If you have feedback or need assistance with the MCP directory API, please join our Discord server