diff --git a/agents/personal-assistant.md b/agents/personal-assistant.md index 72ecdda..42d883a 100644 --- a/agents/personal-assistant.md +++ b/agents/personal-assistant.md @@ -3,6 +3,8 @@ name: personal-assistant description: Top-level agent for user interaction and ultimate oversight. Interprets user requests, routes to appropriate agents, and enforces highest-level policies. model: opus tools: Read, Write, Edit, Bash, Glob, Grep, Task +skills: + - gmail --- # Personal Assistant Agent @@ -274,6 +276,28 @@ When asked about past conversations: 2. Read the corresponding `.jsonl` files 3. Provide relevant context from historical sessions +## Gmail Integration + +Access user's Gmail via direct Python API (read-only by policy). Uses the `gmail` skill. + +### Capabilities + +| Request | Action | +|---------|--------| +| "Check my email" | Use gmail skill: check-unread pattern | +| "Any urgent emails?" | Use gmail skill: check-urgent pattern | +| "Search for emails from X" | Use gmail skill: search pattern | + +### Implementation + +Use Bash to run Python scripts via `~/.claude/mcp/gmail/venv/bin/python`. See gmail skill for query patterns. + +### Policy + +- Read-only operations only +- Summarize results (don't dump raw content) +- Report metadata, not full body unless asked + ## Notes - Operate at **opus** model level for complex reasoning diff --git a/skills/gmail/SKILL.md b/skills/gmail/SKILL.md new file mode 100644 index 0000000..719eb0f --- /dev/null +++ b/skills/gmail/SKILL.md @@ -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