oimiragieo/agent-studio

google-workspace

Google Workspace integration skill for Gmail, Calendar, Drive, Docs, and Sheets via Python client libraries and MCP servers

First seen Mar 22, 2026

Installation

$ npx skills add oimiragieo/agent-studio --skill google-workspace

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from oimiragieo/agent-studio · top by installs.

npx skills add oimiragieo/agent-studio

Browse all from oimiragieo/agent-studio

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 40
Default branch main
Open issues 501
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
Declared agents claude-code

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,001 B
  • docs SUMMARY.md 147 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Google Workspace Integration Skill

When to Invoke

Skill({ skill: 'google-workspace' });

Use when:

  • Integrating with Gmail (send/read/search emails)
  • Working with Google Calendar (create/list/update events)
  • Managing Google Drive (upload/download/share files)
  • Reading or writing Google Docs or Sheets
  • Automating any Google Workspace workflow via API

Setup: OAuth 2.0 Authentication

Google Workspace APIs require OAuth 2.0. Use a service account for server-side automation or user OAuth for delegated access.

Service Account (Recommended for Automation)

pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client
from google.oauth2 import service_account
from googleapiclient.discovery import build

SCOPES = [
    'https://www.googleapis.com/auth/gmail.readonly',
    'https://www.googleapis.com/auth/calendar',
    'https://www.googleapis.com/auth/drive',
]

credentials = service_account.Credentials.from_service_account_file(
    'service-account.json',
    scopes=SCOPES,
)
# For delegated access (act as a user):
delegated_credentials = credentials.with_subject('[email protected]')

User OAuth Flow

from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
import os, pickle

def get_credentials(scopes, token_file='token.pkl', creds_file='credentials.json'):
    creds = None
    if os.path.exists(token_file):
        with open(token_file, 'rb') as f:
            creds = pickle.load(f)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(creds_file, scopes)
            creds = flow.run_local_server(port=0)
        with open(token_file, 'wb') as f:
            pickle.dump(creds, f)
    return creds

Gmail API

service = build('gmail', 'v1', credentials=credentials)

# List messages
results = service.users().messages().list(userId='me', q='is:unread').execute()
messages = results.get('messages', [])

# Read a message
msg = service.users().messages().get(userId='me', id=messages[0]['id'], format='full').execute()
subject = next(h['value'] for h in msg['payload']['headers'] if h['name'] == 'Subject')

# Send an email
import base64
from email.mime.text import MIMEText

def create_message(to, subject, body):
    message = MIMEText(body)
    message['to'] = to
    message['subject'] = subject
    raw = base64.urlsafe_b64encode(message.as_bytes()).decode()
    return {'raw': raw}

msg_body = create_message('[email protected]', 'Hello', 'Body text here')
service.users().messages().send(userId='me', body=msg_body).execute()

Google Calendar API

service = build('calendar', 'v3', credentials=credentials)

# List upcoming events
from datetime import datetime, timezone
now = datetime.now(timezone.utc).isoformat()
events_result = service.events().list(
    calendarId='primary',
    timeMin=now,
    maxResults=10,
    singleEvents=True,
    orderBy='startTime',
).execute()
events = events_result.get('items', [])

# Create an event
event = {
    'summary': 'Team Standup',
    'start': {'dateTime': '2026-03-15T09:00:00-07:00', 'timeZone': 'America/Los_Angeles'},
    'end':   {'dateTime': '2026-03-15T09:30:00-07:00', 'timeZone': 'America/Los_Angeles'},
    'attendees': [{'email': '[email protected]'}],
}
created = service.events().insert(calendarId='primary', body=event).execute()

Google Drive API

from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload
import io

service = build('drive', 'v3', credentials=credentials)

# List files
results = service.files().list(
    pageSize=10,
    fields='files(id, name, mimeType)',
    q="'root' in parents and trashed = false",
).execute()
files = results.get('files', [])

# Upload a file
file_metadata = {'name': 'report.pdf', 'parents': ['<folder_id>']}
media = MediaFileUpload('report.pdf', mimetype='application/pdf')
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()

# Download a file
request = service.files().get_media(fileId='<file_id>')
fh = io.FileIO('downloaded.pdf', 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while not done:
    status, done = downloader.next_chunk()

# Share a file
service.permissions().create(
    fileId='<file_id>',
    body={'type': 'user', 'role': 'reader', 'emailAddress': '[email protected]'},
).execute()

Google Sheets API

service = build('sheets', 'v4', credentials=credentials)
sheet = service.spreadsheets()

SPREADSHEET_ID = '<your-spreadsheet-id>'

# Read values
result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range='Sheet1!A1:D10').execute()
rows = result.get('values', [])

# Write values
body = {'values': [['Name', 'Score'], ['Alice', 95], ['Bob', 87]]}
sheet.values().update(
    spreadsheetId=SPREADSHEET_ID,
    range='Sheet1!A1',
    valueInputOption='RAW',
    body=body,
).execute()

# Append rows
sheet.values().append(
    spreadsheetId=SPREADSHEET_ID,
    range='Sheet1!A1',
    valueInputOption='USER_ENTERED',
    body={'values': [['Charlie', 92]]},
).execute()

Google Docs API

service = build('docs', 'v1', credentials=credentials)

# Read document
doc = service.documents().get(documentId='<doc_id>').execute()
title = doc.get('title')
# Extract text from body content
content = doc.get('body', {}).get('content', [])

# Insert text at end of document
requests = [{
    'insertText': {
        'location': {'index': 1},
        'text': 'New paragraph content.\n',
    }
}]
service.documents().batchUpdate(
    documentId='<doc_id>',
    body={'requests': requests},
).execute()

MCP Server Integration

If a Google Workspace MCP server is available, prefer it over direct API calls:

// In Claude Code agent context
mcp__google_workspace__gmail_send({
  to: '[email protected]',
  subject: 'Hello',
  body: 'Message body',
});

mcp__google_workspace__calendar_create_event({
  title: 'Meeting',
  start: '2026-03-15T09:00:00Z',
  end: '2026-03-15T10:00:00Z',
});

mcp__google_workspace__drive_upload({
  name: 'file.pdf',
  path: '/local/path/file.pdf',
});

Security Notes

  • Store credentials in environment variables or secret managers, never in source code
  • Use service accounts with minimum required scopes
  • Enable domain-wide delegation only when necessary
  • Rotate service account keys regularly
  • Use credentials.json from Google Cloud Console; add to .gitignore
  • For production, use Google Secret Manager: pip install google-cloud-secret-manager

Common Scopes Reference

Service Scope Access Level
Gmail gmail.readonly Read-only
Gmail gmail.send Send only
Gmail gmail.modify Read/write
Calendar calendar.readonly Read-only
Calendar calendar Full access
Drive drive.readonly Read-only
Drive drive.file App-created
Drive drive Full access
Sheets spreadsheets.readonly Read-only
Sheets spreadsheets Full access
Docs documents.readonly Read-only
Docs documents Full access

Always use the most restrictive scope that meets your requirements.