| name | googleworkspace-cli |
| description | Unified CLI interface for Google Workspace APIs (Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin, etc.) with structured output and multi-service support |
| metadata | {"version":"0.1.0","author":"arisng"} |
Google Workspace CLI Agent Skill
Overview
The googleworkspace-cli agent skill provides a unified, production-ready interface to 18+ Google Workspace services through the gws command-line tool. It eliminates authentication boilerplate, API fragmentation, and credential management complexity—enabling Copilot agents to orchestrate email campaigns, calendar workflows, document collaboration, and admin tasks without manually learning each service's API. Use this skill when agents need to integrate with enterprise Google Workspace environments, automate workflows across multiple services, or manage bulk operations securely.
What It Does
- Gmail operations: Search, send, reply, label, archive, and thread management with full-text query support
- Drive management: Create, upload, share, manage permissions, organize folders, and handle team drives
- Calendar automation: Query events, check attendee availability, create meetings, handle recurring patterns
- Sheets integration: Read, write, append data, use formulas, and export spreadsheets
- Docs creation: Create documents, append content, insert tables, manage collaborators
- Chat messaging: Post messages to spaces, create threads, manage channels
- Admin operations: Create/suspend users, manage groups, configure org policies, run admin reports
- Batch operations: Bulk create/update/delete with automatic pagination and error recovery
- Multi-format output: JSON, CSV, YAML, and human-readable table formats natively supported
- Dry-run & validation: Preview changes before executing destructive operations; automatic input sanitization
Installation & Setup
1. Install the gws CLI Tool
# Windows (using Scoop or manual download)
scoop install gws
# Or download from GitHub directly
Invoke-WebRequest -Uri "https://github.com/googleworkspace/cli/releases/download/latest/gws-windows-amd64.exe" `
-OutFile "$env:PROGRAMFILES\gws\gws.exe"
# Linux/macOS
curl -L https://github.com/googleworkspace/cli/releases/download/latest/gws-linux-amd64 -o /usr/local/bin/gws
chmod +x /usr/local/bin/gws
2. Authenticate with Google Workspace
# Interactive OAuth2 flow (one-time setup)
gws auth setup
# Verify authentication status
gws auth status
# Output:
# Account: user@example.com
# Domain: example.com
# Scopes: gmail,drive,calendar,sheets,docs,chat,admin
# Expires: 2026-05-01
3. Optional: Export Credentials for CI/Headless Environments
# Export authentication token for non-interactive use
gws auth export --format env >> .env
# Then load in CI/CD pipeline
cat .env | docker run --env-file /dev/stdin gws:latest gws gmail search --query "from:team"
4. Verify Installation
# Test connectivity to all services
gws health check
# List available services
gws service list
# Test a simple Gmail operation
gws gmail search --query "is:unread" --limit 1 --output json
Quick Start Examples
Example 1: Search Emails and Apply Labels
Scenario: Find urgent emails from leadership and tag them with a custom label.
# Search for urgent emails
$emails = gws gmail search --query 'from:(boss@example.com OR ceo@example.com) subject:(urgent OR critical)' `
--limit 50 --output json | ConvertFrom-Json
# Apply "Urgent" label to each email
foreach ($email in $emails.messages) {
gws gmail modify --id $email.id `
--add-label-ids "URGENT" `
--remove-label-ids "INBOX" `
--output json
}
# Send auto-reply to sender
$firstEmail = $emails.messages[0]
gws gmail send `
--to $firstEmail.headers.From `
--subject "Re: $($firstEmail.headers.Subject)" `
--body "I've received your urgent message and prioritized it. Will respond within 2 hours." `
--output json
Example 2: Create Shared Document and Notify Team
Scenario: Create a meeting notes document, share it with the team, and send a calendar invite.
# Create a new Google Doc
$doc = gws docs create --title "Team Meeting - Q2 Planning" `
--description "Collaborative notes and action items" `
--output json | ConvertFrom-Json
$docId = $doc.documentId
# Share document with team (editor access)
gws drive share --file-id $docId `
--role editor `
--emails-file teams.txt `
--output json
# Insert initial content
gws docs append --document-id $docId `
--text "# Meeting Agenda
## Topics
- Q2 OKRs
- Resource Planning
- Timeline
## Notes
(To be filled in during meeting)
## Action Items
- [ ] Action 1
- [ ] Action 2
" `
--output json
# Create calendar event and invite attendees
gws calendar create `
--summary "Team Meeting - Q2 Planning" `
--start "2026-04-15T10:00:00Z" `
--end "2026-04-15T11:00:00Z" `
--attendees-file teams.txt `
--conference-type hangoutsMeet `
--description "Meeting notes: $(https://docs.google.com/document/d/$docId/edit)" `
--output json
Example 3: Query Calendar and Find Available Meeting Slots
Scenario: Find when all team members are available and suggest optimal meeting times.
# List attendees
$attendees = @("alice@example.com", "bob@example.com", "charlie@example.com")
# Check availability for next 5 business days
$startTime = (Get-Date).AddDays(1).ToUniversalTime().ToString('o')
$endTime = (Get-Date).AddDays(6).ToUniversalTime().ToString('o')
$freebusy = gws calendar freebusy `
--emails $attendees `
--time-min $startTime `
--time-max $endTime `
--output json | ConvertFrom-Json
# Analyze results to find best time slots (3+ hours of free time for all)
$availability = @()
foreach ($slot in $freebusy.calendars) {
if ($slot.busy.Count -lt 2) { # Less than 2 busy blocks = mostly free
$availability += $slot
}
}
Write-Host "Best times for all attendees:"
$availability | ForEach-Object { Write-Host " $_" }
# Create meeting at suggested time
if ($availability.Count -gt 0) {
gws calendar create `
--summary "Team Sync" `
--start "2026-04-16T14:00:00Z" `
--end "2026-04-16T15:00:00Z" `
--attendees $attendees `
--conference-type hangoutsMeet `
--output json
}
Key Capabilities
Gmail Operations
# Search with advanced queries
gws gmail search --query 'from:boss label:work is:unread after:2026-03-01' --limit 100 --output json
# Read email thread with all messages
gws gmail get-thread --thread-id "abc123" --format full --output json
# Send email with attachment
gws gmail send `
--to "user@example.com" `
--subject "Report" `
--body "Please find attached" `
--attachments "report.pdf" "data.xlsx" `
--output json
# Modify multiple emails (batch operation)
gws gmail batch-modify `
--ids "msg1,msg2,msg3" `
--add-labels "important" `
--remove-labels "inbox" `
--output json
# Label management
gws gmail list-labels --output json
gws gmail create-label --name "project-alpha" --color FF6D00 --output json
# Archive messages older than 30 days
gws gmail search --query 'before:2026-02-01' --output json | \
jq '.messages[].id' | \
xargs -I {} gws gmail modify --id {} --add-labels "ARCHIVE" --output json
Drive Operations
# List files and folders
gws drive list --query "name contains 'Report' and trashed=false" --spaces drive --limit 50 --output json
# Create folder
gws drive create-folder --name "Q2 2026 Planning" --parent "root" --output json
# Upload file
gws drive upload --file "presentation.pptx" --name "Q2 Strategy" --parent "ABC123" --output json
# Share file with multiple people
gws drive share --file-id "XYZ789" `
--role editor `
--emails "alice@example.com,bob@example.com" `
--notify --output json
# Grant team-wide access
gws drive share --file-id "ABC123" --role reader --type domain --domain "example.com" --output json
# Update file permissions
gws drive update-permission --file-id "ABC123" --permission-id "perm456" --role commenter --output json
# Move file to team drive
gws drive update --file-id "ABC123" --new-parent "team-drive-id" --output json
# Audit file access
gws drive get-permissions --file-id "ABC123" --output json
gws drive list-revisions --file-id "ABC123" --limit 10 --output json
Calendar Operations
# List events for a date range
gws calendar list `
--calendar-id "primary" `
--time-min "2026-04-01T00:00:00Z" `
--time-max "2026-04-30T23:59:59Z" `
--max-results 100 `
--output json
# Create event with recurrence
gws calendar create `
--summary "Weekly Sync" `
--description "Team synchronization" `
--start "2026-04-21T09:00:00" `
--end "2026-04-21T10:00:00" `
--recurrence "FREQ=WEEKLY;BYDAY=MO,WE,FR;COUNT=12" `
--timezone "America/Los_Angeles" `
--attendees "alice@example.com,bob@example.com" `
--conference-type hangoutsMeet `
--output json
# Find available time slots (busy times)
gws calendar freebusy `
--emails "alice@example.com,bob@example.com,charlie@example.com" `
--time-min "2026-04-15T00:00:00Z" `
--time-max "2026-04-22T23:59:59Z" `
--output json
# Update event
gws calendar update --event-id "evt123" `
--start "2026-04-21T10:00:00" `
--end "2026-04-21T11:00:00" `
--summary "Weekly Sync (Rescheduled)" `
--notify-attendees `
--output json
# Delete recurring event instance
gws calendar delete --event-id "evt123" --calendar-id "primary" --send-notifications --output json
# List calendars
gws calendar list-calendars --summary-only --output json
Sheets Operations
# Read data from spreadsheet
gws sheets get --spreadsheet-id "ABC123" --range "Sheet1!A1:D100" --output json
# Write data to cells
gws sheets update --spreadsheet-id "ABC123" --range "Sheet1!A1" `
--values '[[Name,Email,Status],[Alice,alice@example.com,Active],[Bob,bob@example.com,Inactive]]' `
--output json
# Append rows
gws sheets append --spreadsheet-id "ABC123" --range "Sheet1!A:D" `
--values '[[Charlie,charlie@example.com,Active]]' `
--output json
# Create new spreadsheet
gws sheets create --title "Q2 OKRs" --sheets "Engineering,Product,Sales" --output json
# Add sheet to existing spreadsheet
gws sheets add-sheet --spreadsheet-id "ABC123" --title "New Tab" --output json
# Clear sheet
gws sheets clear --spreadsheet-id "ABC123" --range "Sheet1" --output json
# Batch update (formulas, formatting, etc.)
gws sheets batch-update --spreadsheet-id "ABC123" `
--requests '[{"updateCells":{"range":{"sheetId":0},"rows":[{"values":[{"userEnteredFormula":{"formula":"=SUM(B2:B100)"}}]}]}}]' `
--output json
# Export spreadsheet as CSV
gws sheets export --spreadsheet-id "ABC123" --range "Sheet1" --format csv > output.csv
Docs Operations
# Create document
gws docs create --title "Product Requirements" --output json
# Append text
gws docs append --document-id "doc123" `
--text "# Introduction\n\nThis is a sample document." `
--output json
# Insert table
gws docs insert-table --document-id "doc123" --rows 5 --columns 3 `
--location 1 --output json
# Insert image
gws docs insert-image --document-id "doc123" --image-url "https://example.com/image.png" `
--width 200 --height 150 --location 1 --output json
# Insert page break
gws docs insert-page-break --document-id "doc123" --location 100 --output json
# Update text (replace)
gws docs update --document-id "doc123" --request-type replaceText `
--old-text "placeholder" --new-text "actual content" --output json
# Add comment
gws docs insert-comment --document-id "doc123" `
--text "Please review this section" `
--anchor-text "Introduction" `
--resolved false `
--output json
# Get document content
gws docs get --document-id "doc123" --output json
Chat Operations
# List spaces
gws chat list-spaces --filter "displayName:'engineering'" --limit 50 --output json
# Send message to space
gws chat send-message `
--space "spaces/AAAABBBBCCCCDDDD" `
--text "Team: The deployment is complete." `