Skip to main content
Glama

Google Calendar MCP Server

by harshwadhawe
streamlit_app.py13.8 kB
#!/usr/bin/env python3 """ Project Management Assistant Dashboard A lightweight dashboard integrating GitHub and Google Calendar for project management. """ import streamlit as st import sys import os from datetime import datetime, timedelta from dotenv import load_dotenv import pytz # Load environment variables load_dotenv() # Add src to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) from src.server import chat from src.calendar_client import CalendarClient from src.github_client import GitHubClient from src.query_analyzer import QueryAnalyzer # Page configuration st.set_page_config( page_title="Project Management Assistant", page_icon="📊", layout="wide", initial_sidebar_state="expanded" ) # Custom CSS for modern UI st.markdown(""" <style> .main-header { font-size: 3rem; font-weight: 700; text-align: center; margin-bottom: 0.5rem; } .mcp-highlight { background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; font-weight: 800; } .metric-card { background: white; padding: 1.5rem; border-radius: 10px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); border-left: 4px solid #667eea; } .event-card { background: #f8f9fa; padding: 1rem; border-radius: 8px; margin-bottom: 0.5rem; border-left: 3px solid #667eea; } .repo-card { background: #f8f9fa; padding: 1rem; border-radius: 8px; margin-bottom: 0.5rem; border-left: 3px solid #28a745; } .stTabs [data-baseweb="tab-list"] { gap: 8px; } .stTabs [data-baseweb="tab"] { border-radius: 8px 8px 0 0; padding: 10px 20px; } </style> """, unsafe_allow_html=True) # Initialize session state if "calendar_client" not in st.session_state: st.session_state.calendar_client = None if "github_client" not in st.session_state: st.session_state.github_client = None def initialize_clients(): """Initialize calendar and GitHub clients.""" try: if st.session_state.calendar_client is None: credentials_path = os.getenv("GOOGLE_CREDENTIALS_PATH", "config/credentials.json") token_path = os.getenv("GOOGLE_TOKEN_PATH", "config/token.json") # Redirect stdout during initialization to avoid interfering with Streamlit import sys original_stdout = sys.stdout try: sys.stdout = sys.stderr st.session_state.calendar_client = CalendarClient(credentials_path, token_path) finally: sys.stdout = original_stdout except Exception as e: st.session_state.calendar_client = None # Don't show error to user, just silently fail try: if st.session_state.github_client is None: st.session_state.github_client = GitHubClient() except Exception as e: st.session_state.github_client = None # Don't show error to user, just silently fail def format_time(dt_str): """Format datetime string for display.""" try: dt = datetime.fromisoformat(dt_str.replace('Z', '+00:00')) return dt.strftime('%I:%M %p') except: return dt_str def format_date(dt_str): """Format date string for display.""" try: dt = datetime.fromisoformat(dt_str.replace('Z', '+00:00')) return dt.strftime('%b %d, %Y') except: return dt_str def get_calendar_summary(): """Get calendar summary for today and upcoming week.""" if st.session_state.calendar_client is None: return [], [] try: now = datetime.now() today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) week_end = today_start + timedelta(days=7) events = st.session_state.calendar_client.get_events_from_all_calendars( time_min=today_start, time_max=week_end, max_results=50 ) today_events = [] upcoming_events = [] for event in events: start = event.get('start', {}).get('dateTime') or event.get('start', {}).get('date') if start: try: event_dt = datetime.fromisoformat(start.replace('Z', '+00:00')) event['parsed_start'] = event_dt if event_dt.date() == now.date(): today_events.append(event) elif event_dt.date() > now.date(): upcoming_events.append(event) except: pass # Sort events by time today_events.sort(key=lambda x: x.get('parsed_start', datetime.min)) upcoming_events.sort(key=lambda x: x.get('parsed_start', datetime.min)) return today_events, upcoming_events[:10] except Exception as e: return [], [] def get_github_summary(): """Get GitHub activity summary.""" if st.session_state.github_client is None: return None try: user_info = st.session_state.github_client.get_user_info() repos = st.session_state.github_client.get_repositories(per_page=10) # Get issues and PRs all_issues = [] all_prs = [] for repo in repos[:5]: owner = repo.get('owner', {}).get('login', user_info.get('login')) repo_name = repo.get('name', '') try: issues = st.session_state.github_client.get_issues(owner, repo_name, state='open', per_page=5) all_issues.extend(issues) except: pass try: prs = st.session_state.github_client.get_pull_requests(owner, repo_name, state='open', per_page=5) all_prs.extend(prs) except: pass return { 'user_info': user_info, 'repos': repos, 'open_issues': all_issues[:10], 'open_prs': all_prs[:10] } except Exception as e: return None def main(): # Header st.markdown('<h1 class="main-header">📊 Project Management <span class="mcp-highlight">MCP Server</span> Assistant</h1>', unsafe_allow_html=True) # Initialize clients initialize_clients() # Sidebar with st.sidebar: st.header("⚙️ Settings") if st.button("🔄 Refresh Data", use_container_width=True): st.session_state.calendar_client = None st.session_state.github_client = None initialize_clients() st.rerun() st.divider() # Status indicators st.subheader("🔌 Connections") calendar_status = "✅ Connected" if st.session_state.calendar_client else "❌ Not Connected" github_status = "✅ Connected" if st.session_state.github_client else "❌ Not Connected" st.write(f"**Calendar:** {calendar_status}") st.write(f"**GitHub:** {github_status}") if not st.session_state.calendar_client: st.info("💡 Configure Google Calendar credentials to enable calendar features.") if not st.session_state.github_client: st.info("💡 Set GITHUB_TOKEN in .env to enable GitHub features.") st.divider() st.subheader("💬 AI Assistant") st.caption("Ask questions about your projects, schedule, or GitHub activity") # Main content - AI Assistant only st.header("💬 AI Assistant") st.caption("Ask me anything about your projects, schedule, or GitHub activity") # Predefined queries organized by category st.subheader("📋 Predefined Queries") # Calendar queries st.markdown("#### 📅 Calendar & Schedule") col1, col2, col3 = st.columns(3) with col1: if st.button("📅 What's my schedule today?", use_container_width=True): st.session_state.quick_query = "What's my schedule today?" st.rerun() if st.button("📆 What meetings do I have this week?", use_container_width=True): st.session_state.quick_query = "What meetings do I have this week?" st.rerun() if st.button("⏰ When am I free tomorrow?", use_container_width=True): st.session_state.quick_query = "When am I free tomorrow?" st.rerun() with col2: if st.button("📋 Summarize my schedule for Monday", use_container_width=True): st.session_state.quick_query = "Summarize my schedule for Monday" st.rerun() if st.button("🔍 Am I free next week?", use_container_width=True): st.session_state.quick_query = "Am I free next week?" st.rerun() if st.button("📊 Show upcoming events", use_container_width=True): st.session_state.quick_query = "Show me my upcoming events" st.rerun() with col3: if st.button("⏳ Check availability at 2 PM", use_container_width=True): st.session_state.quick_query = "Am I available tomorrow at 2 PM?" st.rerun() if st.button("📅 What's on my calendar next week?", use_container_width=True): st.session_state.quick_query = "What's on my calendar next week?" st.rerun() if st.button("🔎 Detect scheduling conflicts", use_container_width=True): st.session_state.quick_query = "Are there any scheduling conflicts this week?" st.rerun() st.divider() # GitHub queries st.markdown("#### 🐙 GitHub & Repositories") col1, col2, col3 = st.columns(3) with col1: if st.button("📦 Show my repositories", use_container_width=True): st.session_state.quick_query = "Show me my recent repositories" st.rerun() if st.button("🐛 What issues need attention?", use_container_width=True): st.session_state.quick_query = "What are my open issues?" st.rerun() if st.button("🔀 Show open pull requests", use_container_width=True): st.session_state.quick_query = "What PRs are open in my repos?" st.rerun() with col2: if st.button("🚀 Show current deployments", use_container_width=True): st.session_state.quick_query = "Show current deployments setup on GitHub" st.rerun() if st.button("📝 Recent commits", use_container_width=True): st.session_state.quick_query = "Show me my recent commits" st.rerun() if st.button("📊 GitHub activity summary", use_container_width=True): st.session_state.quick_query = "Give me a summary of my GitHub activity" st.rerun() with col3: if st.button("🔍 Search repositories", use_container_width=True): st.session_state.quick_query = "What repositories do I have?" st.rerun() if st.button("📈 Production deployments", use_container_width=True): st.session_state.quick_query = "What deployments are live in production?" st.rerun() if st.button("📚 Repository details", use_container_width=True): st.session_state.quick_query = "Tell me about my repositories" st.rerun() st.divider() # Custom query input st.subheader("💭 Custom Query") user_input = st.text_input("Enter your question:", placeholder="e.g., What meetings do I have today?") # Process user input if user_input: with st.spinner("Thinking..."): try: # Auto-detect GitHub queries message_lower = user_input.lower() include_github = any(keyword in message_lower for keyword in ['github', 'repo', 'repository', 'issue', 'pr', 'pull request', 'commit', 'deployment', 'deploy', 'deployed', 'deploying', 'production', 'staging']) response = chat( message=user_input, include_calendar_context=True, include_github_context=include_github ) st.markdown("### Response:") st.write(response) except Exception as e: error_msg = f"Error: {str(e)}" st.error(error_msg) # Handle quick query if hasattr(st.session_state, 'quick_query') and st.session_state.quick_query: query = st.session_state.quick_query del st.session_state.quick_query with st.spinner("Thinking..."): try: message_lower = query.lower() include_github = any(keyword in message_lower for keyword in ['github', 'repo', 'repository', 'issue', 'pr', 'pull request', 'commit', 'deployment', 'deploy', 'deployed', 'deploying', 'production', 'staging']) response = chat( message=query, include_calendar_context=True, include_github_context=include_github ) st.markdown("### Response:") st.write(response) except Exception as e: st.error(f"Error: {str(e)}") if __name__ == "__main__": main()

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/harshwadhawe/MCP-server--datathon'

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