Skip to main content
Glama
Google Workspace MCP Server

Google Workspace MCP Server

by ZatesloFL

Google Workspace MCP Server

License: MIT Python 3.10+ PyPI PyPI Downloads Website

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 mcpo

  • Task & task list management with hierarchy

  • Programmable Search Engine (PSE) integration


▶ Quick Start

⊠ Credentials

export GOOGLE_OAUTH_CLIENT_ID="..."
export GOOGLE_OAUTH_CLIENT_SECRET="..."

Full setup →

▶ Launch Commands

uvx workspace-mcp --tool-tier core
uv run main.py --tools gmail drive

More options →

★ Tool Tiers

  • ● core - Essential tools

  • ◐ extended - Core + extras

  • ○ complete - Everything Details →

  1. Download: Grab the latest google_workspace_mcp.dxt from the “Releases” page

  2. Install: Double-click the file – Claude Desktop opens and prompts you to Install

  3. Configure: In Claude Desktop → Settings → Extensions → Google Workspace MCP, paste your Google OAuth credentials

  4. 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

GOOGLE_OAUTH_CLIENT_ID

OAuth client ID from Google Cloud

GOOGLE_OAUTH_CLIENT_SECRET

OAuth client secret

OAUTHLIB_INSECURE_TRANSPORT=1

Development only (allows http:// redirect)

Optional

Variable

Purpose

USER_GOOGLE_EMAIL

Default email for single-user auth

GOOGLE_PSE_API_KEY

API key for Custom Search

GOOGLE_PSE_ENGINE_ID

Search Engine ID for Custom Search

MCP_ENABLE_OAUTH21

Set to true for OAuth 2.1 support

WORKSPACE_MCP_STATELESS_MODE

Set to true for stateless operation (requires OAuth 2.1)

Claude Desktop stores these securely in the OS keychain; set them once in the extension pane.



Prerequisites

  • Python 3.10+

  • uvx (for instant installation) or uv (for development)

  • Google Cloud Project with OAuth 2.0 credentials

Configuration

1. Create Project

console.cloud.google.com

→ Create new project
→ Note project name

Open Console →

2. OAuth Credentials

APIs & Services → Credentials
→ Create Credentials
→ OAuth Client ID
→ Desktop Application

Download & save credentials

3. Enable APIs

APIs & Services → Library

Search & enable:
Calendar, Drive, Gmail,
Docs, Sheets, Slides,
Forms, Tasks, Chat, Search

See quick links below

Complete Setup Process:

  1. 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

  2. Enable Required APIs - In APIs & Services → Library

    • Search for and enable each required API

    • Or use the quick links below for one-click enabling

  3. Configure Environment - Set your credentials:

    export GOOGLE_OAUTH_CLIENT_ID="your-client-id"
    export GOOGLE_OAUTH_CLIENT_SECRET="your-secret"

≡ Full Documentation →

1.1. Credentials: See Credential Configuration for detailed setup options

  1. Environment Configuration:

◆ Development Mode

export OAUTHLIB_INSECURE_TRANSPORT=1

Allows HTTP redirect URIs

@ Default User

export USER_GOOGLE_EMAIL=\
  your.email@gmail.com

Single-user authentication

◆ Custom Search

export GOOGLE_PSE_API_KEY=xxx
export GOOGLE_PSE_ENGINE_ID=yyy

Optional: Search API setup

  1. Server Configuration:

◆ Base Configuration

export WORKSPACE_MCP_BASE_URI=
  http://localhost
export WORKSPACE_MCP_PORT=8000

Server URL & port settings

↻ Proxy Support

export MCP_ENABLE_OAUTH21=
  true

Leverage multi-user OAuth2.1 clients

@ Default Email

export USER_GOOGLE_EMAIL=\
  your.email@gmail.com

Skip email in auth flows in single user mode

Variable

Description

Default

WORKSPACE_MCP_BASE_URI

Base server URI (no port)

http://localhost

WORKSPACE_MCP_PORT

Server listening port

8000

WORKSPACE_EXTERNAL_URL

External URL for reverse proxy setups

None

GOOGLE_OAUTH_REDIRECT_URI

Override OAuth callback URL

Auto-constructed

USER_GOOGLE_EMAIL

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)

Open Control Panel →

2. Get API Key

developers.google.com
/custom-search/v1/overview

→ Create/select project
→ Enable Custom Search API
→ Create credentials (API Key)

Get 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:

  1. Create Search Engine - Visit the Control Panel

    • Choose "Search the entire web" or specify sites

    • Copy the Search Engine ID (looks like: 017643444788157684527:6ivsjbpxpqw)

  2. 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)

  3. Configure Environment - Add to your shell or .env:

    export GOOGLE_PSE_API_KEY="AIzaSy..."
    export GOOGLE_PSE_ENGINE_ID="01764344478..."

≡ Full Documentation →

Start the Server

▶ Quick Start

uv run main.py

Default stdio mode

◆ HTTP Mode

uv run main.py \
  --transport streamable-http

Web interfaces & debugging

@ Single User

uv run main.py \
  --single-user

Simplified 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-mcp

Available 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.json

Traditional method

⚡ .env File

cp .env.oauth21 .env
# Edit .env with credentials

Best for development

Loading Priority

  1. Environment variables (export VAR=value)

  2. .env file in project root (warning - if you run via uvx rather than uv run from 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)

  3. client_secret.json via GOOGLE_CLIENT_SECRET_PATH

  4. Default client_secret.json in 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

list_calendars

Core

List accessible calendars

get_events

Core

Retrieve events with time range filtering

create_event

Core

Create events with attachments & reminders

modify_event

Core

Update existing events

delete_event

Extended

Remove events

📁 Google Drive drive_tools.py

Tool

Tier

Description

search_drive_files

Core

Search files with query syntax

get_drive_file_content

Core

Read file content (Office formats)

list_drive_items

Extended

List folder contents

create_drive_file

Core

Create files or fetch from URLs

📧 Gmail gmail_tools.py

Tool

Tier

Description

search_gmail_messages

Core

Search with Gmail operators

get_gmail_message_content

Core

Retrieve message content

get_gmail_messages_content_batch

Core

Batch retrieve message content

send_gmail_message

Core

Send emails

get_gmail_thread_content

Extended

Get full thread content

modify_gmail_message_labels

Extended

Modify message labels

list_gmail_labels

Extended

List available labels

manage_gmail_label

Extended

Create/update/delete labels

draft_gmail_message

Extended

Create drafts

get_gmail_threads_content_batch

Complete

Batch retrieve thread content

batch_modify_gmail_message_labels

Complete

Batch modify labels

start_google_auth

Complete

Initialize authentication

📝 Google Docs docs_tools.py

Tool

Tier

Description

get_doc_content

Core

Extract document text

create_doc

Core

Create new documents

modify_doc_text

Core

Modify document text

search_docs

Extended

Find documents by name

find_and_replace_doc

Extended

Find and replace text

list_docs_in_folder

Extended

List docs in folder

insert_doc_elements

Extended

Add tables, lists, page breaks

insert_doc_image

Complete

Insert images from Drive/URLs

update_doc_headers_footers

Complete

Modify headers and footers

batch_update_doc

Complete

Execute multiple operations

inspect_doc_structure

Complete

Analyze document structure

export_doc_to_pdf

Extended

Export document to PDF

create_table_with_data

Complete

Create data tables

debug_table_structure

Complete

Debug table issues

*_document_comments

Complete

Read, Reply, Create, Resolve

📊 Google Sheets sheets_tools.py

Tool

Tier

Description

read_sheet_values

Core

Read cell ranges

modify_sheet_values

Core

Write/update/clear cells

create_spreadsheet

Core

Create new spreadsheets

list_spreadsheets

Extended

List accessible spreadsheets

get_spreadsheet_info

Extended

Get spreadsheet metadata

create_sheet

Complete

Add sheets to existing files

*_sheet_comment

Complete

Read/create/reply/resolve comments

🖼️ Google Slides slides_tools.py

Tool

Tier

Description

create_presentation

Core

Create new presentations

get_presentation

Core

Retrieve presentation details

batch_update_presentation

Extended

Apply multiple updates

get_page

Extended

Get specific slide information

get_page_thumbnail

Extended

Generate slide thumbnails

*_presentation_comment

Complete

Read/create/reply/resolve comments

📝 Google Forms forms_tools.py

Tool

Tier

Description

create_form

Core

Create new forms

get_form

Core

Retrieve form details & URLs

set_publish_settings

Complete

Configure form settings

get_form_response

Complete

Get individual responses

list_form_responses

Extended

List all responses with pagination

✓ Google Tasks tasks_tools.py

Tool

Tier

Description

list_tasks

Core

List tasks with filtering

get_task

Core

Retrieve task details

create_task

Core

Create tasks with hierarchy

update_task

Core

Modify task properties

delete_task

Extended

Remove tasks

move_task

Complete

Reposition tasks

clear_completed_tasks

Complete

Hide completed tasks

*_task_list

Complete

List/get/create/update/delete task lists

💬 Google Chat chat_tools.py

Tool

Tier

Description

list_spaces

Extended

List chat spaces/rooms

get_messages

Core

Retrieve space messages

send_message

Core

Send messages to spaces

search_messages

Core

Search across chat history

🔍 Google Custom Search search_tools.py

Tool

Tier

Description

search_custom

Core

Perform web searches

get_search_engine_info

Complete

Retrieve search engine metadata

search_custom_siterestrict

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:

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)

  1. Open Claude Desktop Settings → Developer → Edit Config

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

  2. 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 calendar

Note: Configure OAuth credentials before running. Supports environment variables, .env file, or client_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-http

If 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:

  1. 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.

  2. 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/token

  • Add 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-http

Key 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=true

  • Incompatible 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_URL when all OAuth endpoints should use the external URL (recommended for reverse proxy setups)

  • Use GOOGLE_OAUTH_REDIRECT_URI when you only need to override the callback URL

  • The 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-http

Requires 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.py

Development 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:

  1. Server returns authorization URL

  2. Open URL in browser and authorize

  3. Google provides an authorization code

  4. Paste the code when prompted (or it's handled automatically)

  5. 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     # Dependencies

Adding 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 objects

Architecture Highlights

  • Service Caching: 30-minute TTL reduces authentication overhead

  • Scope Management: Centralized in SCOPE_GROUPS for easy maintenance

  • Error 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: CredentialStore base class defines standard operations (get, store, delete, list users)

  • Local File Storage: LocalDirectoryCredentialStore implementation stores credentials as JSON files

  • Configurable Storage: Environment variable GOOGLE_MCP_CREDENTIALS_DIR sets storage location

  • Multi-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.json or the .credentials/ directory to source control!

  • OAuth Callback: Uses http://localhost:8000/oauth2callback for development (requires OAUTHLIB_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 mcpo over networks

  • Scope 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

  1. Create config.json:

{
  "mcpServers": {
    "google_workspace": {
      "type": "streamablehttp",
      "url": "http://localhost:8000/mcp"
    }
  }
}
  1. Start MCPO:

mcpo --port 8001 --config config.json

≡ Configure Open WebUI

  1. Navigate to Settings → Connections → Tools

  2. Click Add Tool and enter:

    • Server URL: http://localhost:8001/google_workspace

    • API Key: Your mcpo --api-key (if set)

  3. Save - Google Workspace tools are now available!


≡ License

MIT License - see LICENSE file for details.


Validations: MCP Badge

Available Tools

84 tools
batch_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:

  1. After creating table → Use this to verify structure

  2. Before populating → Use this to plan your data format

  3. After population fails → Use this to see what went wrong

  4. 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:

  1. You need to re-authenticate with different credentials

  2. You want to proactively authenticate before using other tools

  3. 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_doc_headers_footersC

Updates headers or footers in a Google Doc.

Args: user_google_email: User's Google email address document_id: ID of the document to update section_type: Type of section to update ("header" or "footer") content: Text content for the header/footer header_footer_type: Type of header/footer ("DEFAULT", "FIRST_PAGE_ONLY", "EVEN_PAGE")

Returns: str: Confirmation message with update details

Inputs: content (required), document_id (required), section_type (required), user_google_email (required), +1 more. 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

    B3.3/5.0

    Scored across 84 tools

    Disambiguation4/5

    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.

    Naming Consistency5/5

    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.

    Tool Count2/5

    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.

    Completeness5/5

    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

    Related MCP Servers