| name | gmail-setup |
| description | Connect a Gmail account to this machine, and diagnose it when Gmail calls start failing. Use when the user wants to set up, connect, or authorize Gmail; when they add a second account; when they ask why email stopped working; or when any gmail command returns auth_required, auth_expired, scope_insufficient, client_invalid, or api_not_enabled. Covers the one-time Google Cloud project and OAuth client, the login flow, multiple accounts as profiles, and `gmail doctor`. |
| allowed-tools | Bash(gmail doctor:*) Bash(gmail whoami:*) Bash(gmail --version) |
gmail-setup
Gmail access here is OAuth against the user's own Google Cloud project. Nothing works
until that project exists and consent has been granted once.
Run gmail doctor first, every time. It checks the whole chain (runtime, OAuth
client, token, scopes, egress, two live API calls) and every failing check names the exact
command or console page that fixes it. Do not guess from an error message when one command
gives you the diagnosis.
gmail doctor
gmail doctor --quick
gmail doctor --json
Is it already set up?
gmail whoami
First-time setup
The Google Cloud half is a browser task the user has to do themselves. Point them at the
"Google Cloud setup" section of the project README rather than retyping it; it is roughly
ten minutes and produces one file.
Two things that go wrong constantly and are worth stating up front:
- The OAuth client must be application type Desktop app. A Web client has no loopback
redirect and consent can never complete.
gmail doctor fails the oauth-client check
with this if they picked wrong.
- The Cloud project must stay in Testing with the user added as a test user. Gmail's
gmail.modify scope is "restricted", and a Published project with a restricted scope
hard-blocks at consent with "Access blocked: has not completed the Google verification
process" and no way to click through. The cost of Testing is that refresh tokens expire
after 7 days, so roughly weekly they re-run gmail login --force. That is the correct
trade for a personal tool.
Once ~/.config/gmail-skill/credentials.json exists:
gmail login
gmail doctor
Logging in
gmail login
gmail login --force
gmail login --read-only
gmail login --profile work
gmail logout --profile work
gmail logout --revoke
--force is the answer to almost every auth failure. Google issues a fresh refresh token
and a token carrying every scope.
Headless or over SSH
gmail login starts a loopback listener and opens a browser. On a box with no browser,
pin the port and forward it from the machine that has one:
ssh -L 8765:localhost:8765 user@host
gmail login --port 8765 --no-browser
Google's device-code flow is not an option: it does not accept Gmail scopes.
Several accounts
One OAuth client, one token file per profile. Every command takes --profile, and
$GMAIL_SKILL_PROFILE sets the default.
gmail login --profile work
gmail --profile work search "is:unread"
Reading a failure
| Code | What happened | What to do |
|---|
auth_required | No token for this profile | gmail login |
auth_expired | Refresh token dead: 7-day Testing expiry, password reset, or revoked | gmail login --force |
scope_insufficient | Token predates a scope this verb needs | gmail login --force |
client_invalid | No client JSON, or it is a Web client | README setup; the type must be Desktop app |
api_not_enabled | Gmail API off for the Cloud project | Enable Gmail API in the console |
rate_limited | Per-minute quota | Retriable. Wait, then batch fewer messages |
quota_exceeded | Daily budget or the account send cap | Not retriable today |
Where things live
~/.config/gmail-skill/ (or $GMAIL_SKILL_HOME), directory 0700:
credentials.json is the OAuth client, <profile>.token.json is a live Gmail session at
0600. Never copy either into a repo, a chat, or a bug report. gmail doctor --json is
already redacted: it carries no token and no client secret.