← Back to Blog

How to Give AI Agents Access to Google Workspace with TapAuth + gws CLI

Tracy Handler·

🤖 AI Agent? You can follow this guide programmatically. The TapAuth CLI handles the full OAuth flow — grant creation, user approval, token caching, and refresh. Pair it with gws (Google Workspace CLI) and you get full Google Workspace access via one environment variable. No OAuth implementation needed.

Google just open-sourced gws — a Rust-based CLI that covers every Google Workspace API. Drive, Gmail, Calendar, Sheets, Docs, Chat, Admin — all accessible from the command line with structured JSON output. It's built dynamically from Google's Discovery Service, so it stays current automatically.

For AI agents, this is a big deal. Instead of writing custom API calls for each Google service, an agent can use gws drive files list or gws gmail messages list and parse structured JSON. It even ships 40+ agent skills via skills.sh.

But there's a catch: gws needs an OAuth access token. And OAuth was built for humans in browsers — not agents in terminals.

The auth gap

The gws CLI supports multiple auth methods, but the simplest for agents is the GOOGLE_WORKSPACE_CLI_TOKEN environment variable. Set it to a valid Google OAuth access token and every gws command uses it automatically. No interactive login, no browser redirect, no credential file management.

The question is: where does the agent get that token?

Google OAuth requires a browser-based consent flow. The user visits a consent screen, clicks "Allow," and the app receives an authorization code via redirect. For a human developer, that's fine. For an AI agent running in a terminal, a container, or a headless environment — it's a non-starter.

This is exactly the problem TapAuth solves.

TapAuth + gws: the full flow

TapAuth is the token layer for AI agents. One API call creates a grant request with specific Google scopes. The user approves in their browser (once). The agent gets a scoped, time-limited access token. Token refresh is automatic.

Here's the complete flow for an agent that needs to read Google Calendar events:

Step 1: Request access

tapauth grant google/calendar.readonly

This creates a grant request. The user gets a URL to approve in their browser. They see exactly what scopes the agent is requesting and can approve or deny.

Step 2: Get the token

export GOOGLE_WORKSPACE_CLI_TOKEN=$(tapauth token google/calendar.readonly)

Once approved, the agent retrieves the access token. TapAuth handles caching — subsequent calls return the cached token instantly if it hasn't expired, and auto-refresh when it has.

Step 3: Use gws

gws calendar events list --params '{"calendarId": "primary", "maxResults": 10}'
gws drive files list --params '{"q": "mimeType='application/vnd.google-apps.spreadsheet'"}'
gws gmail messages list --params '{"userId": "me", "maxResults": 5}'

That's it. The agent has full, scoped access to Google Workspace via a CLI that outputs structured JSON. No OAuth implementation. No redirect servers. No token storage logic.

Scope mapping: TapAuth scopes → gws commands

TapAuth uses Google's standard OAuth scope names. Here's how they map to gws commands:

TapAuth ScopeAccessgws Commands
calendar.readonlyRead calendar eventsgws calendar events list, gws calendar calendars list
calendar.eventsFull calendar accessgws calendar events * (create, update, delete)
spreadsheets.readonlyRead Google Sheetsgws sheets spreadsheets get, gws sheets spreadsheets.values get
spreadsheetsFull Sheets accessgws sheets spreadsheets *, gws sheets spreadsheets.values update
documents.readonlyRead Google Docsgws docs documents get
documentsFull Docs accessgws docs documents *
drive.readonlyRead Drive filesgws drive files list, gws drive files get
gmail.readonlyRead Gmailgws gmail messages list, gws gmail messages get
gmail.sendSend emailsgws gmail messages send

Request multiple scopes by comma-separating them:

tapauth grant google/calendar.readonly,spreadsheets.readonly,drive.readonly

Example workflows

List recent Drive files

# Get a token with Drive read access
export GOOGLE_WORKSPACE_CLI_TOKEN=$(tapauth token google/drive.readonly)

# List the 10 most recently modified files
gws drive files list --params '{"orderBy": "modifiedTime desc", "pageSize": 10, "fields": "files(id,name,mimeType,modifiedTime)"}'

Check today's calendar

# Get a token with Calendar read access
export GOOGLE_WORKSPACE_CLI_TOKEN=$(tapauth token google/calendar.readonly)

# List today's events
TODAY_START=$(date -u +%Y-%m-%dT00:00:00Z)
TODAY_END=$(date -u +%Y-%m-%dT23:59:59Z)
gws calendar events list --params "{\"calendarId\": \"primary\", \"timeMin\": \"$TODAY_START\", \"timeMax\": \"$TODAY_END\", \"singleEvents\": true, \"orderBy\": \"startTime\"}"

Send an email

# Get a token with Gmail send access
export GOOGLE_WORKSPACE_CLI_TOKEN=$(tapauth token google/gmail.send)

# Send a message
# Gmail API requires a base64url-encoded RFC 2822 message
MSG=$(printf 'To: team@example.com
Subject: Weekly update

Here is the weekly summary...' | base64)
gws gmail messages send --params '{"userId": "me"}' --json "{"raw": "$MSG"}"

Read a spreadsheet

# Get a token with Sheets read access
export GOOGLE_WORKSPACE_CLI_TOKEN=$(tapauth token google/spreadsheets.readonly)

# Read a range from a sheet
gws sheets spreadsheets.values get --params '{"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms", "range": "Sheet1!A1:D10"}'

OpenClaw integration: zero-config token delivery

If you're running agents via OpenClaw, token management gets even simpler. OpenClaw's secrets provider can auto-resolve TapAuth tokens at gateway startup, so agents don't need to run tapauth commands at all.

With the tapauth-secrets provider configured, the GOOGLE_WORKSPACE_CLI_TOKEN environment variable is automatically populated from TapAuth. Your agent just uses gws commands directly — no token setup, no environment variable management, no grant flow in the agent's code.

# In your OpenClaw gateway config, add the secrets provider:
# "secrets": { "provider": "tapauth", "scopes": ["google/calendar.readonly", "google/drive.readonly"] }

# Then your agent just uses gws directly:
gws calendar events list --params '{"calendarId": "primary"}'
gws drive files list --params '{"pageSize": 5}'

This is the ideal setup for production agents: the human approves scopes once during setup, and the agent has seamless Google Workspace access from that point forward.

Why this matters for AI agents

Before gws, agents that needed Google Workspace access had to make raw HTTP requests to individual Google APIs — each with its own endpoint structure, pagination model, and query syntax. Or they used language-specific SDKs that required complex initialization.

With gws + TapAuth, the stack simplifies to:

  1. TapAuth handles auth — delegated, scoped, user-approved, auto-refreshing
  2. gws handles API access — structured CLI with JSON output across all Workspace services
  3. The agent focuses on what it's actually good at — understanding context and taking action

No OAuth plumbing. No SDK initialization. No token storage. Just tapauth for auth and gws for everything else.

Getting started

Install both CLIs:

# Install gws
npm install -g @googleworkspace/cli

# Install TapAuth CLI
curl -fsSL https://tapauth.ai/cli/install.sh | bash

Then follow the three-step flow above: tapauth granttapauth tokengws commands. Your agent will have secure, scoped Google Workspace access in under a minute.

For agent framework integration, gws also ships agent skills via skills.sh:

npx skills add https://github.com/googleworkspace/cli

This installs 40+ pre-built skills for Google Workspace operations — ready for any agent framework that supports the skills.sh format.


Links: