gmail
Send, search, and organize Gmail messages, drafts, and labels. Read full threads and get shareable Google Groups permalinks. Use when asked to compose an email, reply to mail, forward a message, search inbox, manage attachments, organize Gmail, read a thread, or find a Google Groups discussion link.
Works with
---
name: gmail
description: Send, search, and organize Gmail messages, drafts, and labels. Read full threads and get shareable Google Groups permalinks. Use when asked to compose an email, reply to mail, forward a message, search inbox, manage attachments, organize Gmail, read a thread, or find a Google Groups discussion link.
license: MIT
---
# Gmail
Interact with Gmail for email management, search, and organization.
## Installation
**Dependencies**: `pip install --user google-auth google-auth-oauthlib google-api-python-client keyring pyyaml`
## Setup Verification
After installation, verify the skill is properly configured:
```bash
$SKILL_DIR/scripts/gmail.py check
```
This will check:
- Python dependencies (google-auth, google-auth-oauthlib, google-api-python-client, keyring, pyyaml)
- Authentication configuration
- Connectivity to Gmail API
If anything is missing, the check command will provide setup instructions.
## Authentication
Gmail uses OAuth 2.0 for authentication. For complete setup instructions, see:
1. [GCP Project Setup Guide](https://github.com/odyssey4me/agent-skills/blob/main/docs/gcp-project-setup.md) - Create project, enable Gmail API
2. [Google OAuth Setup Guide](https://github.com/odyssey4me/agent-skills/blob/main/docs/google-oauth-setup.md) - Configure credentials
### Quick Start
1. Create `~/.config/agent-skills/google.yaml`:
```yaml
oauth_client:
client_id: your-client-id.apps.googleusercontent.com
client_secret: your-client-secret
```
2. Run `$SKILL_DIR/scripts/gmail.py check` to trigger OAuth flow and verify setup.
On scope or authentication errors, see the [OAuth troubleshooting guide](https://github.com/odyssey4me/agent-skills/blob/main/docs/google-oauth-setup.md#troubleshooting).
## Commands
See [permissions.md](references/permissions.md) for read/write classification of each command.
### check
Verify configuration and connectivity.
```bash
$SKILL_DIR/scripts/gmail.py check
```
This validates:
- Python dependencies are installed
- Authentication is configured
- Can connect to Gmail API
- Displays your email address and mailbox statistics
### auth setup
Store OAuth 2.0 client credentials for custom OAuth flow.
```bash
$SKILL_DIR/scripts/gmail.py auth setup \
--client-id YOUR_CLIENT_ID \
--client-secret YOUR_CLIENT_SECRET
```
Credentials are saved to `~/.config/agent-skills/gmail.yaml`.
### auth reset
Clear stored OAuth token. The next command that needs authentication will trigger re-authentication automatically.
```bash
$SKILL_DIR/scripts/gmail.py auth reset
```
Use this when you encounter scope or authentication errors.
### auth status
Show current OAuth token information without making API calls.
```bash
$SKILL_DIR/scripts/gmail.py auth status
```
Displays: whether a token is stored, granted scopes, refresh token presence, token expiry, and client ID.
### messages list
List messages matching a query.
```bash
# List recent messages
$SKILL_DIR/scripts/gmail.py messages list
# Search for unread messages
$SKILL_DIR/scripts/gmail.py messages list --query "is:unread"
# Search with max results
$SKILL_DIR/scripts/gmail.py messages list --query "from:user@example.com" --max-results 20
```
**Arguments:**
- `--query`: Gmail search query (optional)
- `--max-results`: Maximum number of results (default: 10)
**Search Query Examples:**
For complete Gmail search syntax, see [gmail-queries.md](references/gmail-queries.md).
Common queries:
- `is:unread` - Unread messages
- `from:user@example.com` - Messages from sender
- `subject:meeting` - Messages with subject keyword
- `has:attachment` - Messages with attachments
- `after:2024/01/01` - Messages after date
- `label:important` - Messages with label
### messages get
Get a message by ID.
```bash
# Get full message
$SKILL_DIR/scripts/gmail.py messages get MESSAGE_ID
# Get minimal format
$SKILL_DIR/scripts/gmail.py messages get MESSAGE_ID --format minimal
```
**Arguments:**
- `message_id`: The message ID (required)
- `--format`: Message format (full, minimal, raw, metadata) - default: full
### messages mark-read
Mark one or more messages as read by removing the UNREAD label.
```bash
# Mark a single message
$SKILL_DIR/scripts/gmail.py messages mark-read MESSAGE_ID
# Mark multiple messages
$SKILL_DIR/scripts/gmail.py messages mark-read MSG1 MSG2 MSG3
# Mark all unread messages from a sender
$SKILL_DIR/scripts/gmail.py messages mark-read --query "is:unread from:user@example.com"
# Combine IDs and query
$SKILL_DIR/scripts/gmail.py messages mark-read MSG1 --query "is:unread label:updates"
```
**Arguments:**
- `message_ids`: One or more message IDs (optional if `--query` is used)
- `--query`: Gmail search query to find messages to mark as read
- `--max-results`: Maximum messages to mark from `--query` (default: 100)
### threads get
Get a full conversation thread with all messages displayed chronologically. For messages from Google Groups, includes shareable permalinks using the `d/msgid` URL format.
```bash
# Get full thread
$SKILL_DIR/scripts/gmail.py threads get THREAD_ID
```
**Arguments:**
- `thread_id`: The thread ID (required)
### send
Send an email message.
```bash
# Send simple email
$SKILL_DIR/scripts/gmail.py send \
--to recipient@example.com \
--subject "Hello" \
--body "This is the message body"
# Send with CC and BCC
$SKILL_DIR/scripts/gmail.py send \
--to recipient@example.com \
--subject "Team Update" \
--body "Here's the update..." \
--cc team@example.com \
--bcc boss@example.com
```
```bash
# Send from a markdown file with frontmatter
$SKILL_DIR/scripts/gmail.py send --from-file update.md
# Send from file with CLI overrides
$SKILL_DIR/scripts/gmail.py send --from-file update.md --to override@example.com
# Reply to a message in-thread
$SKILL_DIR/scripts/gmail.py send --reply-to MESSAGE_ID --body "Thanks, got it."
```
**Arguments:**
- `--to`: Recipient email address (required unless in `--from-file` or `--reply-to`)
- `--subject`: Email subject (required unless in `--from-file` or `--reply-to`)
- `--body`: Email body text (required unless in `--from-file`)
- `--from-file`: Markdown file with YAML frontmatter (see format below)
- `--cc`: CC recipients (comma-separated)
- `--bcc`: BCC recipients (comma-separated)
- `--reply-to`: Message ID to reply to (sends in-thread, auto-fills to/subject)
CLI flags override frontmatter values. When using `--from-file`, the markdown
body is converted to HTML and sent as multipart/alternative (HTML + plain text
fallback).
**Markdown file format:**
```markdown
---
to: recipient@example.com
cc: team@example.com
bcc: boss@example.com
subject: Weekly Update
---
# Status Update
Here's what happened this week:
- **Feature A** shipped to production
- Fixed the [login bug](https://jira.example.com/DEMO-123)
| Task | Status |
|------|--------|
| Deploy | Done |
```
### drafts list
List draft messages.
```bash
# List drafts
$SKILL_DIR/scripts/gmail.py drafts list
# List with custom max results
$SKILL_DIR/scripts/gmail.py drafts list --max-results 20
```
**Arguments:**
- `--max-results`: Maximum number of results (default: 10)
### drafts create
Create a draft email.
```bash
# Create draft
$SKILL_DIR/scripts/gmail.py drafts create \
--to recipient@example.com \
--subject "Draft Subject" \
--body "This is a draft message"
# Create draft with CC
$SKILL_DIR/scripts/gmail.py drafts create \
--to recipient@example.com \
--subject "Meeting Notes" \
--body "Notes from today's meeting..." \
--cc team@example.com
# Create a reply draft in-thread
$SKILL_DIR/scripts/gmail.py drafts create --reply-to MESSAGE_ID --body "I'll look into this."
```
```bash
# Create draft from a markdown file
$SKILL_DIR/scripts/gmail.py drafts create --from-file update.md
```
**Arguments:**
- `--to`: Recipient email address (required unless in `--from-file`)
- `--subject`: Email subject (required unless in `--from-file`)
- `--body`: Email body text (required unless in `--from-file`)
- `--from-file`: Markdown file with YAML frontmatter (same format as `send`)
- `--cc`: CC recipients (comma-separated)
- `--bcc`: BCC recipients (comma-separated)
### drafts send
Send a draft message.
```bash
# Send draft by ID
$SKILL_DIR/scripts/gmail.py drafts send DRAFT_ID
```
**Arguments:**
- `draft_id`: The draft ID to send (required)
### labels list
List all Gmail labels.
```bash
# List labels
$SKILL_DIR/scripts/gmail.py labels list
```
### labels create
Create a new label.
```bash
# Create label
$SKILL_DIR/scripts/gmail.py labels create "Project X"
```
**Arguments:**
- `name`: Label name (required)
## Examples
### Verify Setup
```bash
$SKILL_DIR/scripts/gmail.py check
```
### Find unread emails
```bash
$SKILL_DIR/scripts/gmail.py messages list --query "is:unread"
```
### Search for emails from a sender
```bash
$SKILL_DIR/scripts/gmail.py messages list --query "from:boss@example.com" --max-results 5
```
### Send a quick email
```bash
$SKILL_DIR/scripts/gmail.py send \
--to colleague@example.com \
--subject "Quick Question" \
--body "Do you have time for a meeting tomorrow?"
```
### Create and send a draft
```bash
# Create draft
$SKILL_DIR/scripts/gmail.py drafts create \
--to team@example.com \
--subject "Weekly Update" \
--body "Here's this week's update..."
# List drafts to get the ID
$SKILL_DIR/scripts/gmail.py drafts list
# Send the draft
$SKILL_DIR/scripts/gmail.py drafts send DRAFT_ID
```
### Organize with labels
```bash
# Create a label
$SKILL_DIR/scripts/gmail.py labels create "Project Alpha"
# List all labels
$SKILL_DIR/scripts/gmail.py labels list
```
### Advanced searches
```bash
# Find emails with attachments from last week
$SKILL_DIR/scripts/gmail.py messages list --query "has:attachment newer_than:7d"
# Find important emails from specific sender
$SKILL_DIR/scripts/gmail.py messages list --query "from:ceo@example.com is:important"
# Find emails in a conversation
$SKILL_DIR/scripts/gmail.py messages list --query "subject:project-alpha"
```
## Gmail Search Query Syntax
Common search operators:
| Operator | Description | Example |
|----------|-------------|---------|
| `from:` | Sender email | `from:user@example.com` |
| `to:` | Recipient email | `to:user@example.com` |
| `subject:` | Subject contains | `subject:meeting` |
| `label:` | Has label | `label:important` |
| `has:attachment` | Has attachment | `has:attachment` |
| `is:unread` | Unread messages | `is:unread` |
| `is:starred` | Starred messages | `is:starred` |
| `after:` | After date | `after:2024/01/01` |
| `before:` | Before date | `before:2024/12/31` |
| `newer_than:` | Newer than period | `newer_than:7d` |
| `older_than:` | Older than period | `older_than:30d` |
Combine operators with spaces (implicit AND) or `OR`:
```bash
# AND (implicit)
from:user@example.com subject:meeting
# OR
from:user@example.com OR from:other@example.com
# Grouping with parentheses
(from:user@example.com OR from:other@example.com) subject:meeting
```
For the complete reference, see [gmail-queries.md](references/gmail-queries.md).
## Error Handling
**Authentication and scope errors are not retryable.** If a command fails with an authentication error, insufficient scope error, or permission denied error (exit code 1), **stop and inform the user**. Do not retry or attempt to fix the issue autonomously — these errors require user interaction (browser-based OAuth consent). Point the user to the [OAuth troubleshooting guide](https://github.com/odyssey4me/agent-skills/blob/main/docs/google-oauth-setup.md#troubleshooting).
**Retryable errors**: Rate limiting (HTTP 429) and temporary server errors (HTTP 5xx) may succeed on retry after a brief wait. All other errors should be reported to the user.
## Model Guidance
This skill makes API calls requiring structured input/output. A standard-capability model is recommended.More General & Other skills
find-skills
vercel-labs/skills
Helps users discover and install agent skills when they ask questions like "how do I do X", "find a skill for X", "is there a skill that can...", or express interest in extending capabilities. This skill should be used when the user is looking for functionality that might exist as an installable skill.
grill-me
mattpocock/skills
A relentless interview to sharpen a plan or design.
grill-with-docs
mattpocock/skills
A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go.

