-
Notifications
You must be signed in to change notification settings - Fork 237
Add Gmail attachment support with ephemeral ID handling #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add Gmail attachment support with ephemeral ID handling #237
Conversation
This commit adds comprehensive Gmail attachment functionality: 1. New helper function `_extract_attachments()`: - Recursively extracts attachment metadata from message payloads - Returns filename, mimeType, size, and attachmentId for each attachment 2. Enhanced `get_gmail_message_content()`: - Now displays attachment information when present - Shows attachment ID needed for downloading 3. New tool `get_gmail_attachment_content()`: - Downloads email attachments via Gmail API - Returns base64-encoded attachment data - Handles ephemeral attachment ID issue correctly Key technical insight: Gmail attachment IDs are ephemeral and change between API calls for the same message. To avoid ID mismatches, the download function uses the attachment ID provided by the caller directly without refetching the message, as refetching would generate new IDs that don't match the original ID. The attachment download endpoint returns size information directly, while filename and mime type should be obtained from the initial message fetch that provided the attachment ID.
Removed f-string prefixes from strings without placeholders in get_gmail_attachment_content function (lines 672, 675, 677, 678, 679). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
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 comprehensive Gmail attachment functionality to the MCP server, enabling users to list and download email attachments while properly handling Gmail's ephemeral attachment ID behavior.
Key Changes:
- New helper function
_extract_attachments()recursively extracts attachment metadata from Gmail message payloads - Enhanced
get_gmail_message_content()now displays attachment information with download instructions - New tool
get_gmail_attachment_content()downloads email attachments and returns base64-encoded data
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
gmail/gmail_tools.py
Outdated
| return "[No readable content found]" | ||
|
|
||
|
|
||
| def _extract_attachments(payload: dict) -> List[Dict[str, any]]: |
Copilot
AI
Oct 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrected type hint from 'any' to 'Any' (should be capitalized as it's from the typing module).
| service.users() | ||
| .messages() | ||
| .attachments() | ||
| .get(userId="me", messageId=message_id, id=attachment_id) | ||
| .execute |
Copilot
AI
Oct 17, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing parentheses for method call. Should be .execute() instead of .execute to actually invoke the method.
| service.users() | |
| .messages() | |
| .attachments() | |
| .get(userId="me", messageId=message_id, id=attachment_id) | |
| .execute | |
| lambda: service.users() | |
| .messages() | |
| .attachments() | |
| .get(userId="me", messageId=message_id, id=attachment_id) | |
| .execute() |
|
Hi All. What is the status of this PR? Really looking for GMAIL attachment support. |
…into fix-gmail-attachment-ephemeral-ids
Has some outstanding little bits to address, one sec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| .messages() | ||
| .attachments() | ||
| .get(userId="me", messageId=message_id, id=attachment_id) | ||
| .execute |
Copilot
AI
Oct 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing parentheses for method call. Should be .execute() to actually invoke the method.
| .execute | |
| .execute() |
| f"Message ID: {message_id}", | ||
| f"Size: {size_kb:.1f} KB ({size_bytes} bytes)", | ||
| "\nBase64-encoded content (first 100 characters shown):", | ||
| f"{attachment['data'][:100]}...", |
Copilot
AI
Oct 23, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential KeyError if 'data' key is missing from attachment response. Add a guard with .get('data', '') to handle cases where the attachment download fails but doesn't raise an exception.
| f"{attachment['data'][:100]}...", | |
| f"{attachment.get('data', '')[:100]}...", |
|
Thanks man. Looking forward to this |
Summary
This PR adds comprehensive Gmail attachment functionality to the MCP server, enabling users to list and download email attachments.
Changes
New helper function
_extract_attachments()Enhanced
get_gmail_message_content()New tool
get_gmail_attachment_content()Key Technical Insight
Gmail attachment IDs are ephemeral and change between API calls for the same message. This PR addresses this by:
If we refetch the message to get metadata, the new attachment IDs won't match the original ID parameter, causing downloads to fail. The attachment download endpoint returns size information directly, making message refetch unnecessary.
Testing
Tested with real Gmail messages containing various attachment types (PDFs, images, etc.). The implementation successfully:
Related Issues
Fixes attachment download functionality that was previously failing with "Could not find attachment metadata" errors.