I wanted my OpenClaw to have its own Google account — so I could ask it to send email, create calendar events, and edit docs directly from chat.
Simple goal. Messy auth path.
Table of contents
Open Table of contents
Before You Start
- Node.js installed on your VPS
- A dedicated Google account for your bot
- SSH access to your VPS
1) Install gws
npm install -g @googleworkspace/cli
2) Set Up Google Cloud
Before login works, you need OAuth client credentials.
In Google Cloud Console:
- Create a new project.
- Enable the APIs you need, like Gmail, Calendar, and Drive.
- Configure the OAuth consent screen: Menu > APIs & Services > OAuth consent screen.
- Create an OAuth Client ID and choose Desktop app.
- Download
client_secret.json.
Remember to publish your app
If your app stays in Testing mode, any refresh token you get expires automatically after 7 days.
To avoid that:
- Go to
https://console.cloud.google.com/ - Open OAuth consent screen
- Click Audience in the left sidebar
- Click Publish app
- Confirm the action
Important: you do not need full Google verification for this personal setup. Publishing the app changes the status to In Production, which removes the 7-day refresh token expiration.
Put your OAuth client secret on the VPS here:
/home/<your-vps-user>/.config/gws/client_secret.json
Use the same user that will run gws commands.
3) Headless VPS OAuth
gws auth login opens a Google URL with a callback like this:
http://localhost:<random-port>/?code=...
On a VPS, there is no browser. If you open that URL on your laptop without forwarding the callback port, the browser will say success while the CLI still fails.
The fix is SSH port forwarding to the exact callback port.
Authenticate the bot account
Run this on the VPS to authenticate your bot’s Google account:
gws auth login
gws will show an interactive scope selector where you choose which Google apps to grant access to — Drive, Gmail, Calendar, Docs, Slides, and so on. Use least-privilege: select only what your bot actually needs. Avoid Cloud Platform and Cloud Pub/Sub unless you specifically need them.
After confirming scopes, gws returns a Google auth URL with a callback port, for example localhost:39217.
Open a new terminal tab on your laptop and run an SSH port-forwarding tunnel, replacing the port with the one gws printed:
ssh -N -L 39217:localhost:39217 <your-vps-user>@<your-vps-ip-or-tailscale-ip>
Then open the Google auth URL and approve it.
4) Verify Auth Actually Works
gws auth list
gws auth default --account [email protected]
gws gmail users labels list --params '{"userId":"me"}'
If this returns labels, you are connected. Now create a calendar event to confirm the full integration is live:
gws calendar events insert \
--params '{"calendarId":"primary"}' \
--json '{
"summary":"Test Event",
"start":{"dateTime":"2026-03-09T10:00:00+02:00","timeZone":"Europe/Helsinki"},
"end":{"dateTime":"2026-03-09T11:00:00+02:00","timeZone":"Europe/Helsinki"}
}'
Copy-Paste Quick Checklist
# 1) Install
npm install -g @googleworkspace/cli
# 2) Place client secret
mkdir -p /home/<your-vps-user>/.config/gws
# then create/edit: /home/<your-vps-user>/.config/gws/client_secret.json
# 3) Start auth on VPS — select scopes interactively
gws auth login
# 4) In second local terminal, tunnel the callback port printed by gws
ssh -N -L <PORT>:localhost:<PORT> <your-vps-user>@<vps>
# 5) Verify
gws auth list
gws gmail users labels list --params '{"userId":"me"}'
Messy process, but once it’s done your agent can send email, create calendar events, and manage Drive without ever touching a browser.