Google Workspace finally gets a CLI, and it was built for AI agents

The gcloud CLI covers just about everything in the GCP ecosystem. Compute, BigQuery (via bq), Cloud Storage (via gsutil), IAM, and dozens more services. But it has zero capability for interacting with Google Workspace apps. You can’t list Gmail messages, read a Google Sheet, create a Calendar event, or manage Drive permissions from gcloud. That gap has existed since day one.

The Google Workspace CLI (gws) fills it. Created by Justin Poehnelt, a Senior Developer Relations Engineer at Google on the Workspace team, gws is an open-source command-line tool that gives programmatic access to every Google Workspace API through a single binary: Gmail, Drive, Calendar, Sheets, Docs, Chat, Admin, and more. The project sits at v0.3.5 with roughly 5,100 GitHub stars, hosted under the official googleworkspace GitHub organization. It carries the standard disclaimer (“This is not an officially supported Google product”), is written in Rust, distributed via npm with pre-built binaries, and under active development toward v1.0 with breaking changes expected.

What makes it interesting for data teams is less the API coverage than the design philosophy: the tool was built from day one for AI agent consumption, not humans. It ships with 100+ agent skill files, a built-in MCP server, structured JSON output by default, and response sanitization against prompt injection.

The gap gws fills

Before gws, the main alternative for automating Workspace was Google Apps Script. It works, but it has a 6-minute execution timeout on free accounts (30 minutes on Workspace), single-threaded synchronous execution, no package manager, daily quotas on API calls, and no CI/CD integration. For data engineers who need to programmatically manage Workspace resources as part of pipelines, Apps Script is fundamentally inadequate. The REST APIs work too, but require substantial boilerplate for authentication, pagination, and error handling.

gws abstracts all of this behind a consistent interface. What’s technically clever is how the CLI builds its command surface. Rather than shipping a static list of commands, gws reads Google’s Discovery Service at runtime and dynamically generates every command from the API specifications. When Google adds a new endpoint, the CLI picks it up automatically. Discovery documents are cached for 24 hours. This means the tool will never fall behind the APIs it wraps.

Seven principles for agent-first CLIs

Poehnelt published a blog post on March 4, 2026 titled “You Need to Rewrite Your CLI for AI Agents” that lays out the philosophy behind the tool. It reached the Hacker News front page. His core thesis: human developer experience optimizes for discoverability and forgiveness, while agent developer experience optimizes for predictability and defense-in-depth. Retrofitting a human-first CLI for agents is, in his view, a losing bet.

The seven principles:

Raw JSON payloads over bespoke flags. Traditional CLIs use flat flag namespaces (--title "Q1 Budget" --locale "en_US") that can’t express nested structures. The gws CLI accepts full API payloads via --json and --params flags, mapping directly to the API schema. LLMs can generate these with zero translation loss.

Schema introspection replacing documentation. Rather than baking static docs into system prompts (expensive in tokens and prone to staleness), gws schema drive.files.list dumps full method signatures as machine-readable JSON: parameters, request body, response types, OAuth scopes. The Discovery Document is the single source of truth.

Context window discipline. A single Gmail message can consume a meaningful fraction of an LLM’s context. Field masks (--params '{"fields": "files(id,name,mimeType)"}') limit what the API returns. NDJSON pagination (--page-all) emits one JSON object per page, stream-processable without buffering the entire response.

Input hardening against hallucinations. Poehnelt’s position is blunt: “Agents hallucinate. Build like it.” The CLI validates file paths to prevent directory traversal (agents hallucinate ../../.ssh), rejects control characters below ASCII 0x20, rejects ? and # in resource names (agents embed query parameters in resource IDs), and rejects % to prevent double-encoding.

Shipping agent skills, not just commands. The repo contains structured Markdown files with YAML frontmatter, one per API surface plus higher-level workflows. Skills encode guidance that isn’t obvious from --help: “Always use --dry-run for mutating operations,” “Always confirm with user before executing write/delete commands.”

Multi-surface delivery. The same core binary serves as a CLI, an MCP server (gws mcp), a Gemini CLI extension, and a headless tool via environment variables.

Safety rails. --dry-run validates requests without hitting the API. --sanitize pipes responses through Google Cloud Model Armor to defend against prompt injection embedded in data (imagine a malicious email body instructing an agent to forward all messages to an attacker).

Installing the CLI and authenticating

Prerequisites

You need two things before starting:

  1. Node.js (any recent LTS version) for the npm install path. If you prefer Rust, you can build from source with cargo install --path . instead, or use the Nix flake (nix run github:googleworkspace/cli).
  2. The gcloud CLI, installed and authenticated with gcloud auth login. The automated setup flow wraps gcloud calls to create and configure your GCP project. If you don’t have gcloud, skip the automated path and follow the manual OAuth setup below.

This is the fastest route if you have gcloud already configured, and it sidesteps most of the OAuth pain points that trip people up in the manual flow.

Terminal window
# Install the CLI globally via npm (bundles pre-built native binaries, no Rust needed)
npm install -g @googleworkspace/cli
# Run the interactive setup wizard
gws auth setup

gws auth setup does the following automatically: creates a GCP project (or uses an existing one), enables the necessary Workspace APIs, configures an OAuth consent screen, creates an OAuth Desktop client, and walks you through the browser-based OAuth login. Credentials are encrypted at rest with AES-256-GCM, with the encryption key stored in your OS keyring.

After setup completes, verify everything works:

Terminal window
# List your 5 most recent Drive files
gws drive files list --params '{"pageSize": 5}'

If you see a JSON array of files, you’re good.

Manual OAuth setup (Google Cloud Console)

Use this path when gws auth setup can’t automate project creation (organization restrictions, for example), or when you want explicit control over the OAuth configuration. Fair warning: the Hacker News thread for this project is full of people who spent 30-45 minutes fighting the manual OAuth flow. Most of the friction comes from two specific mistakes that are easy to avoid once you know about them.

Step 1: Create or select a GCP project. Open the Google Cloud Console and create a new project or select an existing one. Note the project ID.

Step 2: Configure the OAuth consent screen. Navigate to APIs & Services > OAuth consent screen. Set the app type to External. Testing mode is fine for personal use. Under Test users, add your own Google email address. This step is critical: without it, you’ll get a generic “Access blocked” error when trying to log in, with no indication that the missing test user is the cause.

Step 3: Create an OAuth client ID. Navigate to APIs & Services > Credentials. Click Create Credentials > OAuth client ID. This is where the first common mistake happens: you must choose Desktop app as the application type, not “Web application.” The GCP Console defaults to Web application, and nothing in the gws setup warns you if you pick the wrong one. If you accidentally created a Web app client, delete it and create a new one with Desktop app selected. Download the resulting JSON file.

Step 4: Save the client JSON. Move the downloaded file to ~/.config/gws/client_secret.json. Alternatively, you can set the GWS_CLIENT_ID and GWS_CLIENT_SECRET environment variables with the values from the JSON.

Step 5: Log in.

Terminal window
gws auth login

If you didn’t save the client JSON file or set the environment variables, the CLI will prompt you interactively for your credentials. This is the second common source of confusion: the prompt asks for your “OAuth ID,” but what it actually wants is the client ID (the long string ending in .apps.googleusercontent.com), followed by the client secret on a second prompt. These are the two values from the JSON file you downloaded in Step 3. The prompt labels could be clearer here, and it’s not obvious which value goes where if you haven’t done this before.

Once credentials are provided, the CLI opens a browser window for OAuth consent. Two things will happen that may look alarming:

  • A “Google hasn’t verified this app” warning: click Advanced, then “Go to [app name] (unsafe)”. This is expected and safe for personal use. Verification is only required for apps published to other users.
  • Scope checkboxes: select the scopes you need (or Select all) and click Continue.

The scope limit gotcha

Even after getting the OAuth client type right and the credentials entered, there’s one more trap. Unverified OAuth apps in testing mode are limited to roughly 25 OAuth scopes. The gws recommended “all services” preset includes 85+ scopes and will fail silently or throw an error if you exceed this limit. One user on Hacker News described having to add scopes one by one to work around this, which is exactly the kind of friction that makes people give up.

The fix: authorize only the services you actually need. If you only plan to use Drive, Gmail, and Sheets, that’s far fewer scopes and will stay well under the limit. You can always add more services later with another gws auth login call.

Multiple accounts

If you work across several Google accounts (personal and client accounts, for example), gws handles this natively:

Terminal window
# Log in with a specific account
gws auth login --account work@corp.com
gws auth login --account personal@gmail.com
# List registered accounts
gws auth list
# Set a default
gws auth default work@corp.com
# One-off override for a single command
gws --account personal@gmail.com drive files list
# Or via environment variable
export GOOGLE_WORKSPACE_CLI_ACCOUNT=personal@gmail.com

Each account gets its own encrypted credentials file stored as credentials.<base64-email>.enc in ~/.config/gws/.

Headless and CI environments

For pipelines and servers where there’s no browser:

Terminal window
# On a machine WITH a browser: export credentials after interactive login
gws auth export --unmasked > credentials.json
# On the headless machine: point to the exported file
export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json
gws drive files list # works without any browser interaction

For fully automated server-to-server flows, you can use a GCP service account key file:

Terminal window
export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json
gws drive files list

If the service account has Domain-Wide Delegation configured, impersonate a user with:

Terminal window
export GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER=admin@example.com

You can also inject a pre-obtained access token, which is useful when gcloud already mints tokens:

Terminal window
export GOOGLE_WORKSPACE_CLI_TOKEN=$(gcloud auth print-access-token)

Auth precedence

The CLI resolves credentials in this order (first match wins):

  1. Access token (GOOGLE_WORKSPACE_CLI_TOKEN)
  2. Credentials file (GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE)
  3. Per-account encrypted credentials (from gws auth login --account)
  4. Plaintext credentials (~/.config/gws/credentials.json)

Account resolution follows: --account flag > GOOGLE_WORKSPACE_CLI_ACCOUNT env var > default in accounts.json.

Troubleshooting: “API not enabled”

When you try to use a service for the first time, you may get a 403 error with reason accessNotConfigured. The CLI prints a hint with a direct link to enable the API in the GCP Console. Click the link, click Enable, wait about 10 seconds, and retry. Alternatively, re-run gws auth setup, which enables all required APIs automatically.

Connecting gws to Claude Code

The CLI integrates with AI coding agents through two complementary paths: MCP and direct shell commands.

MCP server setup

The built-in MCP server (gws mcp -s drive,gmail,calendar) exposes Google Workspace APIs as structured tools over stdio for any MCP-compatible client: Claude Desktop, Gemini CLI, VS Code Copilot, Cursor. Each service adds roughly 10-80 tools, so scope to what you actually need to stay under typical client tool limits of 50-100 tools.

Register gws as an MCP server with the CLI command:

Terminal window
claude mcp add gws -- gws mcp -s drive,gmail,calendar

Use --scope user to make it available across all projects, or --scope project to share it with your team via the .mcp.json file.

You can also edit the config JSON directly. Add this to your ~/.claude.json under the mcpServers key:

{
"mcpServers": {
"gws": {
"command": "gws",
"args": ["mcp", "-s", "drive,gmail,calendar"]
}
}
}

After adding, restart Claude Code and verify with /mcp in session. You should see gws: connected. If you’re new to building and connecting MCP servers, the gws setup is one of the simpler ones.

Direct shell commands

Claude Code has built-in bash execution and can invoke gws commands directly, parse the structured JSON output, and chain operations together. This is often more token-efficient than MCP because tools only consume tokens when actively used, rather than loading schema definitions into the context. You can ask Claude Code to “list my recent Google Sheets and check if any match the schema of our BigQuery seed table” and it will compose the appropriate gws and bq commands.

Installing agent skills

The repo ships 100+ agent skills as structured Markdown files. To install them for Claude Code (or any agent that uses skill files):

Terminal window
# Install all skills at once
npx skills add https://github.com/googleworkspace/cli
# Or pick only what you need
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-drive
npx skills add https://github.com/googleworkspace/cli/tree/main/skills/gws-gmail

Comparison with third-party MCP servers

Several community MCP servers exist for Google Workspace. The most feature-complete is taylorwilsdon’s google_workspace_mcp covering 12 services with 100+ tools, plus implementations in Go and Python by other developers. They all require similar OAuth setup and offer similar capabilities. The gws CLI’s advantage is that it’s maintained under the official Google Workspace GitHub org by a Google DevRel engineer, dynamically stays current with API changes via Discovery Service, and offers both CLI and MCP surfaces from a single tool. The disadvantage is its “not officially supported” status and pre-v1.0 maturity.

CLI vs MCP: the practical tradeoffs

The debate over whether AI agents should use CLIs or MCP has produced real benchmarks. Mario Zechner ran 120 evaluation runs across standardized tasks and found both approaches achieved 100% success rates, with MCP being 23% faster and 2.5% cheaper. But the speed advantage came primarily from bypassing Claude Code’s malicious command detection on bash invocations, not from inherent protocol superiority. A separate browser automation benchmark found CLI scored 33% better on token efficiency, completing tasks MCP structurally couldn’t, with selective CLI queries consuming 43x fewer tokens than equivalent MCP snapshots.

CLIs win on token efficiency (no ambient schema cost, since tools only consume tokens when actively used), training data familiarity (LLMs have deep knowledge of CLI syntax), Unix composability (pipes enable multi-step workflows in single expressions), and zero implementation overhead (no server to build or deploy). MCP wins on typed schemas (JSON Schema validation prevents malformed commands), client universality (works in Claude Desktop and IDE extensions that lack shell access), stateful operations (sessions and auth tokens managed natively), and security auditing (fine-grained permissions and audit trails).

The emerging consensus, captured well by Zechner: “The protocol is just plumbing. What matters is whether your tool helps or hinders the agent’s ability to complete tasks.” The gws CLI embodies this pragmatism by offering both surfaces from a single binary.

What this means for data teams on GCP

Google Sheets is one of the most common “shadow data sources” in analytics engineering. Business stakeholders maintain mapping tables, seed data, budget figures, and ad-hoc inputs in spreadsheets. BigQuery supports external tables backed by Sheets, and the dbt Semantic Layer now integrates directly with Sheets and Excel. But managing these Sheets programmatically has required either the gspread Python library or the raw REST API.

With gws and an AI coding agent, the workflow becomes conversational. An agent can discover Sheets in Drive, inspect their structure, validate schemas against BigQuery table definitions, create or update external tables, and trigger dbt runs through CLI commands or MCP tool calls. After a job completes, the same agent can compose a summary email via gws gmail, update a Google Doc runbook with column descriptions, push query results back to a Sheets dashboard, or create a Calendar event for the next data quality review. The repo ships 50 curated recipes for exactly these patterns, including recipe-create-events-from-sheet, recipe-draft-email-from-doc, and recipe-label-and-archive-emails.

The broader trend here is convergence. Data infrastructure tools (BigQuery, dbt, Airflow) and productivity tools (Gmail, Sheets, Docs, Calendar) are merging through AI agent layers. Google’s own BigQuery Data Engineering Agent (experimental) automates pipeline creation from natural language. Claude Code users are already combining dbt agent skills with BigQuery MCP, and adding gws MCP to this stack closes the loop between data pipeline outputs and business communication.

The gws CLI is a concrete implementation of a design philosophy that’s gaining traction: build tools for agents first, humans second. For analytics engineers on GCP, the immediate value is practical: programmatic access to the Google Workspace layer that gcloud has always ignored, delivered in a format that AI coding agents can consume natively. The maturity risk (pre-v1.0, not officially supported) is real but mitigated by the dynamic Discovery Service architecture and the author’s position on the Google Workspace DevRel team. Worth watching closely, and worth installing today.