Rust Rewrite · all 14 APIs · one login

Google tools, at terminal speed.

Zero-config, maximum-performance Google tools from the terminal. One binary, all 14 Google Workspace APIs, and output that plays nicely with jq.

Release binaries ship with the OAuth client built in — grr auth login and you are in.

grr terminalA dimensional cream and orange terminal with a glowing screen and a tiny crab perched on its top edge.
brew tap debanjanbasu/tapbrew trust debanjanbasu/tapbrew install grrwinget install debanjanbasu.grrRUSTFLAGS="--cfg reqwest_unstable" cargo install grr-cli
public pulse

Small binary.
Real reach.

Build-time numbers from the public package and release channels, with a quiet optional refresh in your browser.

package version
v2.5.1
the current published line
crates.io downloads
409
409 in the last 30 days
platforms
5
macOS · Linux · Windows (ARM + x86_64)
services
14
one namespaced binary
latest release v2.5.1
GitHub asset downloads 472 across all public releases
Snapshot refreshed Install the binary
platform archives v2.5.1
Linux arm64
3.1 MB
Linux x86_64
3.6 MB
macOS arm64
3.0 MB
Windows ARM
3.5 MB
Windows x86_64
3.2 MB

Compressed release archives, straight from the GitHub release.

watch it work

A real terminal. A real agent. 80 seconds.

Every frame below is grr's actual output: the generated command tree, a live grr transport probe over HTTP/3, a grr ask plan turning plain English into a typed method and parameters — and opencode, an agentic harness, driving grr the way an AI agent would.

Recorded once with scripts/generate-demo.ts; no hand-editing, no mocks — only the pacing is synthetic.

grr ask · the plan
$ grr ask "show my unread gmail"
{"body":null,"confidence":0.88,"dryRun":true,"httpMethod":"GET",
 "leastPrivilegeScope":"https://www.googleapis.com/auth/gmail.readonly",
 "lowConfidence":false,"method":"gmail.users.messages.list",
 "params":{"userId":"me"},"service":"gmail","serviceConfidence":1.0,
 "url":"https://gmail.googleapis.com/gmail/v1/users/me/messages"}
# nothing was sent — rerun with --run to execute this request
the only one you can just ask

Plain English in. A typed plan out.

grr ask "show my unread gmail" is all it takes. A System One model — TypeSafe's Jev by default, any provider speaking the same contract works by config — classifies the request hierarchically: the service (14 options), then the method, then one typed question per required parameter. Every candidate comes from the discovery index, so the model can only select. It can never invent a method, a flag, or a value.

What you get back is a plan, not a guess: the resolved method, the parameters, the URL, the scopes, the confidence — as JSON. Nothing is sent until you say --run. No other Google Workspace CLI does this; for an AI agent it is the fastest path from intent to a verifiable request.

The safety gate fires the moment the method resolves — --readonly and friends cover grr ask like everything else.

all 14 APIs · one login

The useful parts of your Google account, namespaced.

Keep commands close to the work they support. Every data command accepts JSON, JSONL, table, or pretty output; JSON is the default.

01 / inbox

Gmail

Search, read, compose, label, filter, route mail, and batch without leaving your shell.

  • Search and read messages
  • Compose, label, and route mail
  • Batch and filter messages
  • Manage threads, history, and send-as
Gmail illustration
grr gmail
grr gmail users messages list --user-id me --q "in:inbox" --max-results 5
More verified commands
  • grr gmail users messages list --user-id me --q "in:inbox" --max-results 5
  • grr gmail users settings filters list --user-id me
  • grr gmail users threads list --user-id me --max-results 10
  • grr gmail users settings sendAs verify --user-id me --send-as-email alias@example.com
02 / time

Calendar

List calendars, manage events, watch changes, and check free-busy windows in one pass.

  • List calendars and events
  • Create, update, move, and delete
  • Watch changes and free-busy
  • Manage sharing, settings, and colors
Calendar illustration
grr calendar
grr calendar events list --calendar-id primary --max-results 10
More verified commands
  • grr calendar events list --calendar-id primary --max-results 10
  • grr calendar events patch --calendar-id primary --event-id <event-id> --params '{"summary":"Updated"}'
  • grr calendar events watch --calendar-id primary --params '{"type":"web_hook","address":"https://example.com/hook"}'
03 / files

Drive

Find files, inspect metadata, manage sharing and comments, and control storage.

  • Find files and inspect metadata
  • Upload, download, and export
  • Manage sharing and comments
  • Restore, rename, and control storage
Drive illustration
grr drive
grr drive files list --q "trashed = true" --page-size 20
More verified commands
  • grr drive files list --q "trashed = true" --page-size 20
  • grr drive comments create --file-id <file-id> --params '{"content":"Note"}'
  • grr drive about get
04 / people

Contacts

Query people, organize groups, batch-read profiles, and keep photos close to your workflows.

  • Search and organize people
  • Create, update, and manage groups
  • Batch-read profiles and photos
  • Adopt contacts and keep photos close
Contacts illustration
grr contacts
grr people people connections list --resource-name people/me --page-size 20
More verified commands
  • grr people people connections list --resource-name people/me --page-size 20
  • grr people people getBatchGet --resource-names people/123
  • grr people people updateContactPhoto --resource-name people/123 --body-file photo.json
05 / rooms

Chat

Browse spaces, manage members, read messages, and react without context switching.

  • Browse spaces and members
  • Add and remove members
  • Read and send messages
  • React and unreact to messages
Chat illustration
grr chat
grr chat spaces list --page-size 10
More verified commands
  • grr chat spaces list --page-size 10
  • grr chat spaces members create --parent spaces/<space-id> --params '{"member":{"name":"users/user@example.com"}}'
  • grr chat spaces messages reactions create --parent spaces/<space-id>/messages/<message-id> --params '{"emoji":"👍"}'
06 / signals

Forms

Read and update forms, pull responses, and manage watch channels for lightweight automation.

  • Read and update forms
  • Pull response data
  • Create and manage watch channels
  • Renew and delete watches
Forms illustration
grr forms
grr forms forms get --form-id <form-id>
More verified commands
  • grr forms forms get --form-id <form-id>
  • grr forms forms responses list --form-id <form-id> --page-size 50
  • grr forms forms watches renew --form-id <form-id> --watch-id <watch-id>
the generated command surface

Every branch, still namespaced.

14 APIs
Gmail
users: messages, threads, drafts, labels, history, settings (filters, forwarding, sendAs, CSE), watch · 79 methods
Calendar
calendars, events, calendarList, freebusy, acl, colors, settings, channels · 38 methods
Drive
files, permissions, comments, replies, revisions, changes, drives, accessproposals, approvals, teamdrives · 64 methods
People
people, contactGroups, otherContacts · 24 methods
Chat
spaces, messages, members, reactions, spaceEvents, customEmojis, media, availability · 55 methods
Forms
forms, responses, watches · 10 methods
Tasks
tasklists, tasks · 14 methods
Docs
documents · 3 methods
Sheets
spreadsheets, values, sheets, developerMetadata · 17 methods
Slides
presentations, pages · 5 methods
Apps Script
projects, deployments, versions, processes, scripts · 16 methods
Analytics Admin
accounts, properties, dataStreams, customDimensions, customMetrics, conversionEvents, keyEvents, firebaseLinks, googleAdsLinks · 55 methods
Analytics Data
properties, audienceExports · 11 methods
Search Console
searchanalytics, sitemaps, sites, urlInspection, mobileFriendlyTest · 11 methods

Run grr <service> --help and grr schema for the exact flags. The tree is generated from Google's Discovery Service - every method nests by resource (grr gmail users messages list, grr drive files get) with typed flags per parameter. grr api list and grr api describe are the flat, id-based equivalents.

the same index, read flat

Every method by id, no tree walking.

402 methods · 14 APIs

The command tree is generated from an embedded Discovery index, and grr api reads the same index flat: grr api list, grr api describe, and grr api call reach every method those 14 Google APIs publish — 402 of them — by dotted id, with --dry-run before any send and per-method scopes reported up front.

grr api
$ grr api list --service sheets
$ grr api describe sheets.spreadsheets.values.get
$ grr api call sheets.spreadsheets.values.get \
    --param spreadsheetId=1a2b3c --param range=A1:D10
$ grr api refresh --service sheets
scrollytelling

One crab, four moods.

Waves when you arrive.

One OAuth login unlocks all 14 Google Workspace APIs in a single namespaced binary.

Sits with you while you work.

Commands stay close to the work they support, and the output stays parseable.

Sleeps while your scripts run.

No analytics SDK, no telemetry. Tokens rest in the operating system keyring.

Celebrates when you ship.

Output that plays nicely with jq, by default.

built for the shell

Less glue.
More signal.

grr is deliberately small at the interface: predictable commands, fast transport, and no hidden service setup.

01

HTTP/3 when available

The transport probes authenticated QUIC at startup and falls back silently to HTTP/2 when it cannot negotiate.

02

nightly Rust

The CLI enables HTTP/3 through reqwest and QUIC support, which is gated behind Rust nightly and the reqwest_unstable cfg.

03

keyring tokens

PKCE is always enabled; tokens are kept in the operating system keyring, with a local file fallback for headless systems.

04

streaming output

Results go to stdout and logs go to stderr, so jq, scripts, and agents get predictable data by default.

one clean session

From inbox to insight, without the tab.

Search a message, fetch exactly the format you need, and keep the output parseable. The command tree is available as JSON for agents with grr schema.

Browse command examples
terminal · grr
$ grr auth login
{"authenticated":true,"account":null,"token_backend":"os-keyring","token_preview":"ya29.a0AfH6SMBxLqKm..."}

$ grr gmail users messages list --user-id me --q "in:inbox" --max-results 1
{"messages":[{"id":"19f8ab2c","threadId":"19f8ab2c"}],"resultSizeEstimate":1}

$ grr gmail users messages get --user-id me --id 19f8ab2c --param-format metadata
{"id":"19f8ab2c","threadId":"19f8ab2c","labelIds":["UNREAD","INBOX"],"payload":{"headers":[{"name":"Subject","value":"Build notes"}]},"sizeEstimate":4821}
machine-friendly by default

Your shell is the API client.

Use a human-readable table when you need it, or keep the default JSON and let the next tool take it from there.

pipe-friendly output
$ grr gmail users messages list --user-id me --q "from:github.com" --max-results 10 | jq -r '.messages[0].id'
19f8ab2c

$ grr transport
negotiated_protocol: HTTP_3
http3_requested: true
http3_effective: true
fell_back: false
cpus: 10
io_uring: false
http3_always_compiled: true
runtime: tokio multi-thread (auto-sized to cores)
questions, answered

No mystery meat.

The short version of the things people usually want to know before putting a Google account behind a terminal tool.

What is grr?
grr is a Rust CLI for Google services from the terminal. One generated command tree covers 402 methods across the 14 consumer Google Workspace APIs — Gmail, Calendar, Drive, Contacts, Chat, Forms, Tasks, Docs, Sheets, Slides, Apps Script, Analytics Admin, Analytics Data and Search Console — in one namespaced binary with machine-readable output and a single OAuth login.
How does OAuth work?
Release builds need no setup at all: a Google OAuth client is compiled into the binary, so grr auth login just works. Building from source? Run grr auth setup, which creates ~/.grr/config.toml for you, or bring your own client. PKCE is always enabled and tokens are kept in the operating system keyring, with a local file fallback for headless systems. grr auth login --device prints a URL and code for machines without a browser.
Do I need to log in again after an update?
Only when you ask for more: the default consent set is deliberately small — Gmail, Drive, Calendar, Tasks, Docs, Sheets, Slides and sign-in — because Google's consent screen stops submitting past roughly 27 ticked boxes on an unverified project. grr auth login --service <name> asks for one service's full scope set instead, and --all-scopes asks for every scope the 402 methods name. Each login merges with the account's existing grant, so widening the request needs one fresh grr auth login and nothing else.
Is grr affiliated with Google?
No. grr is an independent project. It is not affiliated with, sponsored by, or endorsed by Google LLC. It uses public Google APIs and your own Google account credentials.
How do I install it?
Use a prebuilt GitHub Release, the documented Homebrew package, or the grr-cli crate from crates.io. winget manifests are generated per release, but no public submission has been published yet, so use the Windows release archive today. A crates.io install compiles from source and needs nightly Rust plus the reqwest_unstable cfg — see "Why does it need nightly Rust?". The install page has the exact commands for macOS, Linux, Windows x86_64 and Windows on ARM.
Why does it need nightly Rust?
The CLI enables HTTP/3 through reqwest and QUIC support, which is gated behind Rust nightly and the reqwest_unstable cfg. The repo pins the required toolchain and sets the cfg for in-repo builds; the CLI falls back to HTTP/2 at runtime if QUIC is unavailable.
What is grr api?
A generic escape hatch generated from Google's own Discovery Service, embedded in the binary so it works offline. grr api list browses every method, grr api describe shows its parameters and scopes, and grr api call invokes one by id. Every service in the index — including Tasks, Docs, Sheets and Slides — already has a full typed command tree, so grr api is for composing ids dynamically or reaching the long tail of methods without a dedicated namespace. Use --dry-run to see the exact request first.
Can an AI agent use it?
Yes, and the docs are written for that. Output is JSON on stdout with logs on stderr, so grr ... | jq and agent tool calls both get predictable data. An agent can discover capabilities with grr api list instead of assuming them, inspect any call with --dry-run, and read the exact scope a method declares before calling it — consent itself is granted once, for the small default set, and any other service is one grr auth login --service <name> away. See the docs page for agents.

Your Google workflows deserve a better terminal.

Grab a binary, point it at your own OAuth client, and let grr get out of the way.