gmail_get_email
Retrieve complete email content including subject, sender, recipients, date, labels, and body text using a Gmail message ID.
Instructions
Get the full content of a specific email by its Gmail message ID. Returns subject, sender, recipients, date, labels, and full body text.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| email_id | Yes | The Gmail message ID obtained from search or list results. |
Implementation Reference
- src/mcp_gmail/server_old.py:87-100 (schema)Input schema definition for the 'gmail_get_email' tool, specifying the required 'email_id' parameter.Tool( name="gmail_get_email", description="Get the full content of a specific email by its ID", inputSchema={ "type": "object", "properties": { "email_id": { "type": "string", "description": "The Gmail message ID", }, }, "required": ["email_id"], }, ),
- src/mcp_gmail/server_old.py:322-332 (handler)The main handler in the MCP server's call_tool function that executes the 'gmail_get_email' tool by retrieving the email via GmailClient and formatting it for response.elif name == "gmail_get_email": email_id = arguments.get("email_id") if not email_id: return [TextContent(type="text", text="Error: email_id is required")] email = await client.get_email(email_id) return [ TextContent( type="text", text=_format_full_email(email), ) ]
- src/mcp_gmail/gmail_client.py:264-277 (handler)Core implementation in GmailClient that fetches the full email from Gmail API using users.messages.get and parses it into an Email object.async def get_email(self, message_id: str) -> Email: """Get a single email by ID with full content.""" try: msg = ( self.service.users() .messages() .get(userId="me", id=message_id, format="full") .execute() ) return self._parse_message(msg, include_body=True) except HttpError as e: logger.error(f"Failed to get email {message_id}: {e}") raise
- src/mcp_gmail/server_old.py:752-777 (helper)Helper function used by the handler to format the retrieved email into a readable text response.def _format_full_email(email) -> str: """Format full email for display.""" categories = f"Categories: {', '.join(email.categories)}" if email.categories else "" attachments = "" if email.attachments: att_list = ", ".join(a.filename for a in email.attachments) attachments = f"\nAttachments: {att_list}" body = email.body_text or "(No text content)" if len(body) > 2000: body = body[:2000] + "\n\n... [truncated]" return f""" **Subject:** {email.subject} **From:** {email.sender} **To:** {', '.join(str(t) for t in email.to)} **Date:** {email.date.strftime('%Y-%m-%d %H:%M:%S')} **Labels:** {', '.join(email.labels)} {categories} {attachments} --- {body} """
- Helper function in GmailClient that parses the raw Gmail API message into a structured Email object, including body extraction, categorization, and metadata parsing.def _parse_message(self, msg: dict, include_body: bool = False) -> Email: """Parse Gmail API message into Email model.""" payload = msg.get("payload", {}) headers = payload.get("headers", []) # Parse date date_str = self._get_header(headers, "Date") try: date = parsedate_to_datetime(date_str) except Exception: # Fallback to internal date internal_date = int(msg.get("internalDate", 0)) / 1000 date = datetime.fromtimestamp(internal_date, tz=timezone.utc) # Parse labels label_ids = msg.get("labelIds", []) is_read = "UNREAD" not in label_ids is_starred = "STARRED" in label_ids is_important = "IMPORTANT" in label_ids # Extract body if requested text_body, html_body = None, None if include_body: text_body, html_body = self._extract_body(payload) # Extract attachments attachments = self._extract_attachments(payload) email = Email( id=msg["id"], thread_id=msg["threadId"], subject=self._get_header(headers, "Subject") or "(No Subject)", snippet=msg.get("snippet", ""), body_text=text_body, body_html=html_body, sender=self._parse_email_address(self._get_header(headers, "From")), to=self._parse_email_addresses(self._get_header(headers, "To")), cc=self._parse_email_addresses(self._get_header(headers, "Cc")), reply_to=self._parse_email_address(self._get_header(headers, "Reply-To")) if self._get_header(headers, "Reply-To") else None, date=date, labels=label_ids, is_read=is_read, is_starred=is_starred, is_important=is_important, attachments=attachments, has_attachments=len(attachments) > 0, ) # Categorize email.categories = self._categorize_email(email) email.priority = self._get_priority(email.categories) return email