update : calendar mcp linked
This commit is contained in:
parent
e4cea90a18
commit
d8f27f6d4b
5 changed files with 196 additions and 7 deletions
|
|
@ -41,8 +41,6 @@ pip install -r requirements.txt
|
|||
GOOGLE_MAPS_API_KEY=your_google_maps_api_key
|
||||
ACCUWEATHER_API_KEY=your_accuweather_api_key
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Built With
|
||||
|
|
@ -56,4 +54,30 @@ OPENAI_API_KEY=your_openai_api_key
|
|||
|
||||
-- Airbnb MCP
|
||||
|
||||
-- Accuweather
|
||||
-- Accuweather
|
||||
|
||||
---
|
||||
|
||||
## 📅 Calendar MCP Server (`calendar_mcp.py`)
|
||||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
### 🛠 Features
|
||||
|
||||
- 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)
|
||||
|
||||
---
|
||||
|
||||
### 🌱 Setup
|
||||
|
||||
Add the following to your `.env` file in the root directory:
|
||||
|
||||
```env
|
||||
GOOGLE_CLIENT_ID=your_google_client_id
|
||||
GOOGLE_CLIENT_SECRET=your_google_client_secret
|
||||
GOOGLE_REFRESH_TOKEN=your_refresh_token
|
||||
```
|
||||
|
|
@ -10,17 +10,20 @@ from dotenv import load_dotenv
|
|||
load_dotenv()
|
||||
|
||||
async def run_agent(message: str) -> None:
|
||||
"""Run the Airbnb, Google Maps, Weather agent with the given message."""
|
||||
"""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")
|
||||
if not google_maps_key:
|
||||
raise ValueError("🚨 Missing GOOGLE_MAPS_API_KEY in environment variables.")
|
||||
elif not accuweather_key:
|
||||
raise ValueError("🚨 Missing ACCUWEATHER_API_KEY in environment variables.")
|
||||
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.")
|
||||
env = {
|
||||
**os.environ,
|
||||
"GOOGLE_MAPS_API_KEY": os.getenv("GOOGLE_MAPS_API_KEY"),
|
||||
|
|
@ -33,7 +36,7 @@ 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
|
||||
# "https://www.gumloop.com/mcp/gcalendar",
|
||||
"/Users/priyanshmaheshwari/Desktop/EchovibeLabs/awesome-llm-apps/mcp_ai_agents/ai_travel_planner_mcp_agent_team/calendar_mcp.py" # ✅ Calendar mcp added
|
||||
|
||||
],
|
||||
env=env,
|
||||
|
|
@ -58,8 +61,14 @@ async def run_agent(message: str) -> None:
|
|||
goal="Connects to Booking.com and Airbnb APIs to search and filter accommodations based on user preferences (price range, amenities, location)"
|
||||
)
|
||||
|
||||
calendar_agent = Agent(
|
||||
tools=[mcp_tools],
|
||||
name="Calendar Agent",
|
||||
goal="Creates calendar events for travel plans, including reminders and location details."
|
||||
)
|
||||
|
||||
team = Team(
|
||||
members=[maps_agent, weather_agent, booking_agent],
|
||||
members=[maps_agent, weather_agent, booking_agent, calendar_agent],
|
||||
name="Travel Planning Team",
|
||||
markdown=True,
|
||||
show_tool_calls=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,21 @@
|
|||
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)
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
agno==1.2.13
|
||||
mcp==1.6.0
|
||||
streamlit==1.44.1
|
||||
streamlit==1.44.1
|
||||
google-api-python-client
|
||||
google-auth
|
||||
google-auth-oauthlib
|
||||
Loading…
Reference in a new issue