End-to-end assistant for Gmail and Google Calendar with:
- FastMCP servers:
mcp_gmail.pyandmcp_calendar.pyexpose tools for any MCP-capable IDE/agent. - Gradio chat agent:
assistant.pyprovides an interactive ReAct agent UI. - Non-interactive CLI agent:
automation_agent.pyruns a one-shot prompt for cron/systemd. - Robust logging: unified file logging and filtered console logs.
-
Gmail
- Search emails with flexible queries and pagination.
- Send emails or create drafts (safe by default) with CC/BCC and attachments.
- Utility: today’s date with weekday for constructing date filters.
-
Google Calendar
- Read events (time window, query, calendar selection, includes
event_id). - Create, update, delete events (with optional attendee notifications).
- Free/busy lookups for multiple calendars.
- Find meeting slots with timezone-aware working hours and preferred windows.
- Utility: today’s date with weekday.
- Read events (time window, query, calendar selection, includes
-
Agents
assistant.py: interactive agent with clarifying questions.automation_agent.py: non-interactive agent (noask_user), strict literal-JSON tool inputs.
This repo also includes Google ADK-based agents that wrap the same Gmail/Calendar tools and can be used with the ADK Dev UI or the terminal.
- Package:
adk_assistant/adk_assistant/adk_assistant_agent.py: agent definition using ADKFunctionTools; supports terminal chat.adk_assistant/agent.py: ADK discovery entrypoint that exposesroot_agent,agent, andagents=[root_agent].
Prerequisites:
pip install google-adk- Model auth: set
GOOGLE_API_KEY(or use Vertex AI vars per ADK docs)
Run with the Web UI (Dev UI):
cd /home/sshnaidm/sources/ai-assistant
adk web
# then open the provided URL and select the agent exposed by adk_assistantIf your ADK version requires an explicit agent target, use:
adk web --agent adk_assistant.agent:root_agentSee ADK Quickstart for structure and details: link.
Run in the terminal (two options):
# Option A: ADK CLI
adk run adk_assistant.agent:root_agent
# Option B: the built-in terminal runner in this repo
python -m adk_assistant.adk_assistant_agentNotes:
- The terminal runner prints both tool outputs (e.g., created event details) and model text responses.
- Tool descriptions shown in the ADK UI are synced from the MCP tool descriptions.
- Python 3.9+
- Google Cloud OAuth credentials enabling Gmail and Calendar APIs
- Optional: Ollama for local models
- Enable APIs: Gmail API and Google Calendar API.
- Create OAuth client ID (Desktop app) and download the JSON.
- Save the file to
~/.config/credentials.json(or setCREDENTIALS_FILE).
mkdir -p ~/.config
mv /path/to/downloaded/client_secret.json ~/.config/credentials.jsongit clone https://github.com/sshnaidm/ai-assistant
cd ai-assistant
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtCREDENTIALS_FILE(recommended): absolute path to credentials JSON.LOG_LEVEL: INFO (default), DEBUG, WARNING, ERROR.GOOGLE_API_KEY: required if using Gemini.
export CREDENTIALS_FILE="$HOME/.config/credentials.json"
export LOG_LEVEL=INFO
export GOOGLE_API_KEY=your_key_here # if using GeminiFirst run will create token.json with granted scopes. If you later change scopes, delete token.json and re-auth.
python assistant.pyConfigure model in models.py and assistant.py. The agent can ask clarifying questions via ask_user.
python automation_agent.py --prompt "summarize yesterday's emails and draft a reply to me" \
--max-iterations 6 --timeout 180Notes:
- Uses a minimal profile (no
ask_user), strict literal-JSON tool inputs. - Safe defaults (e.g., Gmail drafts by default).
- Gmail MCP server
CREDENTIALS_FILE=$HOME/.config/credentials.json python mcp_gmail.py- Google Calendar MCP server
CREDENTIALS_FILE=$HOME/.config/credentials.json python mcp_calendar.pyGet Emails from Gmail→get_emails_tool- Input:
gmail_query,count,page,full_body - Example:
{ "gmail_query": "to:me in:inbox", "count": 50 }
- Input:
Send or Draft Email via Gmail→send_email_tool- Input:
to,subject,body,from_email,cc,bcc,attachments,html_body,draft_mode - Safety:
draft_mode=trueby default
- Input:
Get Today's Date→get_today_date- Output:
{ "date": "YYYY-MM-DD", "weekday": "Monday" }
- Output:
Get Calendar Events→get_events_tool- Input:
calendar_id,time_min,time_max,max_results,query - Returns events with
event_id
- Input:
Create Calendar Event→create_event_toolUpdate Calendar Event→update_event_toolDelete Calendar Event→delete_event_toolFind Meeting Slots→find_meeting_slots_tool- Inputs include
attendees,duration_minutes,date_start,date_end,preferred_time_start,preferred_time_end,earliest_hour,latest_hour,max_suggestions - Timezone-aware; preferred times interpreted in primary calendar’s timezone
- Inputs include
Get Free Busy Information→get_free_busy_toolGet Today's Date→get_today_date
Option A: Project-level .cursor/mcp.json (create in your repo root):
{
"mcpServers": {
"gmail_mails": {
"command": "python",
"args": ["/path/to/dir/ai-assistant/mcp_gmail.py"],
"env": {
"CREDENTIALS_FILE": "~/.config/credentials.json",
"LOG_LEVEL": "INFO"
}
},
"google_calendar": {
"command": "python",
"args": ["/path/to/dir/ai-assistant/mcp_calendar.py"],
"env": {
"CREDENTIALS_FILE": "~/.config/credentials.json",
"LOG_LEVEL": "INFO"
}
}
}
}Option B: Cursor Settings → MCP → Add servers (same fields as above). Ensure absolute paths.
Create or edit ~/.config/Claude/claude_desktop_config.json (Linux; macOS and Windows use their respective app config dirs):
{
"mcpServers": {
"gmail_mails": {
"command": "python",
"args": ["/path/to/dir/ai-assistant/mcp_gmail.py"],
"env": {
"CREDENTIALS_FILE": "~/.config/credentials.json",
"LOG_LEVEL": "INFO"
}
},
"google_calendar": {
"command": "python",
"args": ["/path/to/dir/ai-assistant/mcp_calendar.py"],
"env": {
"CREDENTIALS_FILE": "~/.config/credentials.json",
"LOG_LEVEL": "INFO"
}
}
}
}Restart Claude Desktop after editing. The tools will appear in the Tools panel.
Gemini’s official CLI does not currently support MCP servers directly. Recommended options:
- Use this repo’s non-interactive runner:
python automation_agent.py --prompt "plan 30-min meeting with [email protected] this Friday afternoon"- Or use an MCP-capable client (Cursor, Claude Desktop) to access the same tools.
- Central log file (for modules that opt-in):
gmail_agent.logvialogging_config.py. - Independent logs per MCP server:
mcp_gmail.log,mcp_calendar.log. - Control verbosity with
LOG_LEVEL. Console output filters third-party noise.
- OAuth scopes changed? Delete
token.jsonand re-auth. - Attachments not found? Use absolute paths for reliability.
- Calendar preferred times ignored? Ensure
preferred_time_start/preferred_time_endare HH:MM strings.
assistant.py: Gradio chat agent (interactive).automation_agent.py: Non-interactive, one-shot agent runner.gmail.py: Gmail API interactions (search, send/draft).google_calendar.py: Calendar API interactions (events, free/busy, slots).mcp_gmail.py: FastMCP Gmail tools server.mcp_calendar.py: FastMCP Calendar tools server.models.py: LLM initialization and choices (Gemini, Ollama, OpenAI).logging_config.py: Optional centralized logging setup.requirements.txt: Dependencies.token.json: Generated after first auth (do not commit).