Back to Workflow & Productivity

google-workspace

google workspacegmailcalendardrivesheetsapi integrationautomationproductivity
860📄 MIT🕒 2026-06-11Source ↗

Install this skill

npx skills add jezweb/claude-skills

Works across Claude Code, Cursor, Codex, Copilot & Antigravity

The Google Workspace skill provides a programmatic interface for interacting with the Google productivity suite. It handles authentication via OAuth 2.0 for user-specific actions or Service Accounts for server-side background tasks. Developers can build automated workflows that manage email, calendar events, file storage, spreadsheets, and document generation directly from their application environment. The skill specifically targets architectures using Cloudflare Workers for logic execution, ensuring secure credential handling via KV or D1 storage. It supports fine-grained control over permissions through scope management and allows for domain-wide impersonation when using service accounts. By standardizing the request patterns across different APIs like Gmail, Drive, and Sheets, it reduces the complexity of managing multiple Google cloud resources within a single agent-driven project.

When to Use This Skill

  • Syncing incoming email attachments automatically to specific Drive folders
  • Generating dynamic reports by pushing data into Google Sheets
  • Creating recurring calendar invitations from task management systems
  • Onboarding new employees by provisioning resources via Admin SDK

How to Invoke This Skill

Example prompts that trigger this skill in Claude Code, Cursor, or Antigravity:

  • Fetch unread emails from Gmail
  • Add a row to my spreadsheet
  • Schedule a meeting on my calendar
  • Upload this file to Google Drive
  • List all members in the Workspace domain

Pro Tips

  • 💡Always manage API scopes meticulously to grant only necessary permissions, enhancing security and reducing potential risks.
  • 💡Utilize Google Cloud service accounts for server-to-server interactions, ensuring robust and auditable authentication without user intervention.
  • 💡Implement robust error handling and rate limit management, especially when interacting with multiple APIs, to ensure your automations are resilient and performant.

What this skill does

  • Manage emails and labels via Gmail API
  • Read and write data directly to Google Sheets
  • Automate calendar scheduling and event management
  • Interact with Drive files and folder hierarchies
  • Execute domain-wide user impersonation via service account delegation

When not to use it

  • Building high-frequency, real-time analytics dashboards exceeding API quotas
  • Complex document manipulation where Google Docs formatting is strictly constrained

Example workflow

  1. Authenticate agent using OAuth 2.0 with offline access scopes
  2. Parse incoming webhooks for new task notifications
  3. Format incoming data into a row-compatible array
  4. Append row data to the target spreadsheet via Sheets API
  5. Send a confirmation summary email using the Gmail API

Prerequisites

  • Google Cloud Platform project
  • Enabled Google Workspace APIs in the Cloud Console
  • Configured OAuth 2.0 credentials or Service Account keys
  • Environment variables for client ID, secrets, and keys

Pitfalls & limitations

  • !Hitting strict per-user rate limits during high-volume batch processing
  • !Failing to renew access tokens because refresh tokens were not stored securely
  • !Misconfiguring scope permissions resulting in insufficient access errors
  • !Improperly handling domain-wide delegation keys which exposes full admin access

FAQ

How do I handle expired access tokens?
Use the stored refresh token to request a new access token from the Google OAuth 2.0 endpoint. Always ensure you request access_type=offline during the initial consent flow.
Can I use this for non-admin accounts?
Yes, OAuth 2.0 is designed for user-specific interactions where the user grants permission to their individual files and data.
What is the difference between OAuth and Service Accounts?
OAuth acts as a specific user requiring their interactive consent, while Service Accounts act as a machine identity for backend, non-interactive automation.

How it compares

Unlike manual interaction or raw HTTP requests, this skill wraps API authentication and endpoint logic into structured, reusable functions that prevent common handshake failures.

Source & trust

860 stars📄 MIT🕒 Updated 2026-06-11
📄 Full skill instructions — original source: jezweb/claude-skills
# Google Workspace APIs

**Status**: Production Ready
**Last Updated**: 2026-01-09
**Dependencies**: Cloudflare Workers (recommended), Google Cloud Project
**Skill Version**: 1.0.0

---

## Quick Reference

| API | Common Use Cases | Reference |
|-----|------------------|-----------|
| Gmail | Email automation, inbox management | [gmail-api.md](references/gmail-api.md) |
| Calendar | Event management, scheduling | [calendar-api.md](references/calendar-api.md) |
| Drive | File storage, sharing | [drive-api.md](references/drive-api.md) |
| Sheets | Spreadsheet data, reporting | [sheets-api.md](references/sheets-api.md) |
| Docs | Document generation | [docs-api.md](references/docs-api.md) |
| Chat | Bots, webhooks, spaces | [chat-api.md](references/chat-api.md) |
| Meet | Video conferencing | [meet-api.md](references/meet-api.md) |
| Forms | Form responses, creation | [forms-api.md](references/forms-api.md) |
| Tasks | Task management | [tasks-api.md](references/tasks-api.md) |
| Admin SDK | User/group management | [admin-sdk.md](references/admin-sdk.md) |
| People | Contacts management | [people-api.md](references/people-api.md) |

---

## Shared Authentication Patterns

All Google Workspace APIs use the same authentication mechanisms. Choose based on your use case.

### Option 1: OAuth 2.0 (User Context)

Best for: Acting on behalf of a user, accessing user-specific data.

// Authorization URL
const authUrl = new URL('https://accounts.google.com/o/oauth2/v2/auth')
authUrl.searchParams.set('client_id', env.GOOGLE_CLIENT_ID)
authUrl.searchParams.set('redirect_uri', ${env.BASE_URL}/callback)
authUrl.searchParams.set('response_type', 'code')
authUrl.searchParams.set('scope', SCOPES.join(' '))
authUrl.searchParams.set('access_type', 'offline') // For refresh tokens
authUrl.searchParams.set('prompt', 'consent') // Force consent for refresh token

// Token exchange
async function exchangeCode(code: string): Promise<TokenResponse> {
const response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
code,
client_id: env.GOOGLE_CLIENT_ID,
client_secret: env.GOOGLE_CLIENT_SECRET,
redirect_uri: ${env.BASE_URL}/callback,
grant_type: 'authorization_code',
}),
})
return response.json()
}

// Refresh token
async function refreshToken(refresh_token: string): Promise<TokenResponse> {
const response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
refresh_token,
client_id: env.GOOGLE_CLIENT_ID,
client_secret: env.GOOGLE_CLIENT_SECRET,
grant_type: 'refresh_token',
}),
})
return response.json()
}


**Critical:**
- Always request access_type=offline for refresh tokens
- Use prompt=consent to ensure refresh token is returned
- Store refresh tokens securely (Cloudflare KV or D1)
- Access tokens expire in ~1 hour

### Option 2: Service Account (Server-to-Server)

Best for: Backend automation, no user interaction, domain-wide delegation.

import { SignJWT } from 'jose'

async function getServiceAccountToken(
serviceAccount: ServiceAccountKey,
scopes: string[]
): Promise<string> {
const now = Math.floor(Date.now() / 1000)

// Create JWT
const jwt = await new SignJWT({
iss: serviceAccount.client_email,
scope: scopes.join(' '),
aud: 'https://oauth2.googleapis.com/token',
iat: now,
exp: now + 3600,
})
.setProtectedHeader({ alg: 'RS256', typ: 'JWT' })
.sign(await importPKCS8(serviceAccount.private_key, 'RS256'))

// Exchange JWT for access token
const response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: jwt,
}),
})

const data = await response.json()
return data.access_token
}


**Domain-Wide Delegation** (impersonate users):
const jwt = await new SignJWT({
iss: serviceAccount.client_email,
sub: '[email protected]', // User to impersonate
scope: scopes.join(' '),
aud: 'https://oauth2.googleapis.com/token',
iat: now,
exp: now + 3600,
})


**Setup Required:**
1. Create service account in Google Cloud Console
2. Download JSON key file
3. Enable domain-wide delegation in Admin Console (if impersonating)
4. Store key as Cloudflare secret (JSON stringified)

---

## Common Rate Limits

All Google Workspace APIs enforce quotas. These are approximate - check each API's specific limits.

### Per-User Limits (OAuth)

| API | Reads | Writes | Notes |
|-----|-------|--------|-------|
| Gmail | 250/user/sec | 250/user/sec | Aggregate across all methods |
| Calendar | 500/user/100sec | 500/user/100sec | Per calendar |
| Drive | 1000/user/100sec | 1000/user/100sec | |
| Sheets | 100/user/100sec | 100/user/100sec | Lower than others |

### Per-Project Limits

| API | Daily Quota | Per-Minute | Notes |
|-----|-------------|------------|-------|
| Gmail | 1B units | Varies | Unit-based (send = 100 units) |
| Calendar | 1M queries | 500/sec | |
| Drive | 1B queries | 1000/sec | |
| Sheets | Unlimited | 500/user/100sec | |

### Handling Rate Limits

async function withRetry<T>(
fn: () => Promise<T>,
maxRetries = 5
): Promise<T> {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn()
} catch (error: any) {
const status = error.status || error.code

if (status === 429 || status === 503) {
// Rate limited or service unavailable
const retryAfter = error.headers?.get('Retry-After') || Math.pow(2, i)
await new Promise(r => setTimeout(r, retryAfter * 1000))
continue
}

if (status === 403 && error.message?.includes('rateLimitExceeded')) {
// Quota exceeded - exponential backoff
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000))
continue
}

throw error
}
}
throw new Error('Max retries exceeded')
}


---

## Batch Requests

Most Google APIs support batching multiple requests into one HTTP call.

async function batchRequest(
accessToken: string,
requests: BatchRequestItem[]
): Promise<BatchResponse[]> {
const boundary = 'batch_boundary'

let body = ''
requests.forEach((req, i) => {
body += --${boundary}\r\n
body += 'Content-Type: application/http\r\n'
body += Content-ID: <item${i}>\r\n\r\n
body += ${req.method} ${req.path} HTTP/1.1\r\n
body += 'Content-Type: application/json\r\n\r\n'
if (req.body) body += JSON.stringify(req.body)
body += '\r\n'
})
body += --${boundary}--

const response = await fetch('https://www.googleapis.com/batch/v1', {
method: 'POST',
headers: {
'Authorization': Bearer ${accessToken},
'Content-Type': multipart/mixed; boundary=${boundary},
},
body,
})

// Parse multipart response...
return parseBatchResponse(await response.text())
}


**Limits:**
- Max 100 requests per batch (most APIs)
- Max 1000 requests per batch (some APIs like Drive)
- Each request in batch counts toward quota

---

## Cloudflare Workers Configuration

// wrangler.jsonc
{
"name": "google-workspace-mcp",
"main": "src/index.ts",
"compatibility_date": "2026-01-03",
"compatibility_flags": ["nodejs_compat"],

// Store OAuth tokens
"kv_namespaces": [
{ "binding": "TOKENS", "id": "xxx" }
],

// Or use D1 for structured storage
"d1_databases": [
{ "binding": "DB", "database_name": "workspace-mcp", "database_id": "xxx" }
]
}


**Secrets to set:**
echo "your-client-id" | npx wrangler secret put GOOGLE_CLIENT_ID
echo "your-client-secret" | npx wrangler secret put GOOGLE_CLIENT_SECRET
# For service accounts:
cat service-account.json | npx wrangler secret put GOOGLE_SERVICE_ACCOUNT


---

## Common Errors

### Error: "invalid_grant" on Token Refresh
**Cause**: Refresh token revoked or expired (6 months of inactivity)
**Fix**: Re-authenticate user, request new refresh token

### Error: "access_denied" on OAuth
**Cause**: App not verified, or user not in test users list
**Fix**: Add user to OAuth consent screen test users, or complete app verification

### Error: "insufficientPermissions" (403)
**Cause**: Missing required scope
**Fix**: Check scopes in authorization URL, re-authenticate with correct scopes

### Error: "rateLimitExceeded" (403)
**Cause**: Quota exceeded
**Fix**: Implement exponential backoff, reduce request frequency, request quota increase

### Error: "notFound" (404) on Known Resource
**Cause**: Using wrong API version, or resource in trash
**Fix**: Check API version in URL, check trash for deleted items

---

## API-Specific Guides

Detailed patterns for each API are in the references/ directory. Load these when working with specific APIs.

### Gmail API
See [references/gmail-api.md](references/gmail-api.md)
- Message CRUD, labels, threads
- MIME handling, attachments
- Push notifications (Pub/Sub)

### Calendar API
See [references/calendar-api.md](references/calendar-api.md)
- Events CRUD, recurring events
- Free/busy queries
- Calendar sharing

### Drive API
See [references/drive-api.md](references/drive-api.md)
- File upload/download
- Permissions, sharing
- Search queries

### Sheets API
See [references/sheets-api.md](references/sheets-api.md)
- Reading/writing cells
- A1 notation, ranges
- Batch updates

### Chat API
See [references/chat-api.md](references/chat-api.md)
- Bots, webhooks
- Cards v2, interactive forms
- Spaces, members, reactions

*(Additional API references added as MCP servers are built)*

---

## Package Versions (Verified 2026-01-09)

{
"devDependencies": {
"@cloudflare/workers-types": "^4.20260109.0",
"wrangler": "^4.58.0",
"jose": "^6.1.3"
}
}


---

## Official Documentation

- **Google Workspace APIs**: https://developers.google.com/workspace
- **OAuth 2.0**: https://developers.google.com/identity/protocols/oauth2
- **Service Accounts**: https://cloud.google.com/iam/docs/service-accounts
- **API Explorer**: https://developers.google.com/apis-explorer
- **Quotas Dashboard**: https://console.cloud.google.com/iam-admin/quotas

---

## Skill Roadmap

APIs documented as MCP servers are built:

- [ ] Gmail API
- [ ] Calendar API
- [ ] Drive API
- [ ] Sheets API
- [ ] Docs API
- [x] Chat API (migrated from google-chat-api skill)
- [ ] Meet API
- [ ] Forms API
- [ ] Tasks API
- [ ] Admin SDK
- [ ] People API

How to Use This Skill Unit

Option A: Project-Specific (Recommended)

  1. Click "Download" above
  2. In your project, create the directory: .agent/skills/google-workspace/
  3. Save the file as SKILL.md
  4. The agent will automatically discover the skill based on its description.

Option B: Global Installation (All Agents)

Save the file to these locations to make it available across all projects:

  • Claude Code: ~/.claude/skills/jezweb/claude-skills/google-workspace/SKILL.md
  • Cursor: ~/.cursor/skills/jezweb/claude-skills/google-workspace/SKILL.md
  • Antigravity: ~/.gemini/antigravity/skills/jezweb/claude-skills/google-workspace/SKILL.md

🚀 Install with CLI:
npx skills add jezweb/claude-skills

Read the Master Guide: Mastering Agent Skills

Recommended Rules

View more rules

Recommended Workflows

View more workflows

Recommended MCP Servers

View more MCP servers

Take It Further

Maximize your productivity with these powerful resources

📋

Define Your Standards

Set up coding standards to ensure this workflow produces consistent, high-quality results.

Browse Rules Library
📖

Master Workflows

Learn how to create custom workflows, use Turbo Mode, and build your automation library.

Complete Guide

How to use this Skill in Claude Code & Cursor

For Claude Code (CLI)

To use this skill in Claude Code, copy the rule content into your project's custom instructions or follow our Add-Skill CLI guide. This ensures Claude follows your standards during every code generation.

For Cursor & Windsurf

For Cursor or Windsurf, individual skills are best used in the "Rules for AI" section. This specific unit helps the agent avoid workflow & productivity issues, leading to cleaner, more efficient code.

Why the skill format matters: the standardized Agent Skills format lets your AI agent load detailed instructions only when they are relevant, keeping your prompt clean while improving results.

Source & attribution

This skill is categorized under Workflow & Productivity and is published by JezWeb, maintained in jezweb/claude-skills.

← Browse All Agent Skills
Sponsored AI assistant. Recommendations may be paid.