OAuth 2.1 proxy for Google Workspace MCP — Claude.ai connector for Gmail, Drive, Calendar, Docs, Sheets and more
google-workspace-mcp
OAuth 2.1 proxy for google_workspace_mcp, making it compatible with Claude.ai remote connectors and scheduled tasks.
google_workspace_mcp provides comprehensive Google Workspace access (Gmail, Drive, Calendar, Docs, Sheets, and more), but lacks OAuth 2.1 authentication for Claude.ai connectors. This project wraps it with OAuth 2.1 + Streamable HTTP in a single Docker image.
Features
- 120+ Google Workspace tools: Gmail, Drive, Calendar, Docs, Sheets, Slides, Forms, Chat, Tasks, Contacts, Apps Script, Custom Search
- OAuth 2.1: Fixed client credentials — works with Claude.ai connectors and scheduled tasks
- Dynamic tool discovery: New tools from upstream updates appear automatically
- Single Docker image: Both OAuth proxy and Google Workspace MCP backend in one container
Prerequisites
You need Google Cloud OAuth credentials:
- Go to Google Cloud Console
- Create a project (or use an existing one)
- Enable the APIs you need (Gmail, Calendar, Drive, Docs, Sheets, etc.)
- Go to APIs & Services > OAuth consent screen — configure as "External", add your email as a test user
- Go to APIs & Services > Credentials > Create Credentials > OAuth Client ID — type "Web application"
- Add
http://localhost:8000/oauth2callbackas a redirect URI - Download the
client_secret.json
Quick Start
1. Initial Google OAuth consent (one-time)
Before deploying, run the upstream image locally to authorize your Google account:
mkdir -p google_creds && chmod 777 google_creds
docker run -it --rm -p 8000:8000 --user root \
-v $(pwd)/google_creds:/credentials \
-e GOOGLE_OAUTH_CLIENT_ID="your-client-id" \
-e GOOGLE_OAUTH_CLIENT_SECRET="your-client-secret" \
-e USER_GOOGLE_EMAIL="your-email@gmail.com" \
-e GOOGLE_MCP_CREDENTIALS_DIR=/credentials \
ghcr.io/taylorwilsdon/google_workspace_mcp:latest \
"uv run main.py --transport streamable-http --single-user"
Then trigger auth by calling start_google_auth via the MCP endpoint (or use curl):
# Initialize a session
SESSION=$(curl -si -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"setup","version":"1.0"}}}' \
| grep -i mcp-session-id | awk '{print $2}' | tr -d '\r')
# Trigger Google OAuth
curl -s -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"start_google_auth","arguments":{"user_google_email":"your-email@gmail.com","service_name":"gmail"}}}'
Open the authorization URL from the response in your browser and complete the consent. The tokens will be saved in ./google_creds/.
2. Deploy with OAuth proxy
docker run -d \
-e GOOGLE_OAUTH_CLIENT_ID="your-client-id" \
-e GOOGLE_OAUTH_CLIENT_SECRET="your-client-secret" \
-e USER_GOOGLE_EMAIL="your-email@gmail.com" \
-e GOOGLE_MCP_CREDENTIALS_DIR=/credentials \
-e MCP_SECRET=your_secret_here \
-e SERVER_URL=https://your-domain.example.com \
-v /path/to/client_secret.json:/app/google-mcp/client_secret.json:ro \
-v /path/to/google_creds:/credentials \
-p 3000:3000 \
ghcr.io/afonsofigs/google-workspace-mcp:latest
Check the logs for client_id and client_secret to use with Claude.ai.
Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| MCP_SECRET | Yes | Secret to derive OAuth credentials (printed on startup) |
| SERVER_URL | Yes | Public HTTPS URL (OAuth issuer) |
| GOOGLE_OAUTH_CLIENT_ID | Yes | Google Cloud OAuth client ID |
| GOOGLE_OAUTH_CLIENT_SECRET | Yes | Google Cloud OAuth client secret |
| USER_GOOGLE_EMAIL | Yes | Google account email |
| GOOGLE_MCP_CREDENTIALS_DIR | No | Credentials directory (default: /credentials) |
| TOOL_TIER | No | Tool tier: core, extended, or complete (default: all) |
| PORT | No | OAuth proxy port (default: 3000) |
| BACKEND_PORT | No | Backend port (default: 8000) |
Authentication
Same pattern as obsidian-couchdb-mcp and telegram-bot-mcp:
- Fixed client credentials derived from
MCP_SECRETvia SHA-256 - Auto-approve — no login page; security by fixed credentials
- PKCE (S256) mandatory
- Redirect URIs limited to
claude.aiandclaude.com
Claude.ai Connector Setup
- Deploy with HTTPS (e.g., behind Cloudflare Tunnel or reverse proxy)
- Check logs for
client_idandclient_secret - Go to claude.ai/settings/connectors
- Add custom connector: URL
https://your-domain.example.com/mcp - Enter
client_idandclient_secretfrom logs
Architecture
Claude.ai / Scheduled Tasks
|
v (HTTPS + OAuth 2.1 + Streamable HTTP)
OAuth proxy :3000 (this project)
|
v (HTTP + MCP, localhost)
google_workspace_mcp :8000 (taylorwilsdon)
|
v (Google APIs)
Gmail, Drive, Calendar, Docs, Sheets, ...
Kubernetes Deployment
See k8s/deployment.yaml for an example manifest. You'll need:
- A Secret with your Google OAuth credentials,
client_secret.json, andMCP_SECRET - A PVC to persist the Google OAuth tokens
- After the first deploy, copy the tokens from step 1 into the PVC:
POD=$(kubectl get pod -n google-mcp-ns -l app=google-mcp -o jsonpath='{.items[0].metadata.name}')
kubectl cp ./google_creds/your-email@gmail.com.json google-mcp-ns/$POD:/credentials/
Credits
- google_workspace_mcp — Google Workspace MCP backend
- obsidian-couchdb-mcp — OAuth 2.1 proxy pattern
- telegram-bot-mcp — OAuth 2.1 pattern
License
MIT