Google Workspace in your terminal.
Gmail, Calendar, Contacts, Drive, Sheets, Docs, Tasks, Meet — one CLI. Permanent OAuth. Zero bloat.
Every Google Workspace tool is either calendar-only, admin-only, or abandoned. No single CLI covers Gmail + Calendar + Contacts + Drive + Sheets + Docs with permanent OAuth.
gw fixes that. Login once, use forever. No re-auth loops, first-class JSON output, and profile-aware config when you need multiple accounts.
pip install gw-clibrew tap v-gutierrez/gw
brew install gwgit clone https://github.com/v-gutierrez/gw.git
cd gw
pip install -e .- Go to Google Cloud Console
- Create a new project (or select an existing one)
- Go to APIs & Services → Library
- Enable these APIs:
- Gmail API
- Google Calendar API
- Google Drive API
- Google Sheets API
- Google Docs API
- People API (Contacts)
- Google Tasks API
- Go to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Application type: Desktop app
- Name:
gw-cli - Click Create → Download JSON
- Move the file:
mv ~/Downloads/client_secret_*.json ~/.config/gw/credentials.json
gw auth loginFor headless environments (no browser):
gw auth login --headlessFor multiple accounts:
gw auth login --profile workgw doctor
gw calendar todaygw auth setup # guided setup wizard (creates config + logs in)
gw auth login # OAuth login (opens browser)
gw auth login --headless # print auth URL, paste code manually
gw auth login --profile work # login a named profile
gw auth status # show current token/scope status
gw auth logout # revoke token and delete local filesTokens are stored at ~/.config/gw/token.json by default, or token-{profile}.json when you pass --profile PROFILE.
Upgrading from v0.4.x? Run
gw auth logout && gw auth loginto refresh your token with the new Tasks scope.
Config lives at ~/.config/gw/config.toml:
timezone = "America/Sao_Paulo"
default_calendar = "primary"
credentials_path = "~/.config/gw/credentials.json"
token_path = "~/.config/gw/token.json"
timeout_seconds = 30
[profiles.work]
credentials_path = "~/.config/gw/work-credentials.json"
[profiles.personal]
timezone = "Europe/London"Inspect the active config with:
gw config show
gw config show --json
gw config path
gw --profile work config show --jsongw --help
gw --profile work --help
gw completion zsh
gw completion bash
gw completion fish
gw calendar today
gw calendar agenda --days 7
gw calendar next --json
gw calendar today --all --json
gw calendar create "Standup" "2026-03-26T10:00" "2026-03-26T10:30"
gw calendar update EVENT_ID --title "Rescheduled standup" --start "2026-03-26T11:00" --end "2026-03-26T11:30"
gw calendar delete EVENT_ID
gw calendar list
gw calendar calendars
gw meet create
gw meet create --title "Weekly sync" --json
gw contacts search "alice"
gw contacts list --max 20 --json
gw gmail list --max 5
gw gmail search "from:alice@example.com newer_than:7d"
gw gmail thread 18c0ffee --json
gw gmail count --query "is:unread"
gw gmail mark-read 18c0ffee
gw gmail mark-unread 18c0ffee --json
gw gmail list --query "from:alice@example.com" --json
gw gmail read 18c0ffee
gw gmail send "alice@example.com" "Subject" "Hello"
gw gmail draft "alice@example.com" "Draft subject" "Hello later"
gw gmail trash 18c0ffee
gw gmail archive 18c0ffee
gw gmail label 18c0ffee Work
gw gmail star 18c0ffee
gw drive list --max 20 --json
gw drive search "report"
gw drive search "name contains 'report'"
gw drive upload file.txt
gw drive mkdir "Projects"
gw drive share FILE_ID alice@example.com --role writer
gw drive info FILE_ID --json
gw drive download FILE_ID --out report.pdf
gw drive download FILE_ID --format txt
gw drive download SHEET_FILE_ID --format csv
gw tasks lists
gw tasks list --json
gw tasks add "Buy milk" --due 2026-04-01
gw tasks complete TASK_ID
gw tasks delete TASK_ID
gw sheets read SPREADSHEET_ID "Sheet1!A1:C5"
gw sheets write SPREADSHEET_ID "Sheet1!A1" "data"
gw docs list
gw docs read DOCUMENT_ID
gw docs export DOCUMENT_ID --format txt
gw mcp servegw auth setup
gw auth setup --headless
gw doctor
gw doctor --jsongw auth setup guides you through creating or importing OAuth credentials and then logs in.
gw doctor reports the state of credentials, token, authentication, and timezone configuration.
eval "$(gw completion zsh)"
eval "$(gw completion bash)"
gw completion fish | sourcegw mcp serve starts a stdio Model Context Protocol server for AI agents.
Exposed tools:
gmail_send,gmail_draft,gmail_reply,gmail_forward,gmail_list,gmail_search,gmail_thread,gmail_count,gmail_read,gmail_trash,gmail_archive,gmail_label,gmail_star,gmail_mark_read,gmail_mark_unreadcalendar_today,calendar_tomorrow,calendar_week,calendar_agenda,calendar_next,calendar_create,calendar_list,calendar_delete,calendar_update,meet_createcontacts_search,contacts_listdrive_list,drive_search,drive_mkdir,drive_share,drive_info,drive_upload,drive_downloadsheets_read,sheets_writedocs_read,docs_export,docs_listtasks_lists,tasks_list,tasks_add,tasks_complete,tasks_delete
0success1general or usage error2auth failure3config failure
When --json is enabled, errors are emitted as JSON with the shape {"error": "message", "code": N}.
pip install -e ".[dev]"
pytest
ruff check .gw requests the following Google API scopes during gw auth login:
| Scope | Why |
|---|---|
gmail.send |
Send emails, reply, forward |
gmail.modify |
Read, list, search, trash, archive, label, and star emails |
calendar |
Read, create, update, and delete calendar events |
drive |
List, search, upload, and download Drive files |
tasks |
List, create, complete, and delete Google Tasks |
spreadsheets |
Read and write Sheets data |
documents.readonly |
Read and export Docs |
contacts.readonly |
Search and list contacts |
userinfo.email |
Identify authenticated account |
All scopes are the minimum required for each feature. You can review the exact scope list in src/gw/auth.py.
