Gmail
September 7, 2026 · View on GitHub
Give your agents Gmail access.
Usage
Option 1: Import directly
from connectonion import Gmail
agent = Agent("assistant", tools=[Gmail()])
Option 2: Copy and customize
co copy gmail
from tools.gmail import Gmail # Your local copy
Quick Start
from connectonion import Agent, Gmail
gmail = Gmail()
agent = Agent("assistant", tools=[gmail])
agent.input("Show me my recent emails")
agent.input("Find emails from alice@example.com")
Setup
co auth google
Your agent can now read and manage Gmail.
Switch accounts? Run co auth google again to connect a different Google account.
Agent Methods
Reading
read_inbox(last=10, unread=False)
- Read emails from inbox
last: Number of emails (default: 10)unread: Only unread emails (default: False)
get_sent_emails(max_results=10)
- Get emails you sent
get_all_emails(max_results=50)
- Get emails from all folders (inbox, sent, archive)
list_inbox(last=10, unread=False)
- Same fetch as
read_inbox()but returns a list of dicts instead of text - Each dict:
{id, from, subject, date, snippet, unread} - Use this when your code needs the data; use
read_inbox()when an agent needs something readable
Search
search_emails(query, max_results=10)
- Search using Gmail query syntax
- Examples:
"from:alice@example.com","subject:meeting","is:unread has:attachment"
list_search(query, max_results=10)
- Same search, returned as dicts in the same shape as
list_inbox()
Content
get_email_body(email_id)
- Get full email content
get_email_attachments(email_id)
- List attachments (filename, size)
Actions
send(to, subject, body, cc=None, bcc=None, attachments=None)
- Send plain-text mail, optionally attaching a list of files
- Agent-facing
Gmail()instances can attach only files inside the current project; resolved symlinks cannot escape it - Attachments have a 25 MB combined limit, enforced before file contents are read
Drafts
Draft methods edit provider-native Gmail drafts and never send them. The
terminal's co gmail draft review and send --confirm commands bind the final
send to reviewed content; draft sending is intentionally not exposed as a public agent
method.
list_drafts(last=20)
- List draft IDs, recipients, subjects, and attachment counts
create_draft(to, subject, body, cc=None, bcc=None)
- Create and return an unsent draft
get_draft(draft_id)
- Return recipients, body, and the exact attachment manifest
add_draft_attachment(draft_id, path)
- Stage a local project file; the draft remains unsent
- Uses the same path and 25 MB protections as
send()
add_draft_link(draft_id, name, url)
- Append a link to a plain-text body; this does not change sharing permissions
remove_draft_attachment(draft_id, attachment)
- Remove the current one-based item number from
get_draft()["items"](files then managed links)
replace_draft_attachment(draft_id, attachment, path)
- Replace one attachment with a local project file in one draft update
mark_read(email_id)
- Mark email as read
mark_unread(email_id)
- Mark email as unread
archive_email(email_id)
- Archive email (remove from inbox)
star_email(email_id)
- Add star to email
Labels
get_labels()
- List all Gmail labels
add_label(email_id, label)
- Add label to email
get_emails_with_label(label, max_results=10)
- Get emails with specific label
Stats
count_unread()
- Count unread emails
CRM
get_all_contacts(max_emails=500)
- Extract all unique contacts from emails
- Fast regex-based extraction
- Returns list of contacts with email and name
analyze_contact(email, max_emails=50)
- Analyze specific contact using LLM
- Provides relationship context, topics, patterns, tags
- Example:
gmail.analyze_contact("alice@example.com")
Example
from connectonion import Agent, Gmail, Memory
gmail = Gmail()
memory = Memory()
agent = Agent(
name="email-assistant",
tools=[gmail, memory],
system_prompt="You help manage emails and remember important info."
)
agent.input("Check unread emails and save important deadlines to memory")
agent.input("Archive all newsletter emails from this week")
Customizing
Need to modify Gmail's behavior? Copy the source to your project:
co copy gmail
Then import from your local copy:
# from connectonion import Gmail # Before
from tools.gmail import Gmail # After - customize freely!
From the terminal
The same tool backs co gmail, so anything your agent can do
you can do by hand:
co gmail # inbox
co gmail read 3 # open #3, preserve unread state
co gmail read 3 --mark-read # explicitly mark read
co gmail send bob@example.com "Hi" "Body text"
co gmail search "from:alice@example.com is:unread"
co gmail draft create bob@example.com "Report" "Please review."
co gmail draft list # choose the matching row; create prints an ID
co gmail draft attach <draft-id> report.pdf
co gmail draft review <draft-id> --json
co gmail draft send <draft-id> --confirm <review-token> --json
See Also
co gmail— the CLI wrapper- GDrive — the same shape for Drive files
- Outlook — the equivalent for a Microsoft account
Troubleshooting
Missing gmail.readonly scope: Run co auth google
Credentials not found: Run co auth google
In the 1.8.4 candidate, get_draft() adds an items source manifest while
preserving file-only attachments. Local files are tagged as local; existing
untagged files are external. The CLI records Drive exports and managed links
inside provider MIME. The older add_draft_link(name, url) remains an ordinary
body append and does not claim verified Drive provenance. No draft send method
is exposed as an agent tool. See draft review behavior.