This is a comprehensive Gmail API wrapper that handles the full email lifecycle through curl commands. It covers everything from basic inbox queries to thread management, drafts, filters, and even vacation settings. The examples are well-structured with proper RFC 2047 encoding for subjects and base64url formatting for message payloads. You get search with Gmail's query syntax, label management, attachment handling, and all the CRUD operations you'd expect. The troubleshooting section points you to zero doctor for auth issues. It's thorough enough that you won't need to context-switch to Google's docs for most common email automation tasks.
npx -y skills add vm0-ai/vm0-skills --skill gmail --agent claude-codeInstalls into .claude/skills of the current project.
If requests fail, run zero doctor check-connector --env-name GMAIL_TOKEN or zero doctor check-connector --url https://gmail.googleapis.com/gmail/v1/users/me/profile --method GET
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/profile" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10" --header "Authorization: Bearer $GMAIL_TOKEN"
Search using Gmail query syntax:
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=is:unread&maxResults=10" --header "Authorization: Bearer $GMAIL_TOKEN"
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 inboxcurl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}?format=metadata&metadataHeaders=From&metadataHeaders=Subject&metadataHeaders=Date" --header "Authorization: Bearer $GMAIL_TOKEN"
# Encode subject using RFC 2047 MIME encoding for non-ASCII characters
ENCODED_SUBJECT="=?UTF-8?B?$(printf '%s' "{subject}" | base64 -w 0)?="
# Create RFC 2822 message and base64url encode
RAW_MESSAGE=$(printf "To: {recipient-email}\r\nSubject: ${ENCODED_SUBJECT}\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n{body-text}" | base64 -w 0 | tr '+/' '-_' | tr -d '=')
Write to /tmp/gmail_request.json:
{
"raw": "$RAW_MESSAGE"
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
# Encode subject using RFC 2047 MIME encoding for non-ASCII characters
ENCODED_SUBJECT="=?UTF-8?B?$(printf '%s' "Re: {original-subject}" | base64 -w 0)?="
# Include In-Reply-To and References headers for proper threading
RAW_MESSAGE=$(printf "To: {recipient-email}\r\nSubject: ${ENCODED_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 -w 0 | tr '+/' '-_' | tr -d '=')
Write to /tmp/gmail_request.json:
{
"raw": "$RAW_MESSAGE",
"threadId": "{thread-id}"
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
Write to /tmp/gmail_request.json:
{
"addLabelIds": ["STARRED"],
"removeLabelIds": ["UNREAD"]
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}/modify" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}/trash" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s -X DELETE "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/threads?maxResults=10" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/threads/{thread-id}" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/threads/{thread-id}/trash" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/labels" --header "Authorization: Bearer $GMAIL_TOKEN" | jq '.labels[] | {id, name, type}'
Write to /tmp/gmail_request.json:
{
"name": "{label-name}",
"labelListVisibility": "labelShow",
"messageListVisibility": "show"
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/labels" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
curl -s -X DELETE "https://gmail.googleapis.com/gmail/v1/users/me/labels/{label-id}" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/drafts" --header "Authorization: Bearer $GMAIL_TOKEN"
# Encode subject using RFC 2047 MIME encoding for non-ASCII characters
ENCODED_SUBJECT="=?UTF-8?B?$(printf '%s' "{subject}" | base64 -w 0)?="
RAW_MESSAGE=$(printf "To: {recipient-email}\r\nSubject: ${ENCODED_SUBJECT}\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n{body-text}" | base64 -w 0 | tr '+/' '-_' | tr -d '=')
Write to /tmp/gmail_request.json:
{
"message": {
"raw": "$RAW_MESSAGE"
}
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/drafts" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
Write to /tmp/gmail_request.json:
{
"id": "{draft-id}"
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/drafts/send" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
curl -s -X DELETE "https://gmail.googleapis.com/gmail/v1/users/me/drafts/{draft-id}" --header "Authorization: Bearer $GMAIL_TOKEN"
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}/attachments/{attachment-id}" --header "Authorization: Bearer $GMAIL_TOKEN" | jq -r '.data' | base64 -d > attachment.bin
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/settings/vacation" --header "Authorization: Bearer $GMAIL_TOKEN"
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:
curl -s -X PUT "https://gmail.googleapis.com/gmail/v1/users/me/settings/vacation" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/settings/filters" --header "Authorization: Bearer $GMAIL_TOKEN"
Write to /tmp/gmail_request.json:
{
"criteria": {
"from": "{filter-email}"
},
"action": {
"addLabelIds": ["TRASH"],
"removeLabelIds": ["INBOX"]
}
}
Then run:
curl -s -X POST "https://gmail.googleapis.com/gmail/v1/users/me/settings/filters" --header "Authorization: Bearer $GMAIL_TOKEN" --header "Content-Type: application/json" -d @/tmp/gmail_request.json
| 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
Gmail returns message body as base64url encoded. To decode:
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/{message-id}" --header "Authorization: Bearer $GMAIL_TOKEN" | jq -r '.payload.body.data // .payload.parts[0].body.data' | tr '_-' '/+' | base64 -d
larksuite/cli
googleworkspace/cli
googleworkspace/cli
googleworkspace/cli