Architectural Foundations & The 7-Day Trap
Building an unattended agent skill to access personal Google Drive and Gmail requires resolving two foundational constraints:
- Service Accounts Cannot Access Consumer Gmail/Drive: Service accounts require Domain-Wide Delegation (DWD), which is only possible in Google Workspace organizations. For personal
@gmail.comaccounts, OAuth 2.0 User Delegation is mandatory. - Bypassing the 7-Day Refresh Token Expiration: By default, an unverified GCP OAuth app in "Testing" mode issues refresh tokens that expire after exactly 7 days. Switching the GCP Consent Screen status to "In production" grants indefinite refresh tokens for personal use (<100 users) without requiring costly third-party CASA security verification audits.
client_id, client_secret, and the long-lived refresh_token. The CLI script automatically exchanges the refresh token for a 1-hour access token and caches it in /tmp/gsuite_access_token.json (with chmod 600), eliminating network auth overhead on subsequent calls.
Token Economy & Latency Benchmark Matrix
| Operation | Naive / Unoptimized Approach | Optimized Agent Pipeline | Token Savings | Latency Impact |
|---|---|---|---|---|
| Gmail Search | messages.list + full get on all messages |
Server q query + fields=messages(id) + metadata batch |
~95% | 2.5x Faster (Minimal JSON wire payload) |
| Email Body Read | Raw RFC 2822 / HTML body dump into prompt | Extract text/plain; strip reply chains (> ...) and RFC 3676 sigs |
75–90% | Instant local regex stripping |
| Google Drive Search | files.list default payload (dozens of fields) |
Server q + explicit fields="files(id,name,mimeType,size)" |
~75% | 3x Faster server serialization |
| Google Docs Ingestion | Export to PDF / HTML + DOM parser | Native Drive export to Markdown: files.export?mimeType=text/markdown |
~65% | 1.8x Faster (Direct Markdown rendering) |
| Spreadsheet Ingestion | Full CSV export of large workbook | Tab-separated-values (TSV) export or cell range slicing | 80–95% | Avoids 10MB memory traps |
Implementation Blueprint: Skill Setup in 4 Steps
1. Create a project at Google Cloud Console.
2. Enable Gmail API and Google Drive API.
3. In OAuth consent screen, select External, fill app name/email, and click Publish App (change status from Testing to In production).
4. In Credentials, click Create Credentials > OAuth client ID > Desktop app. Download the JSON (gives client_id and client_secret).
Run the built-in authorization helper to generate the permanent refresh token:
node ~/.gemini/config/skills/google-workspace/scripts/auth.mjs \
--client-id "<YOUR_CLIENT_ID>" \
--client-secret "<YOUR_CLIENT_SECRET>"
This prints a consent URL, starts a temporary local HTTP server (http://127.0.0.1:8989), receives the authorization code, and outputs credentials.json.
Save credentials in the skill directory and restrict permissions:
mkdir -p ~/.gemini/config/skills/google-workspace/
chmod 700 ~/.gemini/config/skills/google-workspace/
# Save credentials.json:
cat << 'EOF' > ~/.gemini/config/skills/google-workspace/credentials.json
{
"client_id": "...",
"client_secret": "...",
"refresh_token": "..."
}
EOF
chmod 600 ~/.gemini/config/skills/google-workspace/credentials.json
The agent executes commands with zero external npm dependencies:
# Search recent unread emails:
node scripts/gsuite.mjs gmail list --query "is:unread newer_than:7d"
# Read specific email body (with automatic noise/quote stripping):
node scripts/gsuite.mjs gmail get 18f12a3b4c
# Search Google Drive for invoices or reports:
node scripts/gsuite.mjs drive list --query "name contains 'Invoice' and trashed=false"
# Read Google Doc directly as Markdown:
node scripts/gsuite.mjs drive read 1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms
Security Guardrails & Blast Radius Mitigation
- Least Privilege Scopes: Request
https://www.googleapis.com/auth/gmail.readonlyandhttps://www.googleapis.com/auth/drive.readonlyduring initial setup to protect against prompt injection attacks that attempt to send spam or delete drives. - Trash Over Delete: If write access is needed, route deletions to
trashendpoints (soft delete) instead of irreversible permanent purge. - Hard Context Ceiling: The CLI enforces a default 12KB (~3,000 token) safety cap on all file and email reads to guarantee that a 50MB attachment or 200-page scan never blows up the LLM context.