Skip to content

feat: Add Support for Google Drive and Gmail Operations - #5

Merged
taylorwilsdon merged 6 commits into
mainfrom
add_drive_and_gmail
May 12, 2025
Merged

feat: Add Support for Google Drive and Gmail Operations#5
taylorwilsdon merged 6 commits into
mainfrom
add_drive_and_gmail

Conversation

@taylorwilsdon

Copy link
Copy Markdown
Owner

feat: add Google Drive & Gmail support to MCP server

Description

This pull request introduces comprehensive Google Drive and Gmail integration into the MCP server. It:

  • Defines new OAuth scopes for Drive and Gmail in core/server.py.
  • Updates the combined SCOPES list to include Drive (readonly + per-file) and Gmail (readonly + send).
  • Enhances existing calendar tools with clearer LLM guidance, parameter docs, and return types.
  • Adds a new gdrive package with tools for searching, listing, reading, and creating Drive files.
  • Adds a new gmail package with tools for searching messages and retrieving message content.
  • Registers the new tools by importing gdrive.drive_tools and gmail.gmail_tools in main.py.

Changes

  • core/server.py
    • Added constants:
      • DRIVE_READONLY_SCOPE, DRIVE_FILE_SCOPE
      • GMAIL_READONLY_SCOPE, GMAIL_SEND_SCOPE
    • Introduced DRIVE_SCOPES, GMAIL_SCOPES
    • Updated SCOPES = list(set(BASE_SCOPES + CALENDAR_SCOPES + DRIVE_SCOPES + GMAIL_SCOPES + [DRIVE_FILE_SCOPE]))
  • gcalendar/calendar_tools.py
    • Expanded docstrings for start_auth, list_calendars, get_events with:
      • LLM guidance bullets
      • Detailed Args: and Returns: types
  • gdrive/drive_tools.py (new)
    • Helper: _initiate_drive_auth_and_get_message
    • Tools:
      • search_drive_files(query, …)
      • get_drive_file_content(file_id, …)
      • list_drive_items(folder_id, …)
      • create_drive_file(file_name, content, folder_id, …)
  • gmail/gmail_tools.py (new)
    • Decorator-based auth via @require_google_auth
    • Tools:
      • search_gmail_messages(query, …)
      • get_gmail_message_content(message_id, …)
  • main.py
    • Added imports:
      import gdrive.drive_tools
      import gmail.gmail_tools

How to Test

  1. Place your OAuth client secrets file (client_secret.json) in the project root (or set GOOGLE_CLIENT_SECRETS env var).
  2. Install and run the MCP server:
    uv pip install -e .
    python main.py

@taylorwilsdon
taylorwilsdon requested a review from Copilot May 12, 2025 21:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds support for Google Drive and Gmail operations to the MCP server by updating OAuth scopes and introducing new tools for interacting with these services. Key changes include updating the server’s OAuth scopes in core/server.py, adding new packages (gdrive and gmail) with corresponding tool functions, and enhancing existing calendar tools for improved documentation and clarity.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
main.py Added imports to register new gdrive and gmail tools
gmail/gmail_tools.py Introduced Gmail API tools with decorator-based authentication
gmail/init.py Marked the gmail directory as a Python package
gcalendar/calendar_tools.py Enhanced docstrings with clearer guidance and parameter documentation
core/server.py Updated OAuth scopes to include Drive and Gmail scopes

Comment thread core/server.py
]

# Combined scopes for all supported Google Workspace operations
SCOPES = list(set(BASE_SCOPES + CALENDAR_SCOPES + DRIVE_SCOPES + GMAIL_SCOPES + [DRIVE_FILE_SCOPE])) # Add DRIVE_FILE_SCOPE and GMAIL_SCOPES

Copilot AI May 12, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a set to combine scopes may result in non-deterministic ordering, which could affect behavior if the order of scopes matters in downstream configuration. Consider sorting the resulting list for consistency.

Suggested change
SCOPES = list(set(BASE_SCOPES + CALENDAR_SCOPES + DRIVE_SCOPES + GMAIL_SCOPES + [DRIVE_FILE_SCOPE])) # Add DRIVE_FILE_SCOPE and GMAIL_SCOPES
SCOPES = sorted(set(BASE_SCOPES + CALENDAR_SCOPES + DRIVE_SCOPES + GMAIL_SCOPES + [DRIVE_FILE_SCOPE])) # Add DRIVE_FILE_SCOPE and GMAIL_SCOPES

Copilot uses AI. Check for mistakes.
@taylorwilsdon
taylorwilsdon merged commit ae2361f into main May 12, 2025
bigl34 pushed a commit to bigl34/google_workspace_mcp that referenced this pull request Feb 5, 2026
…mail

feat: Add Support for Google Drive and Gmail Operations
seidnerj added a commit to seidnerj/google_workspace_mcp that referenced this pull request Jun 24, 2026
taylorwilsdon#1 gmail_tools.py: remove contacts/thread fallback for sender From-name;
   sender name is Send-As only — bare address is correct degradation.

taylorwilsdon#2 gmail_web_mime.py: pass maxlinelen=998 to Header.encode() so long
   non-ASCII display names are not folded with CR/LF, preventing ValueError
   in _safe_header for long CJK or similar names.

taylorwilsdon#3 gmail_web_mime.py: escape date_str through _escape_body() in the
   forwarded-message attr block; all other fields were already escaped.

taylorwilsdon#4 gmail_web_mime.py: drop ord("_") from _QP_SAFE exclusion set so
   underscore-heavy ASCII content is correctly classified as quoted-printable
   rather than base64.

taylorwilsdon#5 test_gmail_web_mime.py: tighten BOUNDARY_RE to exactly 16 hex chars
   (was 16–18), matching the documented gmail_boundary() output format.

taylorwilsdon#6 golden_skeleton.py: broaden EMAIL_RE to cover RFC 5321 special chars in
   the local part (apostrophe, bang, etc.) so o'hara@example.com is fully
   redacted rather than partially matched.

taylorwilsdon#7 golden_skeleton.py: change _class_stack to list[set[str]] and test
   membership via set intersection, so multi-class markup like
   class="gmail_attr extra" correctly suppresses inner attribution text.

Tests: add focused tests for each behavioral fix (taylorwilsdon#1taylorwilsdon#4, taylorwilsdon#6taylorwilsdon#7).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants