Google OAuth Skill
Authenticate users with Google APIs via OAuth 2.0 to access services like Gmail, Analytics, Drive, Calendar, Sheets, and more.
Prerequisites
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETenvironment variables must be setREDIRECT_URIenvironment variable must be set (e.g. in.env). This must match the authorized redirect URI configured in the Google Cloud Console.- Node.js must be available
Scope Reference
| Service | Scope key | Full scope | Use when |
|---|---|---|---|
| Analytics (read) | analytics.readonly |
https://www.googleapis.com/auth/analytics.readonly |
viewing reports, properties, metrics |
| Gmail (read) | gmail.readonly |
https://www.googleapis.com/auth/gmail.readonly |
reading emails |
| Gmail (send) | gmail.send |
https://www.googleapis.com/auth/gmail.send |
sending emails |
| Gmail (full) | gmail.modify |
https://www.googleapis.com/auth/gmail.modify |
read + write + delete |
| Drive (read) | drive.readonly |
https://www.googleapis.com/auth/drive.readonly |
listing/reading files |
| Drive (full) | drive.file |
https://www.googleapis.com/auth/drive.file |
creating/editing files |
| Calendar (read) | calendar.readonly |
https://www.googleapis.com/auth/calendar.readonly |
viewing events |
| Calendar (write) | calendar.events |
https://www.googleapis.com/auth/calendar.events |
creating/editing events |
| Sheets | spreadsheets |
https://www.googleapis.com/auth/spreadsheets |
reading/writing spreadsheets |
Instructions
When the user asks to interact with a Google service, follow these steps:
Step 1: Identify the scope
Map the user's request to the minimal scope from the table above. Always prefer read-only scopes unless write access is explicitly needed.
Step 2: Check for an existing token
node ~/.claude/skills/google-oauth/scripts/token-store.js check <scope_key>
If exit code is 0 (token is valid), skip to Step 5.
Step 3: Start the callback server
Before proceeding, verify that GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, and REDIRECT_URI are all set. If any are missing, stop and tell the user which variables need to be set in the .env file before authenticating.
Generate a random state value and start the server in the background:
STATE=$(node -e "console.log(require('crypto').randomBytes(16).toString('hex'))")
node ~/.claude/skills/google-oauth/scripts/oauth-callback-server.js 9876 "$STATE" "$REDIRECT_URI" &
OAUTH_PID=$!
Wait briefly for the server to start, then verify it printed LISTENING.
Step 4: Present the authorization URL
Construct the URL using the GOOGLE_CLIENT_ID env var and the chosen scope:
https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&scope=https://www.googleapis.com/auth/SCOPE_KEY&response_type=code&access_type=offline&prompt=consent&state=${STATE}
Tell the user:
Please open this link to authorize access: [the URL]
After you authorize in your browser, the token will be captured automatically.
Then wait for the background server to complete. Check that stdout contains TOKEN_RECEIVED. If the server exits with an error or times out, inform the user and suggest retrying.
Step 5: Use the token
Retrieve the access token:
TOKEN=$(node ~/.claude/skills/google-oauth/scripts/token-store.js get <scope_key>)
Use the token in API calls via curl with the Authorization: Bearer $TOKEN header. For example:
# Google Analytics — list accounts
curl -s -H "Authorization: Bearer $TOKEN" \
"https://analyticsadmin.googleapis.com/v1beta/accounts"
# Gmail — list messages
curl -s -H "Authorization: Bearer $TOKEN" \
"https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10"
# Drive — list files
curl -s -H "Authorization: Bearer $TOKEN" \
"https://www.googleapis.com/drive/v3/files?pageSize=10"
Token refresh
The get command in token-store.js automatically refreshes expired tokens using the stored refresh_token. If refresh fails (e.g., token was revoked), repeat Steps 3-4 to re-authorize.