Add Gmail skill with direct Python API integration
- Create gmail skill with check-unread, check-urgent, and search patterns - Update PA agent to reference gmail skill - Use direct Gmail API calls via Python (faster/more reliable than MCP) - Includes query patterns for common email operations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
90
skills/gmail/SKILL.md
Normal file
90
skills/gmail/SKILL.md
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
name: gmail
|
||||
description: Gmail read access via direct Python API - search, check unread, detect urgent emails
|
||||
allowed-tools:
|
||||
- Bash
|
||||
---
|
||||
|
||||
# Gmail Skill
|
||||
|
||||
Access Gmail via direct Python API calls. Uses OAuth credentials at `~/.gmail-mcp/`.
|
||||
|
||||
## Usage
|
||||
|
||||
For any Gmail request, use Bash to run the Python helper:
|
||||
|
||||
```bash
|
||||
GMAIL_CREDENTIALS_PATH=~/.gmail-mcp/credentials.json ~/.claude/mcp/gmail/venv/bin/python << 'EOF'
|
||||
from gmail_mcp.utils.GCP.gmail_auth import get_gmail_service
|
||||
from collections import defaultdict
|
||||
|
||||
service = get_gmail_service()
|
||||
|
||||
# Your query here
|
||||
results = service.users().messages().list(userId='me', q='is:unread newer_than:3d', maxResults=25).execute()
|
||||
messages = results.get('messages', [])
|
||||
|
||||
for msg in messages:
|
||||
detail = service.users().messages().get(userId='me', id=msg['id'], format='metadata', metadataHeaders=['From', 'Subject', 'Date']).execute()
|
||||
headers = {h['name']: h['value'] for h in detail['payload']['headers']}
|
||||
print(f"From: {headers.get('From', 'Unknown')}")
|
||||
print(f"Subject: {headers.get('Subject', '(no subject)')}")
|
||||
print(f"Date: {headers.get('Date', 'Unknown')}")
|
||||
print("---")
|
||||
EOF
|
||||
```
|
||||
|
||||
## Query Patterns
|
||||
|
||||
| Request | Gmail Query |
|
||||
|---------|-------------|
|
||||
| Unread | `is:unread` |
|
||||
| Last N days | `newer_than:Nd` |
|
||||
| From sender | `from:email@example.com` |
|
||||
| With attachments | `has:attachment` |
|
||||
| Important | `is:important` |
|
||||
| Urgent keywords | `subject:(urgent OR asap OR "action required")` |
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Check unread (grouped by sender)
|
||||
```bash
|
||||
GMAIL_CREDENTIALS_PATH=~/.gmail-mcp/credentials.json ~/.claude/mcp/gmail/venv/bin/python << 'EOF'
|
||||
from gmail_mcp.utils.GCP.gmail_auth import get_gmail_service
|
||||
from collections import defaultdict
|
||||
service = get_gmail_service()
|
||||
results = service.users().messages().list(userId='me', q='is:unread newer_than:7d', maxResults=25).execute()
|
||||
by_sender = defaultdict(list)
|
||||
for msg in results.get('messages', []):
|
||||
detail = service.users().messages().get(userId='me', id=msg['id'], format='metadata', metadataHeaders=['From', 'Subject']).execute()
|
||||
headers = {h['name']: h['value'] for h in detail['payload']['headers']}
|
||||
sender = headers.get('From', 'Unknown').split('<')[0].strip().strip('"')
|
||||
by_sender[sender].append(headers.get('Subject', '(no subject)')[:50])
|
||||
for sender, subjects in sorted(by_sender.items(), key=lambda x: -len(x[1])):
|
||||
print(f"* {sender} ({len(subjects)})")
|
||||
for s in subjects[:2]: print(f" - {s}")
|
||||
if len(subjects) > 2: print(f" - ...+{len(subjects)-2} more")
|
||||
EOF
|
||||
```
|
||||
|
||||
### Check urgent
|
||||
```bash
|
||||
GMAIL_CREDENTIALS_PATH=~/.gmail-mcp/credentials.json ~/.claude/mcp/gmail/venv/bin/python << 'EOF'
|
||||
from gmail_mcp.utils.GCP.gmail_auth import get_gmail_service
|
||||
service = get_gmail_service()
|
||||
results = service.users().messages().list(userId='me', q='is:unread newer_than:3d (subject:urgent OR subject:asap OR subject:"action required" OR is:important)', maxResults=15).execute()
|
||||
for msg in results.get('messages', []):
|
||||
detail = service.users().messages().get(userId='me', id=msg['id'], format='metadata', metadataHeaders=['From', 'Subject', 'Date']).execute()
|
||||
headers = {h['name']: h['value'] for h in detail['payload']['headers']}
|
||||
print(f"From: {headers.get('From', 'Unknown')}")
|
||||
print(f"Subject: {headers.get('Subject', '(no subject)')}")
|
||||
print(f"Date: {headers.get('Date', 'Unknown')}")
|
||||
print("---")
|
||||
EOF
|
||||
```
|
||||
|
||||
## Policy
|
||||
|
||||
- Read-only operations only
|
||||
- Summarize results (don't dump raw content)
|
||||
- Report metadata, not full body unless asked
|
||||
Reference in New Issue
Block a user