Skip to main content

Google CLI Tools

When does a Google Workspace operation belong in a CLI — and when does it belong in the UI?

Rule of thumb: if an agent workflow produces structured data that needs to land in Sheets, Drive, or Gmail — use the CLI. If a human is making one-off decisions in a document — use the UI.

What It Can Do

gws is a single CLI for all Google Workspace services. Pattern: gws <service> <resource> <method> [flags]

ServiceOperations
sheetsRead/write/append spreadsheets and ranges
driveList, upload, download, share files
gmailSend, read, search, label messages
calendarList events, create meetings, check availability
docsGet document content, create docs
chatSend messages to Spaces

Primary use case in agent workflows: Sheets — structured data in, structured data out. The other services support delivery (Drive upload, Gmail send) rather than data exchange.

When to Use CLI vs UI

SituationUse
Agent pipeline writes ROI model output to SheetsCLI (gws sheets values update)
Human reviews and adjusts numbers in a sheetUI
Agent uploads a PDF deliverable to a shared Drive folderCLI (gws drive files create)
Human moves files between foldersUI
Agent sends a structured report emailCLI (gws gmail send) or transactional email service
Human replies to a client emailUI

Auth Setup (one-time)

gcloud auth application-default login \
--scopes=https://www.googleapis.com/auth/spreadsheets,\
https://www.googleapis.com/auth/drive,\
https://www.googleapis.com/auth/gmail.send

# Verify:
gws auth status
gws drive files list --params '{"pageSize": 3}'

Credentials are stored locally by gcloud — never committed to source control.

Core Operations

Sheets — Read

gws sheets spreadsheets values get \
--params '{"spreadsheetId": "SHEET_ID", "range": "Sheet1!A1:Z50"}' \
--format csv

Sheets — Write

gws sheets spreadsheets values update \
--params '{"spreadsheetId": "SHEET_ID", "range": "Sheet1!A1", "valueInputOption": "USER_ENTERED"}' \
--json '{"values": [["Label","Value"],["ROI","3.2x"]]}'

Sheets — Append Rows

gws sheets spreadsheets values append \
--params '{"spreadsheetId": "SHEET_ID", "range": "Sheet1", "valueInputOption": "USER_ENTERED"}' \
--json '{"values": [["new row","data"]]}'

Drive — Upload File

gws drive files create \
--params '{"uploadType": "multipart"}' \
--upload ./report.pdf \
--json '{"name": "AI Transformation Report", "parents": ["FOLDER_ID"]}'

Drive — Share File

gws drive permissions create \
--params '{"fileId": "FILE_ID", "sendNotificationEmail": true}' \
--json '{"role": "reader", "type": "user", "emailAddress": "client@example.com"}'

Agent Delivery Pipeline Pattern

For workflows that produce a model, render a document, and deliver to a client:

1. Agent writes ROI model → Google Sheets (gws sheets values update)
2. Agent reads headline numbers → injects into report template
3. Report renders to PDF
4. gws drive files create → upload to shared folder
5. gws drive permissions create → share with client
OR
gws gmail send → email PDF directly

Schema Exploration

# Discover all parameters for any method:
gws schema sheets.spreadsheets.values.update
gws schema drive.files.create
gws schema gmail.users.messages.send

Anti-Patterns

Anti-patternFix
Passing full spreadsheet URL as IDStrip to bare ID: everything between /d/ and /edit
Using RAW for cells with formulasUse USER_ENTERED — formulas need evaluation
One API call per cell for bulk writesUse batchUpdate for 5+ ranges
Storing credentials in source controlCredentials live in ~/.config/gcloud/ — host-owned
Using gws for interactive human decisionsCLI is for agent pipelines, not human editing sessions

Context

Questions

When does putting structured agent output into Google Sheets create more friction than it removes?

  • At what data volume does a direct Sheets write become a bottleneck — and what replaces it?
  • Which gws operation is most likely to fail silently in an agent pipeline — and how do you detect it?
  • How does this pattern change when the consumer of the Sheet is another agent rather than a human?