Google Workspace MCP Server
A private, self-hosted Model Context Protocol server that gives Claude authenticated access to Google Calendar, Gmail, Drive, Docs, Sheets, and Slides via stdio transport.
Features
- 43 tools across 7 Google Workspace services
- Secure token storage: AES-256-GCM encryption with macOS Keychain-stored keys
- No hard deletes: Archive/trash semantics only — Docs, Sheets, and Slides move to ARCHIVED folder, Gmail messages can be archived or trashed (30-day retention)
- Prompt injection defense: 5-stage sanitization pipeline for all untrusted content
- OWASP-aligned security: Input validation, rate limiting, structured logging, PKCE OAuth2
Prerequisites
- Node.js >= 20
- macOS (uses Keychain for key storage)
- A Google Cloud project with OAuth credentials
Google OAuth Setup
1. Create a Google Cloud Project
- Go to Google Cloud Console
- Click Select a project → New Project
- Name it (e.g., "Workspace MCP Server") and click Create
2. Enable APIs
Navigate to APIs & Services → Library and enable:
- Google Calendar API
- Gmail API
- Google Drive API
- Google Docs API
- Google Sheets API
- Google Slides API
3. Configure OAuth Consent Screen
- Go to APIs & Services → OAuth consent screen
- Click Get started (or Edit App if you already have one configured)
- Set User type to External (or Internal if using Google Workspace)
- Fill in the required fields:
- App name: e.g., "Workspace MCP Server"
- User support email: your email address
- Developer contact email: your email address
- On the Scopes step, click Add or remove scopes and add:
https://www.googleapis.com/auth/calendar.eventshttps://www.googleapis.com/auth/gmail.modifyhttps://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/gmail.labelshttps://www.googleapis.com/auth/gmail.settings.basichttps://www.googleapis.com/auth/drive.readonlyhttps://www.googleapis.com/auth/drive.filehttps://www.googleapis.com/auth/documentshttps://www.googleapis.com/auth/spreadsheetshttps://www.googleapis.com/auth/presentations
- Save and continue
4. Add Test Users (Required)
While the app is in "Testing" publishing status (before Google verification), only explicitly listed test users can authenticate. If you skip this step you will get a 403: access_denied error saying the app "has not completed the Google verification process".
- Go to APIs & Services → OAuth consent screen
- Under the Audience section (or Test users tab), click Add users
- Enter the Google account email you will authenticate with (e.g.,
you@gmail.com) - Click Save
You can add up to 100 test users. Only these accounts will be able to complete the OAuth flow while the app is in testing mode. You do not need to submit the app for Google verification — test users are sufficient for personal/self-hosted use.
5. Create OAuth Credentials
- Go to APIs & Services → Credentials
- Click Create Credentials → OAuth client ID
- Choose Desktop application
- Name it (e.g., "MCP Server")
- Click Create and note the Client ID and Client Secret
6. Configure the MCP Server
Set environment variables:
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
Or create a config file at ~/.config/google-workspace-mcp/config.json:
{
"clientId": "your-client-id.apps.googleusercontent.com",
"clientSecret": "your-client-secret"
}
7. First Run
npm install
npm run build
npm start
On first run, the server will:
- Open your browser for Google sign-in
- Ask you to authorize the requested scopes
- Store tokens securely in macOS Keychain + encrypted file
- Start the MCP server on stdio
8. Claude Code Integration
Add to your ~/.claude/settings.json:
{
"mcpServers": {
"google-workspace": {
"command": "node",
"args": ["/path/to/google-workspace-mcp/dist/index.js"],
"env": {
"GOOGLE_CLIENT_ID": "your-client-id",
"GOOGLE_CLIENT_SECRET": "your-client-secret"
}
}
}
}
Available Tools
Gmail (13 tools)
Note for existing users: The
gmail.settings.basicscope was added to enable filter management tools. If you authenticated before this scope was introduced, you will be prompted to re-authenticate the next time your token refresh fails. Re-authentication happens automatically — simply follow the browser prompt when it appears.
gmail_search— Search emails by query (up to 500 results)gmail_get_message— Get full email content by IDgmail_send— Send an emailgmail_create_draft— Create a draft emailgmail_list_labels— List all Gmail labelsgmail_archive— Archive messages (remove from inbox)gmail_modify_labels— Add/remove labels (mark read, categorize, etc.)gmail_trash— Move messages to trash (30-day retention)gmail_create_label— Create labels and sub-labelsgmail_delete_label— Delete a user-created label (messages are not deleted)gmail_list_filters— List all Gmail filters with their criteria and actionsgmail_delete_filter— Delete a Gmail filter by ID (usegmail_list_filtersto find IDs)gmail_create_filter— Create a Gmail filter with criteria and automated actions (label, archive, mark read, star, forward)
Calendar (5 tools)
calendar_list_events— List events in a time rangecalendar_get_event— Get full event detailscalendar_create_event— Create a calendar eventcalendar_create_calendar— Create a new calendarcalendar_update_event— Update an existing event
Drive (7 tools)
drive_search— Search files in Drivedrive_get_file_metadata— Get file metadatadrive_download— Download/export file contentdrive_upload— Upload a file to Drivedrive_create_folder— Create a new folder in Drivedrive_move— Move a file or folder to a different parent folderdrive_create_pdf— Generate a formatted PDF from text content and upload to Drive
Docs (5 tools)
docs_get— Get document contentdocs_create— Create a new documentdocs_update— Update document contentdocs_archive— Archive document (move to ARCHIVED folder)docs_delete— Permanently delete a document (irreversible)
Sheets (6 tools)
sheets_get— Get spreadsheet metadatasheets_create— Create a new spreadsheetsheets_read_range— Read cell values from a rangesheets_update_range— Write cell values to a rangesheets_archive— Archive spreadsheet (move to ARCHIVED folder)sheets_delete— Permanently delete a spreadsheet (irreversible)
Slides (5 tools)
slides_get— Get presentation content (title, slide count, extracted text)slides_create— Create a new presentationslides_add_slide— Add a slide with layout and placeholder textslides_archive— Archive presentation (move to ARCHIVED folder)slides_delete— Permanently delete a presentation (irreversible)
Auth (1 tool)
auth_status— Check authentication status and scopes
Security
- Controlled deletions: Docs/Sheets/Slides support both soft archive (move to ARCHIVED folder) and permanent deletion. Gmail supports archive, trash (30-day retention), and label deletion. HTTP DELETE requests are blocked by default, with a targeted allowlist for specific safe operations (label deletion, file deletion).
- Prompt injection defense: All content from external sources (emails, documents, calendar events) passes through a 5-stage sanitization pipeline before being returned to the LLM.
- Token security: OAuth tokens are encrypted with AES-256-GCM. The encryption key is stored in macOS Keychain.
- Rate limiting: Per-tool rate limits prevent runaway API usage.
- Input validation: All tool inputs are validated with Zod schemas.
Configuration
| Environment Variable | Default | Description | |---|---|---| | GOOGLE_CLIENT_ID | (required) | OAuth client ID | | GOOGLE_CLIENT_SECRET | (required) | OAuth client secret | | MAX_CONTENT_LENGTH | 50000 | Max content length before truncation | | AUTH_TIMEOUT_MS | 300000 | OAuth flow timeout (ms) | | LOG_LEVEL | info | Log level: debug, info, warn, error | | ARCHIVE_FOLDER_NAME | ARCHIVED | Name of the archive folder in Drive |
Troubleshooting
"Permission denied. The requested scope may not be authorized." despite valid token
If auth_status shows the required scope is present but a tool still returns a 403, the Google API itself is not enabled in your Cloud project. Each Google API must be enabled separately — granting an OAuth scope is not enough.
Go to APIs & Services → Library in the Cloud Console and enable the API for the failing service (e.g., Google Slides API for slides_* tools). After enabling, retry immediately — no re-authentication is needed.
Re-authenticating to pick up new scopes
If new scopes were added to the server after your initial auth, your stored token won't include them. Delete the token file to force a fresh OAuth flow:
rm ~/.config/google-workspace-mcp/tokens.enc
Then restart the MCP server (e.g., run /mcp in Claude Code). The browser will open for re-authentication — authorize all requested scopes.
Development
npm install
npm run dev # Run with tsx (hot reload)
npm run build # Compile TypeScript
npm test # Run tests
npm run test:watch # Run tests in watch mode





