The CLI Wins: Introducing Google Workspace from the Command Line
Posted on Sat 07 March 2026 in Developer Tools • 9 min read
Google just shipped a command line interface for Gmail. You can read your email from the terminal. List your Drive files with a one-liner. Search your calendar without opening a browser. A year ago that sentence would have sounded like a joke. Today it is a Rust binary with 4,900 GitHub stars and a Hacker News front page spot.
I have been waiting for this moment for about a decade. Not for this specific tool -- I did not know Google would ship a Workspace CLI -- but for the broader shift it represents. The command line is no longer niche. It is strategic. And for those of us who built our workflows around it years ago, this feels like a quiet vindication.
A Decade in the Terminal
About ten years ago, I started a PhD and fell deep into the command line. It was not a deliberate decision at first. I was working on computational problems that required running simulations on remote servers, processing large datasets, and automating repetitive analysis pipelines. A GUI was not going to cut it. So I went full Linux, learned bash scripting properly, and started building my entire workflow around the terminal.
The productivity was immediate and obvious -- to me. I could chain tools together with pipes, automate file transfers with rsync, keep persistent sessions running with tmux, and write scripts that did in seconds what would take twenty minutes of clicking through interfaces. Once you learn to think in terms of composable commands, you start seeing inefficiency everywhere in GUI workflows.
But the people around me were not convinced. The reaction I got most often was that it was overkill. Why spend time learning arcane commands when there is a perfectly good graphical interface? Why write a bash script when you can just click through it? The implication was that I was overcomplicating things for the sake of it -- that the terminal was a fetish, not a tool.
I understood the objection. The learning curve is real. But I also knew something they did not seem to see: the time I spent learning those tools paid for itself many times over. The scripts I wrote once ran hundreds of times. The muscle memory I built compounded. And every new command-line tool I picked up slotted into the same ecosystem of pipes, scripts, and automation.
The Quiet Years
For most of the last decade, the CLI lifestyle felt genuinely niche. The industry was moving in the opposite direction. Dashboards everywhere. Electron wrappers around everything. Web-based IDEs. GUI-first developer tools. The message from the market was clear: the future is visual, interactive, mouse-driven.
And I get it. GUIs are great for discovery and for tasks you do occasionally. I am not against graphical interfaces. But for the work I do every day -- writing code, managing environments, processing data, deploying systems -- the terminal was always faster. Not because it is cooler or more hacker-ish, but because it composes. You can pipe the output of one tool into another. You can wrap a workflow in a script and run it on a schedule. You can version-control your configuration. Try doing that with a sequence of mouse clicks.
During those years, the tools I relied on did not go away. They just did not get much attention. grep, sed, awk, ssh, make -- these were not trending on Hacker News. They were quietly doing their jobs, the same way they had been for decades. And new command-line tools kept appearing for those who were paying attention: ripgrep, fzf, jq, httpie, uv. The ecosystem was evolving, but it felt like it was evolving in a corner.
The Shift
Then, at some point in the last few years, something changed. Big companies started shipping first-class command line interfaces -- not as afterthoughts, but as primary developer experiences.
GitHub shipped gh, and suddenly you could manage pull requests, issues, and CI runs without leaving the terminal. Vercel shipped a CLI that made deployment a one-liner. The AWS CLI became essential infrastructure for anyone working in the cloud. Stripe, Cloudflare, DigitalOcean -- all invested in polished, well-documented CLIs. Bun shipped as a CLI-first JavaScript runtime. Claude Code runs entirely in the terminal. And now Google ships gws -- a single CLI for Gmail, Drive, Calendar, Sheets, Docs, Chat, and Admin.
This is not a coincidence. These companies are not shipping CLIs because engineers asked nicely. They are shipping them because CLIs are the most composable, scriptable, automatable interface you can build. And in a world where automation is no longer optional, that matters more than it ever has.
Why the Command Line Wins Now
The traditional argument for the CLI has always been composability. Pipes, scripts, cron jobs -- the Unix philosophy of small tools that do one thing well and chain together. That argument has been true for fifty years and it is still true today.
But there is a new argument, and it is the one that I think tipped the scales: AI agents need CLIs.
An AI agent cannot click a button. It cannot navigate a web UI. But it can run a command, parse structured output, and chain the result into the next step. The command line is the natural interface between AI and services. Google's gws ships with native MCP (Model Context Protocol) server mode -- meaning AI agents like Claude Desktop, Gemini CLI, or VS Code Copilot can interact with your Gmail, Drive, and Calendar programmatically through it. That is not a feature bolted on as an afterthought. It is a core design decision.
This is the part that feels genuinely new. The CLI is not just winning because of the old arguments about composability and scripting. It is winning because it turns out to be the ideal interface for the next generation of tools -- AI systems that need structured, automatable access to services. The terminal is quietly becoming the universal integration layer.
Getting Started with gws
The tool is still experimental and pre-v1.0 -- not yet officially supported by Google -- but it is functional and the direction it signals matters. Here is how to get it running.
1. Install prerequisites:
You need Node.js (18+) for gws and the Google Cloud SDK for authentication:
# Node.js (18+) — https://nodejs.org/ or via your package manager
Then install the Google Cloud SDK (Ubuntu/Debian):
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee /etc/apt/sources.list.d/google-cloud-sdk.list
sudo apt-get update && sudo apt-get install google-cloud-cli
2. Install gws:
npm install -g @googleworkspace/cli
3. Initialize gcloud and create a project:
gcloud init
This opens a browser for login. Select or create a Google Cloud project (e.g. gcloud-cli-gws).
4. Configure OAuth consent screen:
- Go to OAuth consent screen in your project
- Set User Type to External (required for personal
@gmail.comaccounts -- "Internal" only works for Google Workspace org accounts) - Fill in the app name and support email
- Add your email as a test user -- this is required while the app is in "Testing" status. Without it, login will fail with an "Access blocked" error
5. Create OAuth client and authenticate:
- Go to Credentials in your project
- Click "+ CREATE CREDENTIALS" > "OAuth client ID"
- Application type: Desktop app
- Download the
client_secret_*.jsonfile and copy it to gws config:
mkdir -p ~/.config/gws
cp ~/Downloads/client_secret_*.json ~/.config/gws/client_secret.json
Alternatively, you can skip the download and just copy the Client ID and Client Secret values directly when gws auth setup prompts you. If you go this route, paste the values without quotes -- wrapping them in "..." will cause authentication to fail.
6. Authenticate and select scopes:
gws auth setup # walks you through project config
gws auth login # opens browser for consent -- select the recommended scopes
3. Verify it works:
gws auth status
What It Looks Like in Practice
Once authenticated, the entire Google Workspace is at your fingertips. Every command returns structured JSON, which means you can pipe it into jq, feed it to a script, or hand it to an AI agent.
List your five most recent emails:
gws gmail users messages list --params '{"userId": "me", "maxResults": 5}'
Read the headers of a specific message:
gws gmail users messages get --params '{"userId": "me", "id": "MESSAGE_ID", "format": "metadata"}'
Search your Drive for files with "report" in the name:
gws drive files list --params '{"q": "name contains \"report\"", "pageSize": 5}'
Download an attachment from an email -- first get the message in full to find the attachment ID, then fetch the attachment data and decode it:
# Get the full message to see its parts and attachment IDs
gws gmail users messages get \
--params '{"userId": "me", "id": "MESSAGE_ID", "format": "full"}' \
| jq '[.payload.parts[] | select(.filename | length > 0) | {filename, attachmentId: .body.attachmentId}]'
# Fetch the attachment by ID and decode it to a file
gws gmail users messages attachments get \
--params '{"userId": "me", "messageId": "MESSAGE_ID", "id": "ATTACHMENT_ID"}' \
| jq -r '.data' | tr '_-' '/+' | base64 -d > attachment.pdf
Note the tr '_-' '/+' step -- Gmail returns base64url encoding (with - and _) rather than standard base64 (with + and /), so you need to translate before decoding.
The general pattern is always the same: gws <service> <resource> <method> --params '<JSON>'. Once you learn the shape, you can explore any Workspace API with --help on any resource.
I am not writing this to say "I told you so." The people who told me the terminal was overkill were not wrong about the learning curve. They were wrong about the ceiling. The command line is not just a power-user affectation. It is the interface that composes, scripts, automates, and -- now -- connects to AI.
And honestly, I cannot wait to start automating things with this. Email triage scripts. Calendar summaries piped into my morning terminal. Drive backups on a cron job. AI agents that manage my inbox through MCP. The building blocks are all here now -- it is just a matter of wiring them together. For someone who has spent a decade in the terminal, this is the most exciting development in a long time.
The CLI won. And the best part is, we are just getting started.