
Gmail
- 18 installs
- 44 repo stars
- Updated July 8, 2026
- aviz85/claude-skills-library
Gmail is a Claude skill that reads, sends, and manages emails, drafts, labels, and threads through Google's Gmail REST API using curl.
About
Gmail lets Claude read, send, and manage emails using Google's Gmail REST API over curl. A developer uses it to search messages with Gmail query syntax, send or reply to threads, and manage drafts, labels, and threads. It walks through the OAuth setup to obtain a refresh token and mint short-lived access tokens.
- Reads, sends, and manages emails, drafts, labels, and threads via the Gmail REST API
- Uses curl calls with an OAuth refresh-token flow to mint access tokens
- Documents Gmail query syntax for searching messages (is:unread, from:, has:attachment)
Gmail by the numbers
- 18 all-time installs (skills.sh)
- Ranked #1,366 of 2,719 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
gmail capabilities & compatibility
free (Gmail API within Google quotas)
- Capabilities
- email send · email read · email search · label management
- Works with
- gmail
- Use cases
- Pricing
- Bring your own API key
What gmail says it does
Read, send, and manage emails via Google's Gmail REST API.
Access tokens expire after 1 hour. Use refresh token to get a new one and save to `/tmp`:
Gmail API via curl. Use this skill to read, send, and manage emails, labels, drafts, and threads.
npx skills add https://github.com/aviz85/claude-skills-library --skill gmailAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 18 |
|---|---|
| repo stars | ★ 44 |
| Last updated | July 8, 2026 |
| Repository | aviz85/claude-skills-library ↗ |
What it does
Reading, searching, sending, and managing Gmail messages, drafts, labels, and threads via the Gmail REST API.
Who is it for?
Reading, searching, and sending Gmail email programmatically via the REST API.
Skip if: Providers other than Gmail, or use without completing the Google Cloud OAuth setup.
When should I use this skill?
When you need to read, search, send, reply to, or manage emails, drafts, labels, or threads.
What you get
Emails read, searched, sent, replied to, and labeled via authenticated Gmail API calls.
By the numbers
- access tokens expire after 1 hour
- documents 6 common Gmail search queries
Files
Gmail API
Read, send, and manage emails via Google's Gmail REST API.
Official docs: https://developers.google.com/workspace/gmail/api/reference/rest
---
When to Use
Use this skill when you need to:
- Read and search emails
- Send emails or reply to threads
- Manage drafts
- Create and manage labels
- List and modify threads
- Get user profile information
---
Prerequisites
1. Create Google Cloud Project
1. Go to https://console.cloud.google.com 2. Create a new project or select existing 3. Enable Gmail API: https://console.cloud.google.com/apis/library/gmail.googleapis.com
2. Configure OAuth Consent Screen
1. Go to https://console.cloud.google.com/apis/credentials/consent 2. Select External → Create 3. Fill required fields (app name, support email, developer email) 4. Click Save and Continue through Scopes (skip adding scopes) 5. In Audience section, click Add Users and add your Gmail address as test user 6. Save and continue to finish
3. Create OAuth Client ID
1. Go to https://console.cloud.google.com/apis/credentials 2. Click Create Credentials → OAuth client ID 3. Choose Web application (not Desktop) 4. Add Authorized redirect URI: https://developers.google.com/oauthplayground 5. Click Create and note the Client ID and Client Secret
4. Get Refresh Token (OAuth Playground)
1. Go to https://developers.google.com/oauthplayground/ 2. Click Settings (gear icon ⚙️) → Check Use your own OAuth credentials 3. Enter your Client ID and Client Secret 4. In the left panel, enter scope: https://www.googleapis.com/auth/gmail.modify 5. Click Authorize APIs → Sign in with your test user account 6. Click Exchange authorization code for tokens 7. Copy the Refresh token
5. Set Environment Variables
export GMAIL_CLIENT_ID="your-client-id"
export GMAIL_CLIENT_SECRET="your-client-secret"
export GMAIL_REFRESH_TOKEN="your-refresh-token"---
Get Access Token
Access tokens expire after 1 hour. Use refresh token to get a new one and save to /tmp:
bash -c 'curl -s -X POST "https://oauth2.googleapis.com/token" -d "client_id=$GMAIL_CLIENT_ID" -d "client_secret=$GMAIL_CLIENT_SECRET" -d "refresh_token=$GMAIL_REFRESH_TOKEN" -d "grant_type=refresh_token"' | jq -r '.access_token' > /tmp/gmail_token.txt
# Verify token was obtained
head -c 20 /tmp/gmail_token.txt && echo "..."Important: When using$VARin a command that pipes to another command, wrap the command containing$VARinbash -c '...'. Due to a Claude Code bug, environment variables are silently cleared when pipes are used directly.
Placeholders: Values in{curly-braces}like{message-id}are placeholders. Replace them with actual values when executing.
---
User Profile
Get Profile
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/profile" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'---
Messages
List Messages
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'List Messages with Query
Search using Gmail query syntax:
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=is:unread&maxResults=10" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Common queries:
is:unread- Unread messagesfrom:example@gmail.com- From specific sendersubject:hello- Subject contains "hello"after:2024/01/01- After datehas:attachment- Has attachmentslabel:INBOX- In inbox
Get Message
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Get Message (Metadata Only)
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}?format=metadata&metadataHeaders=From&metadataHeaders=Subject&metadataHeaders=Date" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Send Email
# Create RFC 2822 message and base64url encode
RAW_MESSAGE=$(echo -e "To: {recipient-email}\r\nSubject: {subject}\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n{body-text}" | base64 | tr '+/' '-_' | tr -d '=')Write to /tmp/gmail_request.json:
{
"raw": "$RAW_MESSAGE"
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'Reply to Thread
# Include In-Reply-To and References headers for proper threading
RAW_MESSAGE=$(echo -e "To: {recipient-email}\r\nSubject: Re: {original-subject}\r\nIn-Reply-To: <{original-message-id}>\r\nReferences: <{original-message-id}>\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n{reply-text}" | base64 | tr '+/' '-_' | tr -d '=')Write to /tmp/gmail_request.json:
{
"raw": "$RAW_MESSAGE",
"threadId": "{thread-id}"
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'Modify Message Labels
Write to /tmp/gmail_request.json:
{
"addLabelIds": ["STARRED"],
"removeLabelIds": ["UNREAD"]
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}/modify" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'Trash Message
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}/trash" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Delete Message Permanently
bash -c 'curl -s -X DELETE "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'---
Threads
List Threads
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/threads?maxResults=10" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Get Thread
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/threads/{thread-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Trash Thread
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/threads/{thread-id}/trash" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'---
Labels
List Labels
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/labels" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"' | jq '.labels[] | {id, name, type}'Create Label
Write to /tmp/gmail_request.json:
{
"name": "{label-name}",
"labelListVisibility": "labelShow",
"messageListVisibility": "show"
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/labels" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'Delete Label
bash -c 'curl -s -X DELETE "https://gmail.googleapis.com/gmail/v1/users/me/labels/{label-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'---
Drafts
List Drafts
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/drafts" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Create Draft
RAW_MESSAGE=$(echo -e "To: {recipient-email}\r\nSubject: {subject}\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n{body-text}" | base64 | tr '+/' '-_' | tr -d '=')Write to /tmp/gmail_request.json:
{
"message": {
"raw": "$RAW_MESSAGE"
}
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/drafts" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'Send Draft
Write to /tmp/gmail_request.json:
{
"id": "{draft-id}"
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/drafts/send" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'Delete Draft
bash -c 'curl -s -X DELETE "https://gmail.googleapis.com/gmail/v1/users/me/drafts/{draft-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'---
Attachments
Get Attachment
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}/attachments/{attachment-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"' | jq -r '.data' | base64 -d > attachment.bin---
Settings
Get Vacation Settings
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/settings/vacation" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Update Vacation Settings
Write to /tmp/gmail_request.json:
{
"enableAutoReply": true,
"responseSubject": "Out of Office",
"responseBodyPlainText": "I am currently out of office.",
"restrictToContacts": false,
"restrictToDomain": false
}Then run:
bash -c 'curl -s -X PUT "https://gmail.googleapis.com/gmail/v1/users/me/settings/vacation" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'List Filters
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/settings/filters" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"'Create Filter
Write to /tmp/gmail_request.json:
{
"criteria": {
"from": "{filter-email}"
},
"action": {
"addLabelIds": ["TRASH"],
"removeLabelIds": ["INBOX"]
}
}Then run:
bash -c 'curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/settings/filters" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)" --header "Content-Type: application/json" -d @/tmp/gmail_request.json'---
Common Scopes
| Scope | Permission |
|---|---|
gmail.readonly | Read-only access |
gmail.send | Send emails only |
gmail.compose | Create drafts and send |
gmail.modify | Read, send, delete, manage |
gmail.labels | Manage labels only |
gmail.settings.basic | Manage basic settings |
gmail.settings.sharing | Manage sensitive settings |
Use full URL: https://www.googleapis.com/auth/gmail.modify
---
Decode Message Body
Gmail returns message body as base64url encoded. To decode:
bash -c 'curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}" --header "Authorization: Bearer $(cat /tmp/gmail_token.txt)"' | jq -r '.payload.body.data // .payload.parts[0].body.data' | tr '_-' '/+' | base64 -d---
Guidelines
1. Token Refresh: Access tokens expire in 1 hour; always refresh before API calls 2. Rate Limits: Gmail API has quota limits; implement exponential backoff 3. Batch Requests: Use batch endpoints for multiple operations 4. Message Format: Messages must be RFC 2822 compliant and base64url encoded 5. Scopes: Request minimum required scopes for your use case
---
API Reference
- REST Reference: https://developers.google.com/workspace/gmail/api/reference/rest
- Guides: https://developers.google.com/workspace/gmail/api/guides
- OAuth Playground: https://developers.google.com/oauthplayground/
- Scopes: https://developers.google.com/identity/protocols/oauth2/scopes#gmail
Related skills
FAQ
What credentials does the Gmail skill need?
A Google OAuth Client ID, Client Secret, and a refresh token, set as GMAIL_CLIENT_ID, GMAIL_CLIENT_SECRET, and GMAIL_REFRESH_TOKEN environment variables.
How does the Gmail skill authenticate each call?
It exchanges the refresh token for a one-hour access token via the OAuth token endpoint and uses it as a Bearer token on every curl request.