Google Workspace MCP Server
Provides comprehensive Gmail management including searching messages with Gmail operators, reading message content, sending emails, managing labels, creating drafts, and batch operations for messages and threads.
Enables full calendar management with capabilities to list calendars, retrieve events with time range filtering, create events with attachments and reminders, modify existing events, and delete events.
Allows interaction with Google Chat spaces including listing chat spaces/rooms, retrieving messages, sending messages to spaces, and searching across chat history.
Requires Google Cloud Project setup with OAuth 2.0 credentials and API enablement for accessing Google Workspace services through the server.
Provides document management capabilities including extracting document text, creating new documents, modifying text content, finding and replacing text, inserting elements like tables and images, managing headers/footers, and handling document comments.
Enables file operations including searching files with query syntax, reading file content in Office formats, listing folder contents, and creating files or fetching from URLs.
Allows form management including creating new forms, retrieving form details and URLs, configuring publish settings, and managing form responses with pagination support.
Provides spreadsheet operations including reading cell ranges, writing/updating/clearing cells, creating new spreadsheets, listing accessible spreadsheets, adding sheets to existing files, and managing sheet comments.
Enables presentation management including creating new presentations, retrieving presentation details, applying multiple updates through batch operations, getting specific slide information, generating slide thumbnails, and managing presentation comments.
Provides task management capabilities including listing tasks with filtering, retrieving task details, creating tasks with hierarchy support, modifying task properties, repositioning tasks, and managing task lists.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Google Workspace MCP Server schedule a team meeting for next Tuesday at 2pm about the Q3 roadmap"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Workspace MCP Server
Full natural language control over Google Calendar, Drive, Gmail, Docs, Sheets, Slides, Forms, Tasks, and Chat through all MCP clients, AI assistants and developer tools.
The most feature-complete Google Workspace MCP server, now with Remote OAuth2.1 multi-user support and 1-click Claude installation.
Support for all free Google accounts (Gmail, Docs, Drive etc) & Google Workspace plans (Starter, Standard, Plus, Enterprise, Non Profit) with expanded app options like Chat & Spaces. Interested in a private cloud instance? That can be arranged.
See it in action:
A quick plug for AI-Enhanced Docs
This README was written with AI assistance, and here's why that matters
As a solo dev building open source tools, comprehensive documentation often wouldn't happen without AI help. Using agentic dev tools like Roo & Claude Code that understand the entire codebase, AI doesn't just regurgitate generic content - it extracts real implementation details and creates accurate, specific documentation.
In this case, Sonnet 4 took a pass & a human (me) verified them 8/16/25.
Overview
A production-ready MCP server that integrates all major Google Workspace services with AI assistants. It supports both single-user operation and multi-user authentication via OAuth 2.1, making it a powerful backend for custom applications. Built with FastMCP for optimal performance, featuring advanced authentication handling, service caching, and streamlined development patterns.
Simplified Setup: Now uses Google Desktop OAuth clients - no redirect URIs or port configuration needed!
Related MCP server: VaultAssist
Features
@ Gmail • ≡ Drive • ⧖ Calendar ≡ Docs
Complete Gmail management, end to end coverage
Full calendar management with advanced features
File operations with Office format support
Document creation, editing & comments
Deep, exhaustive support for fine grained editing
≡ Forms • @ Chat • ≡ Sheets • ≡ Slides
Form creation, publish settings & response management
Space management & messaging capabilities
Spreadsheet operations with flexible cell management
Presentation creation, updates & content manipulation
⊠ Authentication & Security
Advanced OAuth 2.0 & OAuth 2.1 support
Automatic token refresh & session management
Transport-aware callback handling
Multi-user bearer token authentication
Innovative CORS proxy architecture
✓ Tasks • ◆ Custom Search • ↻ Transport Support
Full support for all MCP Transports
OpenAPI compatibility via
mcpoTask & task list management with hierarchy
Programmable Search Engine (PSE) integration
▶ Quick Start
⊠ Credentials
export GOOGLE_OAUTH_CLIENT_ID="..."
export GOOGLE_OAUTH_CLIENT_SECRET="..."▶ Launch Commands
uvx workspace-mcp --tool-tier core
uv run main.py --tools gmail drive★ Tool Tiers
●
core- Essential tools◐
extended- Core + extras○
complete- Everything Details →
1. One-Click Claude Desktop Install (Recommended)
Download: Grab the latest
google_workspace_mcp.dxtfrom the “Releases” pageInstall: Double-click the file – Claude Desktop opens and prompts you to Install
Configure: In Claude Desktop → Settings → Extensions → Google Workspace MCP, paste your Google OAuth credentials
Use it: Start a new Claude chat and call any Google Workspace tool
Why DXT?
Desktop Extensions (
.dxt) bundle the server, dependencies, and manifest so users go from download → working MCP in one click – no terminal, no JSON editing, no version conflicts.
Required Configuration
Required
Variable | Purpose |
| OAuth client ID from Google Cloud |
| OAuth client secret |
| Development only (allows |
Optional
Variable | Purpose |
| Default email for single-user auth |
| API key for Custom Search |
| Search Engine ID for Custom Search |
| Set to |
| Set to |
Claude Desktop stores these securely in the OS keychain; set them once in the extension pane.
Prerequisites
Python 3.10+
Google Cloud Project with OAuth 2.0 credentials
Configuration
1. Create Project
console.cloud.google.com
→ Create new project
→ Note project name2. OAuth Credentials
APIs & Services → Credentials
→ Create Credentials
→ OAuth Client ID
→ Desktop ApplicationDownload & save credentials
3. Enable APIs
APIs & Services → Library
Search & enable:
Calendar, Drive, Gmail,
Docs, Sheets, Slides,
Forms, Tasks, Chat, SearchSee quick links below
Complete Setup Process:
Create OAuth 2.0 Credentials - Visit Google Cloud Console
Create a new project (or use existing)
Navigate to APIs & Services → Credentials
Click Create Credentials → OAuth Client ID
Choose Desktop Application as the application type (no redirect URIs needed!)
Download credentials and note the Client ID and Client Secret
Enable Required APIs - In APIs & Services → Library
Search for and enable each required API
Or use the quick links below for one-click enabling
Configure Environment - Set your credentials:
export GOOGLE_OAUTH_CLIENT_ID="your-client-id" export GOOGLE_OAUTH_CLIENT_SECRET="your-secret"
1.1. Credentials: See Credential Configuration for detailed setup options
Environment Configuration:
◆ Development Mode
export OAUTHLIB_INSECURE_TRANSPORT=1Allows HTTP redirect URIs
@ Default User
export USER_GOOGLE_EMAIL=\
your.email@gmail.comSingle-user authentication
◆ Custom Search
export GOOGLE_PSE_API_KEY=xxx
export GOOGLE_PSE_ENGINE_ID=yyyOptional: Search API setup
Server Configuration:
◆ Base Configuration
export WORKSPACE_MCP_BASE_URI=
http://localhost
export WORKSPACE_MCP_PORT=8000Server URL & port settings
↻ Proxy Support
export MCP_ENABLE_OAUTH21=
trueLeverage multi-user OAuth2.1 clients
@ Default Email
export USER_GOOGLE_EMAIL=\
your.email@gmail.comSkip email in auth flows in single user mode
Variable | Description | Default |
| Base server URI (no port) |
|
| Server listening port |
|
| External URL for reverse proxy setups | None |
| Override OAuth callback URL | Auto-constructed |
| Default auth email | None |
Google Custom Search Setup
1. Create Search Engine
programmablesearchengine.google.com
/controlpanel/create
→ Configure sites or entire web
→ Note your Engine ID (cx)2. Get API Key
developers.google.com
/custom-search/v1/overview
→ Create/select project
→ Enable Custom Search API
→ Create credentials (API Key)3. Set Variables
export GOOGLE_PSE_API_KEY=\
"your-api-key"
export GOOGLE_PSE_ENGINE_ID=\
"your-engine-id"Configure in environment
Complete Setup Process:
Create Search Engine - Visit the Control Panel
Choose "Search the entire web" or specify sites
Copy the Search Engine ID (looks like:
017643444788157684527:6ivsjbpxpqw)
Enable API & Get Key - Visit Google Developers Console
Enable "Custom Search API" in your project
Create credentials → API Key
Restrict key to Custom Search API (recommended)
Configure Environment - Add to your shell or
.env:export GOOGLE_PSE_API_KEY="AIzaSy..." export GOOGLE_PSE_ENGINE_ID="01764344478..."
Start the Server
▶ Quick Start
uv run main.pyDefault stdio mode
◆ HTTP Mode
uv run main.py \
--transport streamable-httpWeb interfaces & debugging
@ Single User
uv run main.py \
--single-userSimplified authentication
▶ Selective Tool Loading
# Load specific services only
uv run main.py --tools gmail drive calendar
uv run main.py --tools sheets docs
# Combine with other flags
uv run main.py --single-user --tools gmail★ Tool Tiers
uv run main.py --tool-tier core # ● Essential tools only
uv run main.py --tool-tier extended # ◐ Core + additional
uv run main.py --tool-tier complete # ○ All available tools◆ Docker Deployment
docker build -t workspace-mcp .
docker run -p 8000:8000 -v $(pwd):/app \
workspace-mcp --transport streamable-http
# With tool selection via environment variables
docker run -e TOOL_TIER=core workspace-mcp
docker run -e TOOLS="gmail drive calendar" workspace-mcpAvailable Services: gmail • drive • calendar • docs • sheets • forms • tasks • chat • search
Tool Tiers
The server organizes tools into three progressive tiers for simplified deployment. Choose a tier that matches your usage needs and API quota requirements.
Available Tiers
● Core (--tool-tier core)
Essential tools for everyday tasks. Perfect for light usage with minimal API quotas. Includes search, read, create, and basic modify operations across all services.
● Extended (--tool-tier extended)
Core functionality plus management tools. Adds labels, folders, batch operations, and advanced search. Ideal for regular usage with moderate API needs.
● Complete (--tool-tier complete)
Full API access including comments, headers/footers, publishing settings, and administrative functions. For power users needing maximum functionality.
Important Notes
▶ Start with core and upgrade as needed
▶ Tiers are cumulative – each includes all previous
▶ Mix and match with --tools for specific services
▶ Configuration in core/tool_tiers.yaml
▶ Authentication included in all tiers
Usage Examples
# Basic tier selection
uv run main.py --tool-tier core # Start with essential tools only
uv run main.py --tool-tier extended # Expand to include management features
uv run main.py --tool-tier complete # Enable all available functionality
# Selective service loading with tiers
uv run main.py --tools gmail drive --tool-tier core # Core tools for specific services
uv run main.py --tools gmail --tool-tier extended # Extended Gmail functionality only
uv run main.py --tools docs sheets --tool-tier complete # Full access to Docs and Sheets📋 Credential Configuration
🚀 Environment Variables
export GOOGLE_OAUTH_CLIENT_ID=\
"your-client-id"
export GOOGLE_OAUTH_CLIENT_SECRET=\
"your-secret"Best for production
📁 File-based
# Download & place in project root
client_secret.json
# Or specify custom path
export GOOGLE_CLIENT_SECRET_PATH=\
/path/to/secret.jsonTraditional method
⚡ .env File
cp .env.oauth21 .env
# Edit .env with credentialsBest for development
Loading Priority
Environment variables (
export VAR=value).envfile in project root (warning - if you run viauvxrather thanuv runfrom the repo directory, you are spawning a standalone process not associated with your clone of the repo and it will not find your .env file without specifying it directly)client_secret.jsonviaGOOGLE_CLIENT_SECRET_PATHDefault
client_secret.jsonin project root
Why Environment Variables?
✅ Docker/K8s ready - Native container support
✅ Cloud platforms - Heroku, Railway, Vercel
✅ CI/CD pipelines - GitHub Actions, Jenkins
✅ No secrets in git - Keep credentials secure
✅ Easy rotation - Update without code changes
🧰 Available Tools
Note: All tools support automatic authentication via
@require_google_service()decorators with 30-minute service caching.
📅 Google Calendar calendar_tools.py
Tool | Tier | Description |
| Core | List accessible calendars |
| Core | Retrieve events with time range filtering |
| Core | Create events with attachments & reminders |
| Core | Update existing events |
| Extended | Remove events |
📁 Google Drive drive_tools.py
Tool | Tier | Description |
| Core | Search files with query syntax |
| Core | Read file content (Office formats) |
| Extended | List folder contents |
| Core | Create files or fetch from URLs |
📧 Gmail gmail_tools.py
Tool | Tier | Description |
| Core | Search with Gmail operators |
| Core | Retrieve message content |
| Core | Batch retrieve message content |
| Core | Send emails |
| Extended | Get full thread content |
| Extended | Modify message labels |
| Extended | List available labels |
| Extended | Create/update/delete labels |
| Extended | Create drafts |
| Complete | Batch retrieve thread content |
| Complete | Batch modify labels |
| Complete | Initialize authentication |
📝 Google Docs docs_tools.py
Tool | Tier | Description |
| Core | Extract document text |
| Core | Create new documents |
| Core | Modify document text |
| Extended | Find documents by name |
| Extended | Find and replace text |
| Extended | List docs in folder |
| Extended | Add tables, lists, page breaks |
| Complete | Insert images from Drive/URLs |
| Complete | Modify headers and footers |
| Complete | Execute multiple operations |
| Complete | Analyze document structure |
| Extended | Export document to PDF |
| Complete | Create data tables |
| Complete | Debug table issues |
| Complete | Read, Reply, Create, Resolve |
📊 Google Sheets sheets_tools.py
Tool | Tier | Description |
| Core | Read cell ranges |
| Core | Write/update/clear cells |
| Core | Create new spreadsheets |
| Extended | List accessible spreadsheets |
| Extended | Get spreadsheet metadata |
| Complete | Add sheets to existing files |
| Complete | Read/create/reply/resolve comments |
🖼️ Google Slides slides_tools.py
Tool | Tier | Description |
| Core | Create new presentations |
| Core | Retrieve presentation details |
| Extended | Apply multiple updates |
| Extended | Get specific slide information |
| Extended | Generate slide thumbnails |
| Complete | Read/create/reply/resolve comments |
📝 Google Forms forms_tools.py
Tool | Tier | Description |
| Core | Create new forms |
| Core | Retrieve form details & URLs |
| Complete | Configure form settings |
| Complete | Get individual responses |
| Extended | List all responses with pagination |
✓ Google Tasks tasks_tools.py
Tool | Tier | Description |
| Core | List tasks with filtering |
| Core | Retrieve task details |
| Core | Create tasks with hierarchy |
| Core | Modify task properties |
| Extended | Remove tasks |
| Complete | Reposition tasks |
| Complete | Hide completed tasks |
| Complete | List/get/create/update/delete task lists |
💬 Google Chat chat_tools.py
Tool | Tier | Description |
| Extended | List chat spaces/rooms |
| Core | Retrieve space messages |
| Core | Send messages to spaces |
| Core | Search across chat history |
🔍 Google Custom Search search_tools.py
Tool | Tier | Description |
| Core | Perform web searches |
| Complete | Retrieve search engine metadata |
| Extended | Search within specific domains |
Tool Tier Legend:
• Core: Essential tools for basic functionality • Minimal API usage • Getting started
• Extended: Core tools + additional features • Regular usage • Expanded capabilities
• Complete: All available tools including advanced features • Power users • Full API access
Connect to Claude Desktop
The server supports two transport modes:
Stdio Mode (Default - Recommended for Claude Desktop)
In general, you should use the one-click DXT installer package for Claude Desktop.
If you are unable to for some reason, you can configure it manually via claude_desktop_config.json
Manual Claude Configuration (Alternative)
Open Claude Desktop Settings → Developer → Edit Config
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Add the server configuration:
{
"mcpServers": {
"google_workspace": {
"command": "uvx",
"args": ["workspace-mcp"],
"env": {
"GOOGLE_OAUTH_CLIENT_ID": "your-client-id",
"GOOGLE_OAUTH_CLIENT_SECRET": "your-secret",
"OAUTHLIB_INSECURE_TRANSPORT": "1"
}
}
}
}2. Advanced / Cross-Platform Installation
If you’re developing, deploying to servers, or using another MCP-capable client, keep reading.
Instant CLI (uvx)
# Requires Python 3.10+ and uvx
# First, set credentials (see Credential Configuration above)
uvx workspace-mcp --tool-tier core # or --tools gmail drive calendarNote: Configure OAuth credentials before running. Supports environment variables,
.envfile, orclient_secret.json.
OAuth 2.1 Support (Multi-User Bearer Token Authentication)
The server includes OAuth 2.1 support for bearer token authentication, enabling multi-user session management. OAuth 2.1 automatically reuses your existing GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET credentials - no additional configuration needed!
When to use OAuth 2.1:
Multiple users accessing the same MCP server instance
Need for bearer token authentication instead of passing user emails
Building web applications or APIs on top of the MCP server
Production environments requiring secure session management
Browser-based clients requiring CORS support
Enabling OAuth 2.1:
To enable OAuth 2.1, set the MCP_ENABLE_OAUTH21 environment variable to true.
# OAuth 2.1 requires HTTP transport mode
export MCP_ENABLE_OAUTH21=true
uv run main.py --transport streamable-httpIf MCP_ENABLE_OAUTH21 is not set to true, the server will use legacy authentication, which is suitable for clients that do not support OAuth 2.1.
This implementation solves two critical challenges when using Google OAuth in browser environments:
Dynamic Client Registration: Google doesn't support OAuth 2.1 dynamic client registration. Our server provides a clever proxy that accepts any client registration request and returns the pre-configured Google OAuth credentials, allowing standards-compliant clients to work seamlessly.
CORS Issues: Google's OAuth endpoints don't include CORS headers, blocking browser-based clients. We implement intelligent proxy endpoints that:
Proxy authorization server discovery requests through
/auth/discovery/authorization-server/{server}Proxy token exchange requests through
/oauth2/tokenAdd proper CORS headers to all responses
Maintain security by only proxying to known Google OAuth endpoints
This architecture enables any OAuth 2.1 compliant client to authenticate users through Google, even from browser environments, without requiring changes to the client implementation.
Stateless Mode (Container-Friendly)
The server supports a stateless mode designed for containerized environments where file system writes should be avoided:
Enabling Stateless Mode:
# Stateless mode requires OAuth 2.1 to be enabled
export MCP_ENABLE_OAUTH21=true
export WORKSPACE_MCP_STATELESS_MODE=true
uv run main.py --transport streamable-httpKey Features:
No file system writes: Credentials are never written to disk
No debug logs: File-based logging is completely disabled
Memory-only sessions: All tokens stored in memory via OAuth 2.1 session store
Container-ready: Perfect for Docker, Kubernetes, and serverless deployments
Token per request: Each request must include a valid Bearer token
Requirements:
Must be used with
MCP_ENABLE_OAUTH21=trueIncompatible with single-user mode
Clients must handle OAuth flow and send valid tokens with each request
This mode is ideal for:
Cloud deployments where persistent storage is unavailable
Multi-tenant environments requiring strict isolation
Containerized applications with read-only filesystems
Serverless functions and ephemeral compute environments
MCP Inspector: No additional configuration needed with desktop OAuth client.
Claude Code Inspector: No additional configuration needed with desktop OAuth client.
VS Code MCP Client Support
{
"servers": {
"google-workspace": {
"url": "http://localhost:8000/mcp/",
"type": "http"
}
}
}Reverse Proxy Setup
If you're running the MCP server behind a reverse proxy (nginx, Apache, Cloudflare, etc.), you have two configuration options:
Problem: When behind a reverse proxy, the server constructs OAuth URLs using internal ports (e.g., http://localhost:8000) but external clients need the public URL (e.g., https://your-domain.com).
Solution 1: Set WORKSPACE_EXTERNAL_URL for all OAuth endpoints:
# This configures all OAuth endpoints to use your external URL
export WORKSPACE_EXTERNAL_URL="https://your-domain.com"Solution 2: Set GOOGLE_OAUTH_REDIRECT_URI for just the callback:
# This only overrides the OAuth callback URL
export GOOGLE_OAUTH_REDIRECT_URI="https://your-domain.com/oauth2callback"You also have options for:
| OAUTH_CUSTOM_REDIRECT_URIS (optional) | Comma-separated list of additional redirect URIs |
| OAUTH_ALLOWED_ORIGINS (optional) | Comma-separated list of additional CORS origins |
Important:
Use
WORKSPACE_EXTERNAL_URLwhen all OAuth endpoints should use the external URL (recommended for reverse proxy setups)Use
GOOGLE_OAUTH_REDIRECT_URIwhen you only need to override the callback URLThe redirect URI must exactly match what's configured in your Google Cloud Console
Your reverse proxy must forward OAuth-related requests (
/oauth2callback,/oauth2/*,/.well-known/*) to the MCP server
# Configure credentials first (see Credential Configuration section)
# Start with specific tools only
uvx workspace-mcp --tools gmail drive calendar tasks
# Start with tool tiers (recommended for most users)
uvx workspace-mcp --tool-tier core # Essential tools
uvx workspace-mcp --tool-tier extended # Core + additional features
uvx workspace-mcp --tool-tier complete # All tools
# Start in HTTP mode for debugging
uvx workspace-mcp --transport streamable-httpRequires Python 3.10+ and uvx. The package is available on PyPI.
Development Installation
For development or customization:
git clone https://github.com/taylorwilsdon/google_workspace_mcp.git
cd google_workspace_mcp
uv run main.pyDevelopment Installation (For Contributors):
{
"mcpServers": {
"google_workspace": {
"command": "uv",
"args": [
"run",
"--directory",
"/path/to/repo/google_workspace_mcp",
"main.py"
],
"env": {
"GOOGLE_OAUTH_CLIENT_ID": "your-client-id",
"GOOGLE_OAUTH_CLIENT_SECRET": "your-secret",
"OAUTHLIB_INSECURE_TRANSPORT": "1"
}
}
}
}HTTP Mode (For debugging or web interfaces)
If you need to use HTTP mode with Claude Desktop:
{
"mcpServers": {
"google_workspace": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:8000/mcp"]
}
}
}Note: Make sure to start the server with --transport streamable-http when using HTTP mode.
First-Time Authentication
The server uses Google Desktop OAuth for simplified authentication:
No redirect URIs needed: Desktop OAuth clients handle authentication without complex callback URLs
Automatic flow: The server manages the entire OAuth process transparently
Transport-agnostic: Works seamlessly in both stdio and HTTP modes
When calling a tool:
Server returns authorization URL
Open URL in browser and authorize
Google provides an authorization code
Paste the code when prompted (or it's handled automatically)
Server completes authentication and retries your request
◆ Development
Project Structure
google_workspace_mcp/
├── auth/ # Authentication system with decorators
├── core/ # MCP server and utilities
├── g{service}/ # Service-specific tools
├── main.py # Server entry point
├── client_secret.json # OAuth credentials (not committed)
└── pyproject.toml # DependenciesAdding New Tools
from auth.service_decorator import require_google_service
@require_google_service("drive", "drive_read") # Service + scope group
async def your_new_tool(service, param1: str, param2: int = 10):
"""Tool description"""
# service is automatically injected and cached
result = service.files().list().execute()
return result # Return native Python objectsArchitecture Highlights
Service Caching: 30-minute TTL reduces authentication overhead
Scope Management: Centralized in
SCOPE_GROUPSfor easy maintenanceError Handling: Native exceptions instead of manual error construction
Multi-Service Support:
@require_multiple_services()for complex tools
Credential Store System
The server includes an abstract credential store API and a default backend for managing Google OAuth credentials with support for multiple storage backends:
Features:
Abstract Interface:
CredentialStorebase class defines standard operations (get, store, delete, list users)Local File Storage:
LocalDirectoryCredentialStoreimplementation stores credentials as JSON filesConfigurable Storage: Environment variable
GOOGLE_MCP_CREDENTIALS_DIRsets storage locationMulti-User Support: Store and manage credentials for multiple Google accounts
Automatic Directory Creation: Storage directory is created automatically if it doesn't exist
Configuration:
# Optional: Set custom credentials directory
export GOOGLE_MCP_CREDENTIALS_DIR="/path/to/credentials"
# Default locations (if GOOGLE_MCP_CREDENTIALS_DIR not set):
# - ~/.google_workspace_mcp/credentials (if home directory accessible)
# - ./.credentials (fallback)Usage Example:
from auth.credential_store import get_credential_store
# Get the global credential store instance
store = get_credential_store()
# Store credentials for a user
store.store_credential("user@example.com", credentials)
# Retrieve credentials
creds = store.get_credential("user@example.com")
# List all users with stored credentials
users = store.list_users()The credential store automatically handles credential serialization, expiry parsing, and provides error handling for storage operations.
⊠ Security
Credentials: Never commit
.env,client_secret.jsonor the.credentials/directory to source control!OAuth Callback: Uses
http://localhost:8000/oauth2callbackfor development (requiresOAUTHLIB_INSECURE_TRANSPORT=1)Transport-Aware Callbacks: Stdio mode starts a minimal HTTP server only for OAuth, ensuring callbacks work in all modes
Production: Use HTTPS & OAuth 2.1 and configure accordingly
Network Exposure: Consider authentication when using
mcpoover networksScope Minimization: Tools request only necessary permissions
◆ Integration with Open WebUI
▶ Instant Start (No Config)
# Set credentials & launch in one command
GOOGLE_OAUTH_CLIENT_ID="your_id" \
GOOGLE_OAUTH_CLIENT_SECRET="your_secret" \
uvx mcpo --port 8000 --api-key "secret" \
-- uvx workspace-mcp◆ Manual Configuration
Create
config.json:
{
"mcpServers": {
"google_workspace": {
"type": "streamablehttp",
"url": "http://localhost:8000/mcp"
}
}
}Start MCPO:
mcpo --port 8001 --config config.json≡ Configure Open WebUI
Navigate to Settings → Connections → Tools
Click Add Tool and enter:
Server URL:
http://localhost:8001/google_workspaceAPI Key: Your mcpo
--api-key(if set)
Save - Google Workspace tools are now available!
≡ License
MIT License - see LICENSE file for details.
Validations:
Available Tools
84 toolsbatch_modify_gmail_message_labelsB
Adds or removes labels from multiple Gmail messages in a single batch request.
Args: user_google_email (str): The user's Google email address. Required. message_ids (List[str]): A list of message IDs to modify. add_label_ids (Optional[List[str]]): List of label IDs to add to the messages. remove_label_ids (Optional[List[str]]): List of label IDs to remove from the messages.
Returns: str: Confirmation message of the label changes applied to the messages.
Inputs: message_ids (required), user_google_email (required), add_label_ids, remove_label_ids. Returns: result
batch_update_docA
Executes multiple document operations in a single atomic batch update.
Args: user_google_email: User's Google email address document_id: ID of the document to update operations: List of operation dictionaries. Each operation should contain: - type: Operation type ('insert_text', 'delete_text', 'replace_text', 'format_text', 'insert_table', 'insert_page_break') - Additional parameters specific to each operation type
Example operations: [ {"type": "insert_text", "index": 1, "text": "Hello World"}, {"type": "format_text", "start_index": 1, "end_index": 12, "bold": true}, {"type": "insert_table", "index": 20, "rows": 2, "columns": 3} ]
Returns: str: Confirmation message with batch operation results
Inputs: document_id (required), operations (required), user_google_email (required). Returns: result
batch_update_presentationC
Apply batch updates to a Google Slides presentation.
Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation to update. requests (List[Dict[str, Any]]): List of update requests to apply.
Returns: str: Details about the batch update operation results.
Inputs: presentation_id (required), requests (required), user_google_email (required). Returns: result
check_drive_file_public_accessB
Searches for a file by name and checks if it has public link sharing enabled.
Args: user_google_email (str): The user's Google email address. Required. file_name (str): The name of the file to check.
Returns: str: Information about the file's sharing status and whether it can be used in Google Docs.
Inputs: file_name (required), user_google_email (required). Returns: result
clear_completed_tasksB
Clear all completed tasks from a task list. The tasks will be marked as hidden.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list to clear completed tasks from.
Returns: str: Confirmation message.
Inputs: task_list_id (required), user_google_email (required). Returns: result
create_docC
Creates a new Google Doc and optionally inserts initial content.
Returns: str: Confirmation message with document ID and link.
Inputs: title (required), user_google_email (required), content. Returns: result
create_document_commentC
Create a new comment on a Google Document.
Inputs: comment_content (required), document_id (required), user_google_email (required). Returns: result
create_drive_fileA
Creates a new file in Google Drive, supporting creation within shared drives. Accepts either direct content or a fileUrl to fetch the content from.
Args: user_google_email (str): The user's Google email address. Required. file_name (str): The name for the new file. content (Optional[str]): If provided, the content to write to the file. folder_id (str): The ID of the parent folder. Defaults to 'root'. For shared drives, this must be a folder ID within the shared drive. mime_type (str): The MIME type of the file. Defaults to 'text/plain'. fileUrl (Optional[str]): If provided, fetches the file content from this URL.
Returns: str: Confirmation message of the successful file creation with file link.
Inputs: file_name (required), user_google_email (required), content, fileUrl, +2 more. Returns: result
create_eventA
Creates a new event.
Args: user_google_email (str): The user's Google email address. Required. summary (str): Event title. start_time (str): Start time (RFC3339, e.g., "2023-10-27T10:00:00-07:00" or "2023-10-27" for all-day). end_time (str): End time (RFC3339, e.g., "2023-10-27T11:00:00-07:00" or "2023-10-28" for all-day). calendar_id (str): Calendar ID (default: 'primary'). description (Optional[str]): Event description. location (Optional[str]): Event location. attendees (Optional[List[str]]): Attendee email addresses. timezone (Optional[str]): Timezone (e.g., "America/New_York"). attachments (Optional[List[str]]): List of Google Drive file URLs or IDs to attach to the event. add_google_meet (bool): Whether to add a Google Meet video conference to the event. Defaults to False. reminders (Optional[Union[str, List[Dict[str, Any]]]]): JSON string or list of reminder objects. Each should have 'method' ("popup" or "email") and 'minutes' (0-40320). Max 5 reminders. Example: '[{"method": "popup", "minutes": 15}]' or [{"method": "popup", "minutes": 15}] use_default_reminders (bool): Whether to use calendar's default reminders. If False, uses custom reminders. Defaults to True.
Returns: str: Confirmation message of the successful event creation with event link.
Inputs: end_time (required), start_time (required), summary (required), user_google_email (required), +9 more. Returns: result
create_formA
Create a new form using the title given in the provided form message in the request.
Args: user_google_email (str): The user's Google email address. Required. title (str): The title of the form. description (Optional[str]): The description of the form. document_title (Optional[str]): The document title (shown in browser tab).
Returns: str: Confirmation message with form ID and edit URL.
Inputs: title (required), user_google_email (required), description, document_title. Returns: result
create_presentationB
Create a new Google Slides presentation.
Args: user_google_email (str): The user's Google email address. Required. title (str): The title for the new presentation. Defaults to "Untitled Presentation".
Returns: str: Details about the created presentation including ID and URL.
Inputs: user_google_email (required), title. Returns: result
create_presentation_commentC
Create a new comment on a Google Presentation.
Inputs: comment_content (required), presentation_id (required), user_google_email (required). Returns: result
create_sheetB
Creates a new sheet within an existing spreadsheet.
Args: user_google_email (str): The user's Google email address. Required. spreadsheet_id (str): The ID of the spreadsheet. Required. sheet_name (str): The name of the new sheet. Required.
Returns: str: Confirmation message of the successful sheet creation.
Inputs: sheet_name (required), spreadsheet_id (required), user_google_email (required). Returns: result
create_spreadsheetB
Creates a new Google Spreadsheet.
Args: user_google_email (str): The user's Google email address. Required. title (str): The title of the new spreadsheet. Required. sheet_names (Optional[List[str]]): List of sheet names to create. If not provided, creates one sheet with default name.
Returns: str: Information about the newly created spreadsheet including ID and URL.
Inputs: title (required), user_google_email (required), sheet_names. Returns: result
create_spreadsheet_commentC
Create a new comment on a Google Spreadsheet.
Inputs: comment_content (required), spreadsheet_id (required), user_google_email (required). Returns: result
create_table_with_dataA
Creates a table and populates it with data in one reliable operation.
CRITICAL: YOU MUST CALL inspect_doc_structure FIRST TO GET THE INDEX!
MANDATORY WORKFLOW - DO THESE STEPS IN ORDER:
Step 1: ALWAYS call inspect_doc_structure first Step 2: Use the 'total_length' value from inspect_doc_structure as your index Step 3: Format data as 2D list: [["col1", "col2"], ["row1col1", "row1col2"]] Step 4: Call this function with the correct index and data
EXAMPLE DATA FORMAT: table_data = [ ["Header1", "Header2", "Header3"], # Row 0 - headers ["Data1", "Data2", "Data3"], # Row 1 - first data row ["Data4", "Data5", "Data6"] # Row 2 - second data row ]
CRITICAL INDEX REQUIREMENTS:
NEVER use index values like 1, 2, 10 without calling inspect_doc_structure first
ALWAYS get index from inspect_doc_structure 'total_length' field
Index must be a valid insertion point in the document
DATA FORMAT REQUIREMENTS:
Must be 2D list of strings only
Each inner list = one table row
All rows MUST have same number of columns
Use empty strings "" for empty cells, never None
Use debug_table_structure after creation to verify results
Args: user_google_email: User's Google email address document_id: ID of the document to update table_data: 2D list of strings - EXACT format: [["col1", "col2"], ["row1col1", "row1col2"]] index: Document position (MANDATORY: get from inspect_doc_structure 'total_length') bold_headers: Whether to make first row bold (default: true)
Returns: str: Confirmation with table details and link
Inputs: document_id (required), index (required), table_data (required), user_google_email (required), +1 more. Returns: result
create_taskA
Create a new task in a task list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list to create the task in. title (str): The title of the task. notes (Optional[str]): Notes/description for the task. due (Optional[str]): Due date in RFC 3339 format (e.g., "2024-12-31T23:59:59Z"). parent (Optional[str]): Parent task ID (for subtasks). previous (Optional[str]): Previous sibling task ID (for positioning).
Returns: str: Confirmation message with the new task ID and details.
Inputs: task_list_id (required), title (required), user_google_email (required), due, +3 more. Returns: result
create_task_listB
Create a new task list.
Args: user_google_email (str): The user's Google email address. Required. title (str): The title of the new task list.
Returns: str: Confirmation message with the new task list ID and details.
Inputs: title (required), user_google_email (required). Returns: result
debug_table_structureA
ESSENTIAL DEBUGGING TOOL - Use this whenever tables don't work as expected.
USE THIS IMMEDIATELY WHEN:
Table population put data in wrong cells
You get "table not found" errors
Data appears concatenated in first cell
Need to understand existing table structure
Planning to use populate_existing_table
WHAT THIS SHOWS YOU:
Exact table dimensions (rows × columns)
Each cell's position coordinates (row,col)
Current content in each cell
Insertion indices for each cell
Table boundaries and ranges
HOW TO READ THE OUTPUT:
"dimensions": "2x3" = 2 rows, 3 columns
"position": "(0,0)" = first row, first column
"current_content": What's actually in each cell right now
"insertion_index": Where new text would be inserted in that cell
WORKFLOW INTEGRATION:
After creating table → Use this to verify structure
Before populating → Use this to plan your data format
After population fails → Use this to see what went wrong
When debugging → Compare your data array to actual table structure
Args: user_google_email: User's Google email address document_id: ID of the document to inspect table_index: Which table to debug (0 = first table, 1 = second table, etc.)
Returns: str: Detailed JSON structure showing table layout, cell positions, and current content
Inputs: document_id (required), user_google_email (required), table_index. Returns: result
delete_eventB
Deletes an existing event.
Args: user_google_email (str): The user's Google email address. Required. event_id (str): The ID of the event to delete. calendar_id (str): Calendar ID (default: 'primary').
Returns: str: Confirmation message of the successful event deletion.
Inputs: event_id (required), user_google_email (required), calendar_id. Returns: result
delete_taskB
Delete a task from a task list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list containing the task. task_id (str): The ID of the task to delete.
Returns: str: Confirmation message.
Inputs: task_id (required), task_list_id (required), user_google_email (required). Returns: result
delete_task_listA
Delete a task list. Note: This will also delete all tasks in the list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list to delete.
Returns: str: Confirmation message.
Inputs: task_list_id (required), user_google_email (required). Returns: result
draft_gmail_messageA
Creates a draft email in the user's Gmail account. Supports both new drafts and reply drafts.
Args: user_google_email (str): The user's Google email address. Required. subject (str): Email subject. body (str): Email body (plain text). to (Optional[str]): Optional recipient email address. Can be left empty for drafts. cc (Optional[str]): Optional CC email address. bcc (Optional[str]): Optional BCC email address. thread_id (Optional[str]): Optional Gmail thread ID to reply within. When provided, creates a reply draft. in_reply_to (Optional[str]): Optional Message-ID of the message being replied to. Used for proper threading. references (Optional[str]): Optional chain of Message-IDs for proper threading. Should include all previous Message-IDs.
Returns: str: Confirmation message with the created draft's ID.
Examples: # Create a new draft draft_gmail_message(subject="Hello", body="Hi there!", to="user@example.com")
# Create a draft with CC and BCC
draft_gmail_message(
subject="Project Update",
body="Here's the latest update...",
to="user@example.com",
cc="manager@example.com",
bcc="archive@example.com"
)
# Create a reply draft
draft_gmail_message(
subject="Re: Meeting tomorrow",
body="Thanks for the update!",
to="user@example.com",
thread_id="thread_123",
in_reply_to="<message123@gmail.com>",
references="<original@gmail.com> <message123@gmail.com>"
)Inputs: body (required), subject (required), user_google_email (required), bcc, +5 more. Returns: result
export_doc_to_pdfA
Exports a Google Doc to PDF format and saves it to Google Drive.
Args: user_google_email: User's Google email address document_id: ID of the Google Doc to export pdf_filename: Name for the PDF file (optional - if not provided, uses original name + "_PDF") folder_id: Drive folder ID to save PDF in (optional - if not provided, saves in root)
Returns: str: Confirmation message with PDF file details and links
Inputs: document_id (required), user_google_email (required), folder_id, pdf_filename. Returns: result
find_and_replace_docB
Finds and replaces text throughout a Google Doc.
Args: user_google_email: User's Google email address document_id: ID of the document to update find_text: Text to search for replace_text: Text to replace with match_case: Whether to match case exactly
Returns: str: Confirmation message with replacement count
Inputs: document_id (required), find_text (required), replace_text (required), user_google_email (required), +1 more. Returns: result
get_doc_contentA
Retrieves content of a Google Doc or a Drive file (like .docx) identified by document_id.
Native Google Docs: Fetches content via Docs API.
Office files (.docx, etc.) stored in Drive: Downloads via Drive API and extracts text.
Returns: str: The document content with metadata header.
Inputs: docs_service (required), document_id (required), drive_service (required), user_google_email (required). Returns: result
get_drive_file_contentA
Retrieves the content of a specific Google Drive file by ID, supporting files in shared drives.
• Native Google Docs, Sheets, Slides → exported as text / CSV. • Office files (.docx, .xlsx, .pptx) → unzipped & parsed with std-lib to extract readable text. • Any other file → downloaded; tries UTF-8 decode, else notes binary.
Args: user_google_email: The user’s Google email address. file_id: Drive file ID.
Returns: str: The file content as plain text with metadata header.
Inputs: file_id (required), user_google_email (required). Returns: result
get_drive_file_permissionsB
Gets detailed metadata about a Google Drive file including sharing permissions.
Args: user_google_email (str): The user's Google email address. Required. file_id (str): The ID of the file to check permissions for.
Returns: str: Detailed file metadata including sharing status and URLs.
Inputs: file_id (required), user_google_email (required). Returns: result
get_eventsA
Retrieves events from a specified Google Calendar. Can retrieve a single event by ID or multiple events within a time range. You can also search for events by keyword by supplying the optional "query" param.
Args:
user_google_email (str): The user's Google email address. Required.
calendar_id (str): The ID of the calendar to query. Use 'primary' for the user's primary calendar. Defaults to 'primary'. Calendar IDs can be obtained using list_calendars.
event_id (Optional[str]): The ID of a specific event to retrieve. If provided, retrieves only this event and ignores time filtering parameters.
time_min (Optional[str]): The start of the time range (inclusive) in RFC3339 format (e.g., '2024-05-12T10:00:00Z' or '2024-05-12'). If omitted, defaults to the current time. Ignored if event_id is provided.
time_max (Optional[str]): The end of the time range (exclusive) in RFC3339 format. If omitted, events starting from time_min onwards are considered (up to max_results). Ignored if event_id is provided.
max_results (int): The maximum number of events to return. Defaults to 25. Ignored if event_id is provided.
query (Optional[str]): A keyword to search for within event fields (summary, description, location). Ignored if event_id is provided.
detailed (bool): Whether to return detailed event information including description, location, and attendees. Defaults to False.
Returns: str: A formatted list of events (summary, start and end times, link) within the specified range, or detailed information for a single event if event_id is provided.
Inputs: user_google_email (required), calendar_id, detailed, event_id, +4 more. Returns: result
get_formC
Get a form.
Args: user_google_email (str): The user's Google email address. Required. form_id (str): The ID of the form to retrieve.
Returns: str: Form details including title, description, questions, and URLs.
Inputs: form_id (required), user_google_email (required). Returns: result
get_form_responseB
Get one response from the form.
Args: user_google_email (str): The user's Google email address. Required. form_id (str): The ID of the form. response_id (str): The ID of the response to retrieve.
Returns: str: Response details including answers and metadata.
Inputs: form_id (required), response_id (required), user_google_email (required). Returns: result
get_gmail_message_contentA
Retrieves the full content (subject, sender, plain text body) of a specific Gmail message.
Args: message_id (str): The unique ID of the Gmail message to retrieve. user_google_email (str): The user's Google email address. Required.
Returns: str: The message details including subject, sender, and body content.
Inputs: message_id (required), user_google_email (required). Returns: result
get_gmail_messages_content_batchA
Retrieves the content of multiple Gmail messages in a single batch request. Supports up to 25 messages per batch to prevent SSL connection exhaustion.
Args: message_ids (List[str]): List of Gmail message IDs to retrieve (max 25 per batch). user_google_email (str): The user's Google email address. Required. format (Literal["full", "metadata"]): Message format. "full" includes body, "metadata" only headers.
Returns: str: A formatted list of message contents with separators.
Inputs: message_ids (required), user_google_email (required), format. Returns: result
get_gmail_thread_contentC
Retrieves the complete content of a Gmail conversation thread, including all messages.
Args: thread_id (str): The unique ID of the Gmail thread to retrieve. user_google_email (str): The user's Google email address. Required.
Returns: str: The complete thread content with all messages formatted for reading.
Inputs: thread_id (required), user_google_email (required). Returns: result
get_gmail_threads_content_batchA
Retrieves the content of multiple Gmail threads in a single batch request. Supports up to 25 threads per batch to prevent SSL connection exhaustion.
Args: thread_ids (List[str]): A list of Gmail thread IDs to retrieve. The function will automatically batch requests in chunks of 25. user_google_email (str): The user's Google email address. Required.
Returns: str: A formatted list of thread contents with separators.
Inputs: thread_ids (required), user_google_email (required). Returns: result
get_messagesC
Retrieves messages from a Google Chat space.
Returns: str: Formatted messages from the specified space.
Inputs: space_id (required), user_google_email (required), order_by, page_size. Returns: result
get_pageC
Get details about a specific page (slide) in a presentation.
Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation. page_object_id (str): The object ID of the page/slide to retrieve.
Returns: str: Details about the specific page including elements and layout.
Inputs: page_object_id (required), presentation_id (required), user_google_email (required). Returns: result
get_page_thumbnailB
Generate a thumbnail URL for a specific page (slide) in a presentation.
Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation. page_object_id (str): The object ID of the page/slide. thumbnail_size (str): Size of thumbnail ("LARGE", "MEDIUM", "SMALL"). Defaults to "MEDIUM".
Returns: str: URL to the generated thumbnail image.
Inputs: page_object_id (required), presentation_id (required), user_google_email (required), thumbnail_size. Returns: result
get_presentationC
Get details about a Google Slides presentation.
Args: user_google_email (str): The user's Google email address. Required. presentation_id (str): The ID of the presentation to retrieve.
Returns: str: Details about the presentation including title, slides count, and metadata.
Inputs: presentation_id (required), user_google_email (required). Returns: result
get_search_engine_infoB
Retrieves metadata about a Programmable Search Engine.
Args: user_google_email (str): The user's Google email address. Required.
Returns: str: Information about the search engine including its configuration and available refinements.
Inputs: user_google_email (required). Returns: result
get_spreadsheet_infoB
Gets information about a specific spreadsheet including its sheets.
Args: user_google_email (str): The user's Google email address. Required. spreadsheet_id (str): The ID of the spreadsheet to get info for. Required.
Returns: str: Formatted spreadsheet information including title and sheets list.
Inputs: spreadsheet_id (required), user_google_email (required). Returns: result
get_taskC
Get details of a specific task.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list containing the task. task_id (str): The ID of the task to retrieve.
Returns: str: Task details including title, notes, status, due date, etc.
Inputs: task_id (required), task_list_id (required), user_google_email (required). Returns: result
get_task_listB
Get details of a specific task list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list to retrieve.
Returns: str: Task list details including title, ID, and last updated time.
Inputs: task_list_id (required), user_google_email (required). Returns: result
insert_doc_elementsB
Inserts structural elements like tables, lists, or page breaks into a Google Doc.
Args: user_google_email: User's Google email address document_id: ID of the document to update element_type: Type of element to insert ("table", "list", "page_break") index: Position to insert element (0-based) rows: Number of rows for table (required for table) columns: Number of columns for table (required for table) list_type: Type of list ("UNORDERED", "ORDERED") (required for list) text: Initial text content for list items
Returns: str: Confirmation message with insertion details
Inputs: document_id (required), element_type (required), index (required), user_google_email (required), +4 more. Returns: result
insert_doc_imageB
Inserts an image into a Google Doc from Drive or a URL.
Args: user_google_email: User's Google email address document_id: ID of the document to update image_source: Drive file ID or public image URL index: Position to insert image (0-based) width: Image width in points (optional) height: Image height in points (optional)
Returns: str: Confirmation message with insertion details
Inputs: docs_service (required), document_id (required), drive_service (required), image_source (required), +4 more. Returns: result
inspect_doc_structureA
Essential tool for finding safe insertion points and understanding document structure.
USE THIS FOR:
Finding the correct index for table insertion
Understanding document layout before making changes
Locating existing tables and their positions
Getting document statistics and complexity info
CRITICAL FOR TABLE OPERATIONS: ALWAYS call this BEFORE creating tables to get a safe insertion index.
WHAT THE OUTPUT SHOWS:
total_elements: Number of document elements
total_length: Maximum safe index for insertion
tables: Number of existing tables
table_details: Position and dimensions of each table
WORKFLOW: Step 1: Call this function Step 2: Note the "total_length" value Step 3: Use an index < total_length for table insertion Step 4: Create your table
Args: user_google_email: User's Google email address document_id: ID of the document to inspect detailed: Whether to return detailed structure information
Returns: str: JSON string containing document structure and safe insertion indices
Inputs: document_id (required), user_google_email (required), detailed. Returns: result
list_calendarsB
Retrieves a list of calendars accessible to the authenticated user.
Args: user_google_email (str): The user's Google email address. Required.
Returns: str: A formatted list of the user's calendars (summary, ID, primary status).
Inputs: user_google_email (required). Returns: result
list_docs_in_folderC
Lists Google Docs within a specific Drive folder.
Returns: str: A formatted list of Google Docs in the specified folder.
Inputs: user_google_email (required), folder_id, page_size. Returns: result
list_drive_itemsA
Lists files and folders, supporting shared drives.
If drive_id is specified, lists items within that shared drive. folder_id is then relative to that drive (or use drive_id as folder_id for root).
If drive_id is not specified, lists items from user's "My Drive" and accessible shared drives (if include_items_from_all_drives is True).
Args:
user_google_email (str): The user's Google email address. Required.
folder_id (str): The ID of the Google Drive folder. Defaults to 'root'. For a shared drive, this can be the shared drive's ID to list its root, or a folder ID within that shared drive.
page_size (int): The maximum number of items to return. Defaults to 100.
drive_id (Optional[str]): ID of the shared drive. If provided, the listing is scoped to this drive.
include_items_from_all_drives (bool): Whether items from all accessible shared drives should be included if drive_id is not set. Defaults to True.
corpora (Optional[str]): Corpus to query ('user', 'drive', 'allDrives'). If drive_id is set and corpora is None, 'drive' is used. If None and no drive_id, API defaults apply.
Returns: str: A formatted list of files/folders in the specified folder.
Inputs: user_google_email (required), corpora, drive_id, folder_id, +2 more. Returns: result
list_form_responsesB
List a form's responses.
Args: user_google_email (str): The user's Google email address. Required. form_id (str): The ID of the form. page_size (int): Maximum number of responses to return. Defaults to 10. page_token (Optional[str]): Token for retrieving next page of results.
Returns: str: List of responses with basic details and pagination info.
Inputs: form_id (required), user_google_email (required), page_size, page_token. Returns: result
list_gmail_labelsC
Lists all labels in the user's Gmail account.
Args: user_google_email (str): The user's Google email address. Required.
Returns: str: A formatted list of all labels with their IDs, names, and types.
Inputs: user_google_email (required). Returns: result
list_spacesC
Lists Google Chat spaces (rooms and direct messages) accessible to the user.
Returns: str: A formatted list of Google Chat spaces accessible to the user.
Inputs: user_google_email (required), page_size, space_type. Returns: result
list_spreadsheetsC
Lists spreadsheets from Google Drive that the user has access to.
Args: user_google_email (str): The user's Google email address. Required. max_results (int): Maximum number of spreadsheets to return. Defaults to 25.
Returns: str: A formatted list of spreadsheet files (name, ID, modified time).
Inputs: user_google_email (required), max_results. Returns: result
list_task_listsB
List all task lists for the user.
Args: user_google_email (str): The user's Google email address. Required. max_results (int): Maximum number of task lists to return (default: 1000, max: 1000). page_token (Optional[str]): Token for pagination.
Returns: str: List of task lists with their IDs, titles, and details.
Inputs: user_google_email (required), max_results, page_token. Returns: result
list_tasksA
List all tasks in a specific task list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list to retrieve tasks from. max_results (int): Maximum number of tasks to return. (default: 20, max: 10000). page_token (Optional[str]): Token for pagination. show_completed (bool): Whether to include completed tasks (default: True). Note that show_hidden must also be true to show tasks completed in first party clients, such as the web UI and Google's mobile apps. show_deleted (bool): Whether to include deleted tasks (default: False). show_hidden (bool): Whether to include hidden tasks (default: False). show_assigned (bool): Whether to include assigned tasks (default: False). completed_max (Optional[str]): Upper bound for completion date (RFC 3339 timestamp). completed_min (Optional[str]): Lower bound for completion date (RFC 3339 timestamp). due_max (Optional[str]): Upper bound for due date (RFC 3339 timestamp). due_min (Optional[str]): Lower bound for due date (RFC 3339 timestamp). updated_min (Optional[str]): Lower bound for last modification time (RFC 3339 timestamp).
Returns: str: List of tasks with their details.
Inputs: task_list_id (required), user_google_email (required), completed_max, completed_min, +9 more. Returns: result
manage_gmail_labelB
Manages Gmail labels: create, update, or delete labels.
Args: user_google_email (str): The user's Google email address. Required. action (Literal["create", "update", "delete"]): Action to perform on the label. name (Optional[str]): Label name. Required for create, optional for update. label_id (Optional[str]): Label ID. Required for update and delete operations. label_list_visibility (Literal["labelShow", "labelHide"]): Whether the label is shown in the label list. message_list_visibility (Literal["show", "hide"]): Whether the label is shown in the message list.
Returns: str: Confirmation message of the label operation.
Inputs: action (required), user_google_email (required), label_id, label_list_visibility, +2 more. Returns: result
modify_doc_textA
Modifies text in a Google Doc - can insert/replace text and/or apply formatting in a single operation.
Args: user_google_email: User's Google email address document_id: ID of the document to update start_index: Start position for operation (0-based) end_index: End position for text replacement/formatting (if not provided with text, text is inserted) text: New text to insert or replace with (optional - can format existing text without changing it) bold: Whether to make text bold (True/False/None to leave unchanged) italic: Whether to make text italic (True/False/None to leave unchanged) underline: Whether to underline text (True/False/None to leave unchanged) font_size: Font size in points font_family: Font family name (e.g., "Arial", "Times New Roman")
Returns: str: Confirmation message with operation details
Inputs: document_id (required), start_index (required), user_google_email (required), bold, +6 more. Returns: result
modify_eventA
Modifies an existing event.
Args: user_google_email (str): The user's Google email address. Required. event_id (str): The ID of the event to modify. calendar_id (str): Calendar ID (default: 'primary'). summary (Optional[str]): New event title. start_time (Optional[str]): New start time (RFC3339, e.g., "2023-10-27T10:00:00-07:00" or "2023-10-27" for all-day). end_time (Optional[str]): New end time (RFC3339, e.g., "2023-10-27T11:00:00-07:00" or "2023-10-28" for all-day). description (Optional[str]): New event description. location (Optional[str]): New event location. attendees (Optional[List[str]]): New attendee email addresses. timezone (Optional[str]): New timezone (e.g., "America/New_York"). add_google_meet (Optional[bool]): Whether to add or remove Google Meet video conference. If True, adds Google Meet; if False, removes it; if None, leaves unchanged. reminders (Optional[Union[str, List[Dict[str, Any]]]]): JSON string or list of reminder objects to replace existing reminders. Each should have 'method' ("popup" or "email") and 'minutes' (0-40320). Max 5 reminders. Example: '[{"method": "popup", "minutes": 15}]' or [{"method": "popup", "minutes": 15}] use_default_reminders (Optional[bool]): Whether to use calendar's default reminders. If specified, overrides current reminder settings.
Returns: str: Confirmation message of the successful event modification with event link.
Inputs: event_id (required), user_google_email (required), add_google_meet, attendees, +9 more. Returns: result
modify_gmail_message_labelsA
Adds or removes labels from a Gmail message. To archive an email, remove the INBOX label. To delete an email, add the TRASH label.
Args: user_google_email (str): The user's Google email address. Required. message_id (str): The ID of the message to modify. add_label_ids (Optional[List[str]]): List of label IDs to add to the message. remove_label_ids (Optional[List[str]]): List of label IDs to remove from the message.
Returns: str: Confirmation message of the label changes applied to the message.
Inputs: message_id (required), user_google_email (required), add_label_ids, remove_label_ids. Returns: result
modify_sheet_valuesA
Modifies values in a specific range of a Google Sheet - can write, update, or clear values.
Args: user_google_email (str): The user's Google email address. Required. spreadsheet_id (str): The ID of the spreadsheet. Required. range_name (str): The range to modify (e.g., "Sheet1!A1:D10", "A1:D10"). Required. values (Optional[Union[str, List[List[str]]]]): 2D array of values to write/update. Can be a JSON string or Python list. Required unless clear_values=True. value_input_option (str): How to interpret input values ("RAW" or "USER_ENTERED"). Defaults to "USER_ENTERED". clear_values (bool): If True, clears the range instead of writing values. Defaults to False.
Returns: str: Confirmation message of the successful modification operation.
Inputs: range_name (required), spreadsheet_id (required), user_google_email (required), clear_values, +2 more. Returns: result
move_taskA
Move a task to a different position or parent within the same list, or to a different list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the current task list containing the task. task_id (str): The ID of the task to move. parent (Optional[str]): New parent task ID (for making it a subtask). previous (Optional[str]): Previous sibling task ID (for positioning). destination_task_list (Optional[str]): Destination task list ID (for moving between lists).
Returns: str: Confirmation message with updated task details.
Inputs: task_id (required), task_list_id (required), user_google_email (required), destination_task_list, +2 more. Returns: result
read_document_commentsC
Read all comments from a Google Document.
Inputs: document_id (required), user_google_email (required). Returns: result
read_presentation_commentsC
Read all comments from a Google Presentation.
Inputs: presentation_id (required), user_google_email (required). Returns: result
read_sheet_valuesB
Reads values from a specific range in a Google Sheet.
Args: user_google_email (str): The user's Google email address. Required. spreadsheet_id (str): The ID of the spreadsheet. Required. range_name (str): The range to read (e.g., "Sheet1!A1:D10", "A1:D10"). Defaults to "A1:Z1000".
Returns: str: The formatted values from the specified range.
Inputs: spreadsheet_id (required), user_google_email (required), range_name. Returns: result
read_spreadsheet_commentsC
Read all comments from a Google Spreadsheet.
Inputs: spreadsheet_id (required), user_google_email (required). Returns: result
reply_to_document_commentC
Reply to a specific comment in a Google Document.
Inputs: comment_id (required), document_id (required), reply_content (required), user_google_email (required). Returns: result
reply_to_presentation_commentC
Reply to a specific comment in a Google Presentation.
Inputs: comment_id (required), presentation_id (required), reply_content (required), user_google_email (required). Returns: result
reply_to_spreadsheet_commentC
Reply to a specific comment in a Google Spreadsheet.
Inputs: comment_id (required), reply_content (required), spreadsheet_id (required), user_google_email (required). Returns: result
resolve_document_commentC
Resolve a comment in a Google Document.
Inputs: comment_id (required), document_id (required), user_google_email (required). Returns: result
resolve_presentation_commentC
Resolve a comment in a Google Presentation.
Inputs: comment_id (required), presentation_id (required), user_google_email (required). Returns: result
resolve_spreadsheet_commentC
Resolve a comment in a Google Spreadsheet.
Inputs: comment_id (required), spreadsheet_id (required), user_google_email (required). Returns: result
search_customA
Performs a search using Google Custom Search JSON API.
Args: user_google_email (str): The user's Google email address. Required. q (str): The search query. Required. num (int): Number of results to return (1-10). Defaults to 10. start (int): The index of the first result to return (1-based). Defaults to 1. safe (Literal["active", "moderate", "off"]): Safe search level. Defaults to "off". search_type (Optional[Literal["image"]]): Search for images if set to "image". site_search (Optional[str]): Restrict search to a specific site/domain. site_search_filter (Optional[Literal["e", "i"]]): Exclude ("e") or include ("i") site_search results. date_restrict (Optional[str]): Restrict results by date (e.g., "d5" for past 5 days, "m3" for past 3 months). file_type (Optional[str]): Filter by file type (e.g., "pdf", "doc"). language (Optional[str]): Language code for results (e.g., "lang_en"). country (Optional[str]): Country code for results (e.g., "countryUS").
Returns: str: Formatted search results including title, link, and snippet for each result.
Inputs: q (required), user_google_email (required), country, date_restrict, +8 more. Returns: result
search_custom_siterestrictA
Performs a search restricted to specific sites using Google Custom Search.
Args: user_google_email (str): The user's Google email address. Required. q (str): The search query. Required. sites (List[str]): List of sites/domains to search within. num (int): Number of results to return (1-10). Defaults to 10. start (int): The index of the first result to return (1-based). Defaults to 1. safe (Literal["active", "moderate", "off"]): Safe search level. Defaults to "off".
Returns: str: Formatted search results from the specified sites.
Inputs: q (required), sites (required), user_google_email (required), num, +2 more. Returns: result
search_docsC
Searches for Google Docs by name using Drive API (mimeType filter).
Returns: str: A formatted list of Google Docs matching the search query.
Inputs: query (required), user_google_email (required), page_size. Returns: result
search_drive_filesA
Searches for files and folders within a user's Google Drive, including shared drives.
Args:
user_google_email (str): The user's Google email address. Required.
query (str): The search query string. Supports Google Drive search operators.
page_size (int): The maximum number of files to return. Defaults to 10.
drive_id (Optional[str]): ID of the shared drive to search. If None, behavior depends on corpora and include_items_from_all_drives.
include_items_from_all_drives (bool): Whether shared drive items should be included in results. Defaults to True. This is effective when not specifying a drive_id.
corpora (Optional[str]): Bodies of items to query (e.g., 'user', 'domain', 'drive', 'allDrives').
If 'drive_id' is specified and 'corpora' is None, it defaults to 'drive'.
Otherwise, Drive API default behavior applies. Prefer 'user' or 'drive' over 'allDrives' for efficiency.
Returns: str: A formatted list of found files/folders with their details (ID, name, type, size, modified time, link).
Inputs: query (required), user_google_email (required), corpora, drive_id, +2 more. Returns: result
search_gmail_messagesA
Searches messages in a user's Gmail account based on a query. Returns both Message IDs and Thread IDs for each found message, along with Gmail web interface links for manual verification.
Args: query (str): The search query. Supports standard Gmail search operators. user_google_email (str): The user's Google email address. Required. page_size (int): The maximum number of messages to return. Defaults to 10.
Returns: str: LLM-friendly structured results with Message IDs, Thread IDs, and clickable Gmail web interface URLs for each found message.
Inputs: query (required), user_google_email (required), page_size. Returns: result
search_messagesC
Searches for messages in Google Chat spaces by text content.
Returns: str: A formatted list of messages matching the search query.
Inputs: query (required), user_google_email (required), page_size, space_id. Returns: result
send_gmail_messageA
Sends an email using the user's Gmail account. Supports both new emails and replies.
Args: to (str): Recipient email address. subject (str): Email subject. body (str): Email body (plain text). cc (Optional[str]): Optional CC email address. bcc (Optional[str]): Optional BCC email address. user_google_email (str): The user's Google email address. Required. thread_id (Optional[str]): Optional Gmail thread ID to reply within. When provided, sends a reply. in_reply_to (Optional[str]): Optional Message-ID of the message being replied to. Used for proper threading. references (Optional[str]): Optional chain of Message-IDs for proper threading. Should include all previous Message-IDs.
Returns: str: Confirmation message with the sent email's message ID.
Examples: # Send a new email send_gmail_message(to="user@example.com", subject="Hello", body="Hi there!")
# Send an email with CC and BCC
send_gmail_message(
to="user@example.com",
cc="manager@example.com",
bcc="archive@example.com",
subject="Project Update",
body="Here's the latest update..."
)
# Send a reply
send_gmail_message(
to="user@example.com",
subject="Re: Meeting tomorrow",
body="Thanks for the update!",
thread_id="thread_123",
in_reply_to="<message123@gmail.com>",
references="<original@gmail.com> <message123@gmail.com>"
)Inputs: body (required), subject (required), to (required), user_google_email (required), +5 more. Returns: result
send_messageC
Sends a message to a Google Chat space.
Returns: str: Confirmation message with sent message details.
Inputs: message_text (required), space_id (required), user_google_email (required), thread_key. Returns: result
set_publish_settingsB
Updates the publish settings of a form.
Args: user_google_email (str): The user's Google email address. Required. form_id (str): The ID of the form to update publish settings for. publish_as_template (bool): Whether to publish as a template. Defaults to False. require_authentication (bool): Whether to require authentication to view/submit. Defaults to False.
Returns: str: Confirmation message of the successful publish settings update.
Inputs: form_id (required), user_google_email (required), publish_as_template, require_authentication. Returns: result
start_google_authA
Manually initiate Google OAuth authentication flow.
NOTE: This tool should typically NOT be called directly. The authentication system automatically handles credential checks and prompts for authentication when needed. Only use this tool if:
You need to re-authenticate with different credentials
You want to proactively authenticate before using other tools
The automatic authentication flow failed and you need to retry
In most cases, simply try calling the Google Workspace tool you need - it will automatically handle authentication if required.
Inputs: service_name (required), user_google_email. Returns: result
update_taskB
Update an existing task.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list containing the task. task_id (str): The ID of the task to update. title (Optional[str]): New title for the task. notes (Optional[str]): New notes/description for the task. status (Optional[str]): New status ("needsAction" or "completed"). due (Optional[str]): New due date in RFC 3339 format.
Returns: str: Confirmation message with updated task details.
Inputs: task_id (required), task_list_id (required), user_google_email (required), due, +3 more. Returns: result
update_task_listC
Update an existing task list.
Args: user_google_email (str): The user's Google email address. Required. task_list_id (str): The ID of the task list to update. title (str): The new title for the task list.
Returns: str: Confirmation message with updated task list details.
Inputs: task_list_id (required), title (required), user_google_email (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 84 tools
Most tools have distinct purposes targeting specific Google Workspace services (Docs, Gmail, Calendar, etc.), with clear boundaries. However, some overlap exists, such as get_doc_content and get_drive_file_content for document retrieval, and multiple comment tools (create_document_comment, read_document_comments, etc.) that could cause confusion if not carefully distinguished by context.
Tool names follow a highly consistent snake_case pattern with clear verb_noun conventions (e.g., create_doc, modify_event, list_calendars). The naming is uniform across all 84 tools, making it predictable and easy to understand the action and target resource for each tool.
With 84 tools, the set is excessively large for a single server, making it overwhelming and difficult for agents to navigate efficiently. While Google Workspace is broad, this count suggests poor scoping, as many tools could be consolidated or split into focused sub-servers (e.g., separate servers for Docs, Gmail, Calendar) to improve usability.
The tool set provides comprehensive coverage across Google Workspace services, including full CRUD operations for Docs, Sheets, Slides, Calendar, Gmail, Drive, Tasks, and Forms. It supports complex workflows (e.g., batch operations, document structure inspection) and integrates auxiliary functions like search and authentication, leaving no obvious gaps for the domain.
Related MCP Connectors
Gmail, Outlook, Drive, OneDrive and calendars for AI agents. Many accounts, one endpoint, audit log.
Multiple Gmail accounts, editable Google Sheets & Docs for AI agents. Deny-by-default access rules.
Use your apps from your AI: Gmail, Slack, Google Sheets, HubSpot and 2,300+ more on your accounts.
Permissioned access to Gmail, Drive and Calendar via the user's own Google account
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceProvides AI assistants with access to Google Workspace APIs including Sheets, Calendar, Gmail, Tasks, Drive, and Docs. Enables full CRUD operations and management of Google services through natural language.1-
- AlicenseNot gradedqualityDmaintenanceEnables natural language control over Google Workspace (Gmail, Drive, Calendar, Sheets, Slides, Tasks) through secure OAuth 2.1 authentication, with vault-level security and multi-user isolation.501 npm7-
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Google Workspace services (Gmail, Drive, Docs, Tasks, Calendar) through OAuth 2.0 authentication, providing 25+ operations for business automation and productivity.1-
- AlicenseBqualityDmaintenanceProvides 240 tools for managing Google Workspace services including Gmail, Drive, Calendar, Sheets, Docs, Slides, Contacts, and Tasks via natural language.100MIT