gmail-access
Search, read, draft, and reply to Gmail emails using the gmail.cs CLI tool. Use when the user asks about emails, wants to search Gmail, create email drafts, reply to messages, or download attachments.
When & Why to Use This Skill
The Gmail Access skill enables Claude agents to securely interact with Gmail accounts via a specialized CLI tool. It streamlines email management by allowing users to search messages using advanced query syntax, read full threads, create drafts, and reply to conversations. With built-in support for 1Password credential storage and OAuth 2.0, it provides a professional-grade solution for automating communication workflows while maintaining high security standards.
Use Cases
- Inbox Organization: Search and filter unread messages, specific labels, or senders to quickly summarize recent communications.
- Automated Drafting: Generate professional email drafts or follow-ups based on chat context and save them directly to Gmail for review.
- Information Retrieval: Use complex Gmail operators (e.g., 'has:attachment', 'newer_than:7d') to find specific invoices, receipts, or project updates.
- Attachment Management: Identify and download email attachments to local directories for further data processing or document analysis.
- Seamless Communication: Reply to existing email threads directly within the agent workflow to maintain continuity in client or team interactions.
| name | gmail-access |
|---|---|
| description | Search, read, draft, and reply to Gmail emails using the gmail.cs CLI tool. Use when the user asks about emails, wants to search Gmail, create email drafts, reply to messages, or download attachments. |
Gmail Access
Access Gmail accounts securely via the gmail.cs CLI tool located in this skill directory. Credentials are stored in 1Password and never exposed.
Setup
1. Create OAuth Credentials
You need to create your own Google OAuth credentials to use this skill.
- Go to Google Cloud Console
- Create a new project (or select an existing one)
- Enable the Gmail API for your project
- Go to "Credentials" > "Create Credentials" > "OAuth client ID"
- Choose "Desktop app" as the application type
- Copy the Client ID and Client Secret
- Replace the placeholder values in both
gmail.csandget-gmail-token.cs:private const string ClientId = "YOUR_CLIENT_ID.apps.googleusercontent.com"; private const string ClientSecret = "YOUR_CLIENT_SECRET";
Note: Client secrets for desktop/CLI apps cannot be fully protected per OAuth 2.0 spec. It's safe to commit these to your private repository but avoid public repositories.
2. Authorize Your Gmail Account(s)
For each Gmail account you want to access:
# Run the token setup script
dotnet run get-gmail-token.cs your-email@gmail.com
# This will:
# 1. Open a browser for Google OAuth authorization
# 2. Get a refresh token
# 3. Store it in 1Password as "Gmail - your-email@gmail.com"
Prerequisites:
- 1Password CLI installed (
brew install 1password-cli) - 1Password CLI authenticated
The refresh token allows the tool to access your Gmail without repeated logins (tokens are cached for one hour).
Quick Reference
# Search emails
dotnet run gmail.cs -- search --email your-email@gmail.com --query "<gmail query>" --max-results 20
# Create a draft
dotnet run gmail.cs -- draft --email your-email@gmail.com --to "recipient@example.com" --subject "Subject" --body "Body"
# Reply to an email
dotnet run gmail.cs -- reply --email your-email@gmail.com --message-id "<id>" --body "Reply text"
# Download attachments
dotnet run gmail.cs -- download-attachments --email your-email@gmail.com --message-id "<id>" --output-dir "/tmp/attachments"
Commands
search
Search emails with Gmail query syntax.
dotnet run gmail.cs -- search --email your-email@gmail.com --query "from:someone@example.com" --max-results 10
Options:
--email(required): Gmail account to search--queryor-q: Gmail search query (supports all Gmail operators)--max-resultsor-m: Maximum results (default: 20)
Common query patterns:
from:sender@example.com- From specific sendersubject:invoice- Subject contains wordhas:attachment- Has attachmentsnewer_than:7d- Last 7 daysis:unread- Unread messageslabel:important- Specific label
draft
Create a new email draft.
dotnet run gmail.cs -- draft --email your-email@gmail.com --to "recipient@example.com" --subject "Subject" --body "Email content"
Options:
--email(required): Sender account--toor-t(required): Recipient email--subjector-s: Subject line--bodyor-b(required): Email body content
reply
Create a reply draft to an existing email.
dotnet run gmail.cs -- reply --email your-email@gmail.com --message-id "18abc123def" --body "Reply text"
Options:
--email(required): Account to reply from--message-idor-m(required): Gmail message ID to reply to (from search results)--bodyor-b(required): Reply content
download-attachments
Download all attachments from an email.
dotnet run gmail.cs -- download-attachments --email your-email@gmail.com --message-id "18abc123def" --output-dir /tmp/attachments
Options:
--email(required): Account--message-idor-m(required): Gmail message ID--output-diror-o(required): Directory to save attachments
Output Format
All commands output JSON. Success responses include "success": true. Example search result:
{
"success": true,
"count": 2,
"messages": [
{
"id": "18abc123def",
"threadId": "18abc000000",
"from": "sender@example.com",
"to": "your-email@gmail.com",
"subject": "Example Subject",
"date": "Mon, 1 Jan 2025 10:00:00 +0100",
"snippet": "Preview of email content...",
"body": "Full email body text"
}
]
}
Authentication
First use per hour requires 1Password authorization (Touch ID). Subsequent calls use cached token. If token expired, you'll see a Touch ID prompt.
Writing Ephemeral Programs
When writing programs that use gmail.cs, use CliWrap:
#:package CliWrap@3.6.6
using CliWrap;
using CliWrap.Buffered;
var result = await Cli.Wrap("dotnet")
.WithArguments(["run", "gmail.cs", "--", "search", "--email", "your-email@gmail.com", "--query", "is:unread"])
.WithWorkingDirectory("/path/to/gmail/skill") // Set to your gmail skill directory
.ExecuteBufferedAsync();
var json = result.StandardOutput;