Gmail
Read, search, send, and organize Gmail messages with GmailTools using OAuth or a service account.
Gmail enables an Agent to interact with Gmail, allowing it to read, search, send, manage emails, and organize them with labels. Supports both OAuth and service account authentication.
Prerequisites
Install dependencies
uv pip install agno google-api-python-client google-auth-httplib2 google-auth-oauthlib openaiSet up Google OAuth
Follow the Gmail Python quickstart:
- Create or select a Google Cloud project and enable the Gmail API.
- Configure Google Auth Platform > Branding, including the app name and support contact.
- Under Audience, choose the appropriate Internal or External audience. For an external app in Testing, add the Google accounts that will authorize it as test users.
- Configure the required Gmail scopes under Data Access. Use
gmail.readonlyfor a tool selection that only reads mail; writing and composing require the corresponding Gmail scopes. - Under Clients, create a Desktop app OAuth client and download its JSON credentials.
- Pass its path as
credentials_path. The initial interactive sign-in stores access and refresh tokens intoken.jsonin the current directory, or at the writabletoken_pathyou supply.
For client credentials from environment variables, set GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and GOOGLE_PROJECT_ID. Publishing an external app with sensitive or restricted scopes may require Google's verification process.
Shared authentication and headless servers
Google toolkits accept one shared AuthConfig, which aggregates their scopes before authentication. For example:
from agno.tools.google.auth import AuthConfig
from agno.tools.google.gmail import GmailTools
auth = AuthConfig(interactive=False, http_timeout=60)
gmail = GmailTools(auth=auth)This headless configuration requires existing usable credentials or a delegated service account. Gmail tool calls return an authentication error if a browser sign-in would be needed; for the initial local OAuth flow, set interactive=True and provide your client credentials.
AuthConfig(db=...) can store tokens in a supported Agno database. Encryption is enabled by default and requires token_encryption_key or GOOGLE_TOKEN_ENCRYPTION_KEY. The stored Google token uses a shared provider identity (google, with no user ID); an agent's user_id does not choose a separate mailbox. Configure separate credential boundaries in applications that serve different Google accounts.
When using auth=, put service_account_path and delegated_user on AuthConfig. Passing them alongside auth= on GmailTools raises an error. See the AuthConfig source for its full configuration.
Service Account Authentication (Alternative)
For server/bot deployments without browser access:
- Create a service account at IAM & Admin > Service Accounts in Google Cloud Console
- Download the JSON key file
- Configure domain-wide delegation in Google Workspace Admin Console (required for Gmail)
- Set environment variables:
export GOOGLE_SERVICE_ACCOUNT_FILE=/path/to/service-account-key.json
export GOOGLE_DELEGATED_USER=user@yourdomain.com # Required for GmailExample
from agno.agent import Agent
from agno.tools.google.gmail import GmailTools
agent = Agent(tools=[GmailTools()])
agent.print_response("Show me my latest 5 unread emails", markdown=True)Quick Start Examples
# OAuth authentication (browser-based)
from agno.agent import Agent
from agno.tools.google.gmail import GmailTools
agent = Agent(
tools=[GmailTools(
credentials_path="path/to/credentials.json"
)],
instructions=["You help users manage their Gmail inbox."],
)
# Service account authentication (no browser needed)
agent = Agent(
tools=[GmailTools(
service_account_path="path/to/service-account.json",
delegated_user="user@domain.com" # Required for Gmail
)],
)Most list/search methods cap each requested page at max_results (default 20). Pass a returned nextPageToken as page_token to retrieve another page. This is not a cap on full-thread responses or label-operation batches.
Toolkit Params
| Parameter | Type | Default | Description |
|---|---|---|---|
auth | Optional[AuthConfig] | None | Shared Google authentication, scope aggregation, and optional database token storage; accepted through the shared base class. |
creds | Credentials | None | Pre-fetched credentials (OAuth or service account) to skip auth flow |
credentials_path | str | None | Path to OAuth credentials JSON file |
token_path | str | None | Path to token file for storing access/refresh tokens |
service_account_path | str | None | Path to service account JSON key. When set, OAuth is skipped |
delegated_user | str | None | Email to impersonate (required for Gmail with service account) |
scopes | List[str] | None | Custom OAuth scopes |
oauth_port | int | 0 | Port for the OAuth local server. 0 auto-selects a port |
login_hint | str | None | Email to pre-select in OAuth consent screen |
include_html | bool | False | Keep HTML when no plain-text body is available in get_message, get_thread, or get_draft. Legacy list/search helpers do not use this option. |
max_body_length | int | None | Body text limit for get_message, get_thread, and get_draft; legacy list/search helpers bypass it. |
attachment_dir | str | None | Directory to save downloaded attachments |
max_results | int | 20 | Default per-page cap for list/search methods; does not bound all tool output. |
max_batch_size | int | 10 | Max items per Gmail API batch request (max 100) |
get_latest_emails | bool | True | Enable get_latest_emails tool |
get_emails_from_user | bool | True | Enable get_emails_from_user tool |
get_unread_emails | bool | True | Enable get_unread_emails tool |
get_starred_emails | bool | True | Enable get_starred_emails tool |
get_emails_by_context | bool | True | Enable get_emails_by_context tool |
get_emails_by_date | bool | True | Enable get_emails_by_date tool |
get_emails_by_thread | bool | True | Enable get_emails_by_thread tool |
search_emails | bool | True | Enable search_emails tool |
mark_email_as_read | bool | True | Enable mark_email_as_read tool |
mark_email_as_unread | bool | True | Enable mark_email_as_unread tool |
star_email | bool | True | Enable star_email tool |
unstar_email | bool | True | Enable unstar_email tool |
archive_email | bool | False | Enable archive_email tool |
create_draft_email | bool | True | Enable create_draft_email tool |
send_email | bool | True | Enable send_email tool |
send_email_reply | bool | True | Enable send_email_reply tool |
list_custom_labels | bool | True | Enable list_custom_labels tool |
apply_label | bool | True | Enable apply_label tool |
remove_label | bool | True | Enable remove_label tool |
delete_custom_label | bool | True | Enable delete_custom_label tool |
get_message | bool | True | Enable get_message tool |
get_thread | bool | True | Enable get_thread tool |
search_threads | bool | True | Enable search_threads tool |
modify_thread_labels | bool | False | Enable modify_thread_labels tool |
trash_thread | bool | False | Enable trash_thread tool |
get_draft | bool | True | Enable get_draft tool |
list_drafts | bool | True | Enable list_drafts tool |
send_draft | bool | False | Enable send_draft tool |
update_draft | bool | True | Enable update_draft tool |
list_labels | bool | False | Enable list_labels tool |
modify_message_labels | bool | False | Enable modify_message_labels tool |
trash_message | bool | False | Enable trash_message tool |
download_attachment | bool | False | Enable download_attachment tool |
Toolkit Functions
Reading Emails
| Function | Description |
|---|---|
get_latest_emails | Get the latest emails across the mailbox (no implicit INBOX filter). Parameters: count (int), page_token (Optional[str]) |
get_emails_from_user | Get emails from a specific sender. Parameters: user (str), count (int), page_token (Optional[str]) |
get_unread_emails | Get unread emails. Parameters: count (int), page_token (Optional[str]) |
get_starred_emails | Get starred emails. Parameters: count (int), page_token (Optional[str]) |
get_emails_by_context | Get emails matching a context. Parameters: context (str), count (int), page_token (Optional[str]) |
get_emails_by_date | Get emails within a date range. Parameters: start_date (str), range_in_days (int), num_emails (int), page_token (Optional[str]) |
get_emails_by_thread | Get all emails from a thread. Parameters: thread_id (str) |
search_emails | Search using Gmail query syntax, forwarded unchanged. Parameters: query (str), count (int), page_token (Optional[str]) |
get_message | Get a specific message by ID. Parameters: message_id (str), download_attachments (bool) |
get_thread | Get all messages in a thread. Parameters: thread_id (str) |
search_threads | Search email threads. Parameters: query (str), count (int), page_token (Optional[str]) |
Managing Emails
| Function | Description |
|---|---|
mark_email_as_read | Mark email as read. Parameters: message_id (str) |
mark_email_as_unread | Mark email as unread. Parameters: message_id (str) |
star_email | Star an email. Parameters: message_id (str) |
unstar_email | Unstar an email. Parameters: message_id (str) |
archive_email | Archive an email. Parameters: message_id (str) |
trash_message | Move message to trash, or restore with undo. Parameters: message_id (str), undo (bool) |
trash_thread | Move thread to trash. Parameters: thread_id (str) |
download_attachment | Download email attachment. Parameters: message_id (str), attachment_id (str), filename (str) |
Composing & Sending
| Function | Description |
|---|---|
create_draft_email | Create draft with attachments. Parameters: to (str), subject (str), body (str), cc (str), bcc (str), attachments (str or List[str]), thread_id (str), message_id (str) |
send_email | Send email with attachments. Parameters: to (str), subject (str), body (str), cc (str), bcc (str), attachments (str or List[str]), thread_id (str), message_id (str) |
send_email_reply | Reply to email thread. Parameters: thread_id (str), message_id (str), to (str), subject (str), body (str), cc (str), attachments (str or List[str]) |
get_draft | Get draft by ID. Parameters: draft_id (str) |
list_drafts | List one page of draft IDs. Parameters: count (int), page_token (Optional[str]) |
send_draft | Send a draft. Parameters: draft_id (str) |
update_draft | Update draft content. Parameters: draft_id (str), to (str), subject (str), body (str), cc (str), bcc (str), attachments (str or List[str]), thread_id (str), message_id (str) |
Label Management
| Function | Description |
|---|---|
list_labels | List all labels in the account. No parameters |
list_custom_labels | List user-created labels. No parameters |
apply_label | Apply label to emails. Parameters: context (str), label_name (str), count (int) |
remove_label | Remove label from emails. Parameters: context (str), label_name (str), count (int) |
delete_custom_label | Delete a custom label. Parameters: label_name (str), confirm (bool) |
modify_message_labels | Modify message labels. Parameters: message_id (str), add_labels (str, comma-separated), remove_labels (str, comma-separated) |
modify_thread_labels | Modify thread labels. Parameters: thread_id (str), add_labels (str, comma-separated), remove_labels (str, comma-separated) |
You can use include_tools or exclude_tools to modify the list of tools the agent has access to. Learn more about selecting tools.
Cookbook Examples
The agno cookbook includes several Gmail examples demonstrating different use cases:
| Example | Description |
|---|---|
basic.py | Core examples: read-only agent, safe agent, label manager, full agent, thread reply |
daily_digest.py | Summarize recent emails into a structured daily digest grouped by priority |
draft_reply.py | Read a conversation thread and draft a contextual reply for human review |
inbox_triage.py | Personal inbox triage agent with Learning Machine for persistent preferences |
followup_tracker.py | Find unanswered sent emails, draft follow-ups |
action_items.py | Extract structured action items from email threads |
For send_email_reply, supply the recipient (to), subject, and body along with the original message/thread identifiers. The current validator still requires recipient and subject; a call with only message_id and body fails.
Tips for Using Gmail Tools
-
Authentication:
- Use OAuth for user-facing applications (requires browser)
- Use service accounts for server/bot deployments (requires domain-wide delegation)
-
Search Queries: Agent instructions guide the model to translate a request into Gmail syntax, such as
is:unread newer_than:7d. The Python tool forwards that query unchanged. -
Attachments: When sending emails with attachments, provide file paths as strings or a list of strings.
-
Thread Management: Use thread operations (
get_thread,trash_thread, etc.) to manage entire conversations. -
Label Operations: Gmail's label system is hierarchical - use forward slashes for nested labels (e.g., "Work/Projects").
-
Rate Limits: Be mindful of Gmail API quotas when performing bulk operations.