Gmail Skill
Gmail API integration skill. Provides OAuth 2.0 authentication, read/send email, and label management.
Prerequisites
1. Google Cloud Console Setup
- •Open https://console.cloud.google.com/
- •Select or create a project
- •Go to APIs & Services > Library
- •Search for Gmail API and click Enable
2. Create OAuth Credentials
- •Go to APIs & Services > Credentials
- •Create Credentials > OAuth client ID
- •Application type: Desktop app
- •Name: Gmail CLI (or any name)
- •Click Create
3. Download Credentials
- •On the created OAuth client, click Download JSON
- •Save the file to
C:\claude\json\desktop_credentials.json
File structure example:
json
{
"installed": {
"client_id": "xxx.apps.googleusercontent.com",
"client_secret": "xxx",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"redirect_uris": ["http://localhost"]
}
}
4. OAuth Consent Screen
- •APIs & Services > OAuth consent screen
- •User Type: External (or Internal if Google Workspace)
- •Fill in App name, User support email, Developer contact
- •Scopes: add
gmail.readonly,gmail.send,gmail.modify - •Test users: add your own email (if in test mode)
5. Run Authentication
powershell
cd C:\claude && python -m lib.gmail login
- •A browser opens showing the Google account selector
- •After consent, the token is saved automatically
- •Token location:
C:\claude\json\token_gmail.json
Commands
| Command | Description |
|---|---|
python -m lib.gmail login | OAuth login (first-time only) |
python -m lib.gmail status | Check auth status |
python -m lib.gmail inbox | View inbox |
python -m lib.gmail unread | View unread mail |
python -m lib.gmail read <email_id> | Read email details |
python -m lib.gmail send <to> <subject> <body> | Send email |
python -m lib.gmail search <query> | Search emails |
python -m lib.gmail labels | List labels |
python -m lib.gmail mark-read <email_id> | Mark as read |
python -m lib.gmail archive <email_id> | Archive |
python -m lib.gmail trash <email_id> | Move to trash |
Usage Examples
Inbox
powershell
# 10 most recent python -m lib.gmail inbox # 20 most recent (JSON output) python -m lib.gmail inbox --limit 20 --json
Unread
powershell
# List unread python -m lib.gmail unread # JSON output python -m lib.gmail unread --json
Search
powershell
# From a specific sender python -m lib.gmail search "from:boss@company.com" # Subject contains keyword python -m lib.gmail search "subject:meeting" # With attachments python -m lib.gmail search "has:attachment" # Date range python -m lib.gmail search "after:2024/01/01 before:2024/12/31" # Combined search python -m lib.gmail search "from:client@example.com subject:invoice has:attachment"
Send
powershell
# Plain text python -m lib.gmail send "recipient@example.com" "Meeting agenda" "Please attend tomorrow at 3pm." # With CC python -m lib.gmail send "recipient@example.com" "Weekly report" "See attached" --cc "manager@example.com" # HTML mail python -m lib.gmail send "recipient@example.com" "Notice" "<h1>Notice</h1><p>Details...</p>" --html
Read Details
powershell
# By email ID python -m lib.gmail read "18d5f7c8e9a0b123" # Mark as read as well python -m lib.gmail read "18d5f7c8e9a0b123" --mark-read
Python API
python
from lib.gmail import GmailClient, login, get_token
# Auth (first time)
login()
# Create client
client = GmailClient()
# Inbox
emails = client.list_emails(query="in:inbox", max_results=10)
for email in emails:
print(f"{email.sender}: {email.subject}")
# Unread
unread = client.list_emails(query="is:unread", max_results=5)
# Search
results = client.list_emails(query="from:boss@company.com", max_results=20)
# Send
result = client.send(
to="recipient@example.com",
subject="Hello",
body="Email body."
)
print(f"Sent: {result.permalink}")
# Reply
client.reply(email_id="...", body="Reply content")
# Labels
labels = client.list_labels()
client.modify_labels(email_id, add_labels=["STARRED"])
# Read/unread
client.mark_as_read(email_id)
client.mark_as_unread(email_id)
# Archive/trash
client.archive(email_id)
client.trash(email_id)
Claude Mandatory Execution Rules (MANDATORY)
When Gmail keywords are detected, Claude MUST do the following automatically.
Step 1: Check auth status (always first)
powershell
cd C:\claude && python -m lib.gmail status --json
Result interpretation:
- •
"authenticated": true, "valid": true-> proceed to Step 2 - •
"authenticated": false-> instruct the user to log in:codeGmail authentication required. Run: python -m lib.gmail login
Step 2: Run command for the request
| User Request | Command to Run |
|---|---|
| "메일 확인해줘" | python -m lib.gmail inbox --json |
| "안읽은 메일" | python -m lib.gmail unread --json |
| "메일 보내줘" | python -m lib.gmail send "addr" "subject" "body" |
| "메일 검색" | python -m lib.gmail search "query" --json |
| "라벨 목록" | python -m lib.gmail labels --json |
| "이 메일 읽어줘" | python -m lib.gmail read "ID" --json |
Step 3: Parse JSON result and respond
Parse the --json flag output and present to the user in a readable form.
Example — unread mail:
json
{"count": 3, "emails": [{"id": "...", "subject": "Meeting agenda", "from": "boss@example.com", ...}]}
-> "You have 3 unread messages:\n1. boss@example.com - Meeting agenda\n2. ..."
Required (MUST)
| Rule | Description |
|---|---|
cd C:\claude && prefix | Run modules from project root |
Use --json flag | Easier result parsing |
| Use Bash tool directly | Execute lib/gmail CLI |
| Detailed guidance on errors | Auth steps, OAuth setup, etc. |
Prohibited (NEVER)
| Prohibited | Reason |
|---|---|
| Read gmail_token.json directly | Security risk |
| Call Gmail API via WebFetch | OAuth token required |
| Respond "no infrastructure" | CLI is directly runnable via Bash |
| Ask user to run manually | Claude should execute directly |
Gmail Search Query Syntax
| Filter | Query Example |
|---|---|
| Sender | from:example@gmail.com |
| Recipient | to:me@gmail.com |
| Subject | subject:meeting |
| Attachment | has:attachment |
| Unread | is:unread |
| Read | is:read |
| Starred | is:starred |
| Important | is:important |
| After date | after:2024/01/01 |
| Before date | before:2024/12/31 |
| Label | label:work |
| Inbox | in:inbox |
| Sent | in:sent |
| Spam | in:spam |
| Trash | in:trash |
Error Handling
| Error | Solution |
|---|---|
GmailCredentialsNotFoundError | Create desktop_credentials.json |
GmailAuthError | Re-run python -m lib.gmail login |
GmailRateLimitError | Retry after a moment |
| 403 Permission Denied | Check scopes on the OAuth Consent Screen |
File Locations
| File | Purpose |
|---|---|
C:\claude\json\desktop_credentials.json | OAuth client (user-created) |
C:\claude\json\token_gmail.json | Access token (auto-generated) |
C:\claude\lib\gmail\ | Library source code |
Rate Limits
Respects Gmail API 2026 rate limits:
- •Reads: 250 requests/sec
- •Sends: 100/min (standard account)
- •Bulk sends: Google Workspace account required
/auto Option Integration
The /auto --gmail option can inject Gmail context into a task.
code
/auto --gmail "Analyze recent client mail and draft replies" -> Step 1: Check Gmail auth -> Step 2: Search/fetch mail -> Step 3: Use analysis as context -> Step 4: Run main workflow
Security Notes
- •OAuth tokens are stored locally only
- •Auto-refresh via refresh_token
- •Re-authentication required upon expiry
- •credentials.json is never committed (.gitignore)