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]
Supported services:
sheets— Read/write/append spreadsheets and rangesdrive— List, upload, download, share filesgmail— Send, read, search, label messagescalendar— List events, create meetings, check availabilitydocs— Get document content, create docschat— Send 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
Agent pipeline writes ROI model output to Sheets — use CLI (gws sheets values update)
Human reviews and adjusts numbers in a sheet — use UI
Agent uploads a PDF deliverable to a shared Drive folder — use CLI (gws drive files create)
Human moves files between folders — use UI
Agent sends a structured report email — use CLI (gws gmail send) or transactional email service
Human replies to a client email — use UI
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"}'
Adopting a Vendor's Skill Library
A CLI that ships SKILL.md files (gws generate-skills, future others) is a vendor skill library. Adopting one wholesale floods agent discovery with unused verbs. Cherry-pick instead. Two matrices below are universal — any vendor library reuses the same shape.
Matrix A — Vendoring Tiers (Value × Effort)
Tier 1 — core agent ops — vendor immediately. Service atoms + workflow digests the agent calls in active sessions today.
- sheets, gmail, calendar, drive (service atoms)
- workflow-weekly-digest, workflow-meeting-prep (composed workflows)
Tier 2 — adapt on use — catalog only. Promote when a real session demands the verb.
- doc-from-template, generate-report-from-sheet (recipes)
- exec-assistant, researcher, sales-ops (personas)
- docs, slides, tasks (lower-traffic service atoms)
Tier 3 — defer — skip unless explicit demand signal arrives. No catalog row.
- classroom, keep, script, modelarmor, events, admin-reports
- Recipes and personas not in Tier 2
Matrix B — Implementation Steps (what / where / reversibility)
Step 0 — Install vendor CLI + verify auth
- Writes:
$PATH,~/.config/{vendor}/ - Reverse:
npm rm -g @{vendor}/cli(or vendor's uninstall)
Step 1 — Create vendor namespace root
- Writes:
.agents/skills/_vendor/{vendor-name}/ - Reverse:
rm -rfthe folder
Step 2 — Pull Tier-1 SKILL.md files
- Writes:
.agents/skills/_vendor/{vendor-name}/{skill}/SKILL.md - Reverse:
git revert
Step 3 — Symlink to agent-readable surface
- Writes:
.claude/skills/{vendor-name}-{skill}→.agents/skills/_vendor/{vendor-name}/{skill} - Reverse:
unlink
Step 4 — Lock refresh script + manifest
- Writes:
scripts/sync-{vendor-name}-skills.sh+.agents/skills/_vendor/{vendor-name}/.vendor-manifest.json - Reverse: delete script + manifest
Step 5 — Promote on signal
- After 3+ sessions actively call a vendor skill, copy → adapt frontmatter → add gates → reference upstream
- Reverse: git history
The namespace prefix {vendor-name}-{skill} prevents flat-name collision with native skills. The vendor folder is read-only — never edit upstream content; promote instead.
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
Passing full spreadsheet URL as ID — strip to bare ID: everything between /d/ and /edit
Using RAW for cells with formulas — use USER_ENTERED; formulas need evaluation
One API call per cell for bulk writes — use batchUpdate for 5+ ranges
Storing credentials in source control — credentials live in ~/.config/gcloud/; host-owned
Using gws for interactive human decisions — CLI is for agent pipelines, not human editing sessions
Context
- AI CLI Tools — other CLI tools in the agent workflow stack
- Agent Workflows — where this fits in the broader automation pipeline
- Data Pipelines — structured data patterns for agent output
Links
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
gwsoperation 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?