gmail_list_unread
Retrieve unread emails from your Gmail inbox, with optional filtering by categories like financial, action_required, kids, or navy to organize messages.
Instructions
List unread emails from the inbox. Optionally filter by a pre-configured category such as navy, kids, financial, or action_required.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Filter by category name. Must be one of: navy, kids, financial, action_required. Leave empty for all unread emails. | |
| max_results | No | Maximum number of emails to return. Default is 20. |
Implementation Reference
- src/mcp_gmail/server.py:499-508 (handler)Primary handler logic for the 'gmail_list_unread' tool. Parses input arguments, constructs a SearchQuery object with is_unread=True and optional category filter, invokes GmailClient.list_emails, formats the results using _format_email_list, and returns as TextContent.elif name == "gmail_list_unread": category = arguments.get("category") max_results = arguments.get("max_results", 20) search = SearchQuery( is_unread=True, category=category, max_results=max_results, ) results = await client.list_emails(search) return [TextContent(type="text", text=_format_email_list(results))]
- src/mcp_gmail/server.py:76-93 (schema)JSON schema definition for the 'gmail_list_unread' tool inputs: optional 'category' (string enum) and 'max_results' (integer). Defines the tool interface for MCP clients.Tool( name="gmail_list_unread", description="List unread emails from the inbox. Optionally filter by a pre-configured category such as navy, kids, financial, or action_required.", inputSchema={ "type": "object", "properties": { "category": { "type": "string", "description": "Filter by category name. Must be one of: navy, kids, financial, action_required. Leave empty for all unread emails." }, "max_results": { "type": "integer", "description": "Maximum number of emails to return. Default is 20." } }, "required": [] }, ),
- src/mcp_gmail/server.py:1128-1131 (registration)Registers all tools including 'gmail_list_unread' by returning the predefined GMAIL_TOOLS list from the list_tools handler decorated with @server.list_tools().@server.list_tools() async def list_tools() -> list[Tool]: return GMAIL_TOOLS
- Core helper method implementing the email listing logic. Builds Gmail API search query (adds 'is:unread' if specified), fetches messages, parses into EmailSummary, applies category filtering post-fetch, handles API errors.async def list_emails(self, search: SearchQuery) -> list[EmailSummary]: """List emails matching search criteria.""" query = self._build_query(search) logger.info(f"Searching emails with query: {query}") try: results = ( self.service.users() .messages() .list(userId="me", q=query, maxResults=search.max_results) .execute() ) messages = results.get("messages", []) if not messages: return [] # Fetch each message's metadata summaries = [] for msg_ref in messages: msg = ( self.service.users() .messages() .get(userId="me", id=msg_ref["id"], format="metadata") .execute() ) email = self._parse_message(msg) # Filter by category if specified if search.category: if search.category not in email.categories: continue summaries.append(self._email_to_summary(email)) return summaries except HttpError as e: logger.error(f"Failed to list emails: {e}") raise
- src/mcp_gmail/models.py:98-111 (schema)Pydantic model defining the SearchQuery used by the tool, including fields like category, is_unread, and max_results for structured query building and validation.class SearchQuery(BaseModel): """Search query parameters.""" query: Optional[str] = Field(default=None, description="Gmail search query") sender: Optional[str] = Field(default=None, description="Filter by sender") subject: Optional[str] = Field(default=None, description="Filter by subject") labels: list[str] = Field(default_factory=list, description="Filter by labels") category: Optional[str] = Field(default=None, description="Filter by our category") is_unread: Optional[bool] = Field(default=None, description="Filter by read status") has_attachment: Optional[bool] = Field(default=None) after_date: Optional[datetime] = Field(default=None) before_date: Optional[datetime] = Field(default=None) max_results: int = Field(default=20, ge=1, le=100)