Sponsored by Deepsite.site

Google Workspace MCP Server

Created By
taylorwilsdon7 months ago
Comprehensive, highly performant Google Workspace Streamable HTTP & SSE MCP Server with complete coverage for Calendar, Gmail, Docs, Sheets, Slides, Chat & Drive!
Content

Google Workspace MCP Server

License: MIT Python 3.11+ UV

Connect MCP Clients, AI Assistants and more to Google Workspace services through the Model Context Protocol

See it in action:


📑 Table of Contents


🌐 Overview

The Google Workspace MCP Server integrates Google Workspace services (Calendar, Drive, Gmail, and Docs) with AI assistants and other applications using the Model Context Protocol (MCP). This allows AI systems to access and interact with user data from Google Workspace applications securely and efficiently.


✨ Features

  • 🔐 OAuth 2.0 Authentication: Securely connects to Google APIs using user-authorized credentials with automatic token refresh and centralized authentication flow
  • 📅 Google Calendar Integration: Full calendar management - list calendars, fetch events, create/modify/delete events with support for all-day and timed events
  • 📁 Google Drive Integration: Search files, list folder contents, read file content, and create new files. Supports extraction and retrieval of .docx, .xlsx and other Microsoft Office formats natively!
  • 📧 Gmail Integration: Complete email management - search messages, retrieve content, send emails, and create drafts with full support for all query syntax
  • 📄 Google Docs Integration: Search for documents, read document content, list documents in folders, and create new documents right from your chat!
  • 🔄 Multiple Transport Options: Streamable HTTP + SSE fallback
  • 🔌 mcpo Compatibility: Easily expose the server as an OpenAPI endpoint for integration with tools like Open WebUI
  • 🧩 Extensible Design: Simple structure for adding support for more Google Workspace APIs and tools
  • 🔄 Integrated OAuth Callback: Handles the OAuth redirect directly within the server on port 8000
  • ⚡ Thread-Safe Session Management: Robust session handling with thread-safe architecture for improved reliability

🚀 Quick Start

Prerequisites

  • Python 3.11+
  • uv package installer (or pip)
  • Google Cloud Project with OAuth 2.0 credentials enabled for required APIs (Calendar, Drive, Gmail, Docs)

Installation

Manual Installation

# Clone the repository (replace with your fork URL if different)
git clone https://github.com/taylorwilsdon/google_workspace_mcp.git
cd google_workspace_mcp

# Create a virtual environment and install dependencies
uv venv
source .venv/bin/activate  # On Windows use `.venv\Scripts\activate`
uv pip install -e .

Configuration

  1. Create OAuth 2.0 Credentials (web application type) in the Google Cloud Console.
  2. Enable the Google Calendar API, Google Drive API, Gmail API, and Google Docs API for your project.
  3. Download the OAuth client credentials as client_secret.json and place it in the project's root directory.
  4. Add the following redirect URI to your OAuth client configuration in the Google Cloud Console. Note that http://localhost:8000 is the default base URI and port, which can be customized via environment variables (WORKSPACE_MCP_BASE_URI and WORKSPACE_MCP_PORT). If you change these, you must update the redirect URI in the Google Cloud Console accordingly.
    http://localhost:8000/oauth2callback
    
  5. ⚠️ Important: Ensure client_secret.json is added to your .gitignore file and never committed to version control.

Server Configuration

The server's base URL and port can be customized using environment variables:

  • WORKSPACE_MCP_BASE_URI: Sets the base URI for the server (default: http://localhost). This affects the server_url used for Gemini native function calling and the OAUTH_REDIRECT_URI.
  • WORKSPACE_MCP_PORT: Sets the port the server listens on (default: 8000). This affects the server_url, port, and OAUTH_REDIRECT_URI.

Example usage:

export WORKSPACE_MCP_BASE_URI="https://my-custom-domain.com"
export WORKSPACE_MCP_PORT="9000"
uv run main.py

Environment Setup

The server uses HTTP for localhost OAuth callbacks during development. Set this environment variable before running the server:

# Allow HTTP for localhost OAuth callbacks (development only!)
export OAUTHLIB_INSECURE_TRANSPORT=1

Without this, you might encounter an "OAuth 2 MUST utilize HTTPS" error during the authentication flow.

Start the Server

Choose one of the following methods to run the server:

HTTP Server Mode
python main.py
# or using uv
uv run main.py

Runs the server with an HTTP transport layer on port 8000.

Single-User Mode

Multi-user MCP is kind of a mess, so right now now everything runs best as 1:1 mapping between client snd server. That will change as soon as Claude can permform OAuth 2.1 flows, so this MCP was built eith a flag for simplified single-user environments. You can run the server in single-user mode, which bypasses session-to-OAuth mapping and uses any available credentials from the .credentials directory:

python main.py --single-user
# or using uv
uv run main.py --single-user

In single-user mode:

  • The server automatically finds and uses any valid credentials in the .credentials directory
  • No session mapping is required - the server uses the first valid credential file found
  • Useful for development, testing, or single-user deployments
  • Still requires initial OAuth authentication to create credential files

This mode is particularly helpful when you don't need multi-user session management and want simplified credential handling.

Using Docker

You can build and run the server using the provided Dockerfile.

# Build the Docker image
docker build -t google-workspace-mcp .

# Run the Docker container
# The -p flag maps the container port 8000 to the host port 8000
# The -v flag mounts the current directory to /app inside the container
# This is useful for development to pick up code changes without rebuilding
docker run -p 8000:8000 -v $(pwd):/app google-workspace-mcp

The smithery.yaml file is configured to start the server correctly within the Docker container.

Important Ports

The default ports are 8000, but can be changed via the WORKSPACE_MCP_PORT environment variable.

ServiceDefault PortDescription
OAuth Callback8000Handled internally by the server via the /oauth2callback route
HTTP Mode Server8000Default when using HTTP transport

Connecting to the Server

The server supports multiple connection methods:

Claude Desktop:

Can run anywhere and be used via mcp-remote or invoked locally with uv run main.py and using mcp-remote with localhost. Claude Desktop lacks native support for streamable HTTP or SSE.

config.json:

{
  "mcpServers": {
    "Google workspace": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "http://localhost:8000/mcp”
      ]
    }
  }
}
Using mcpo (Recommended for OpenAPI Spec Access) With config.json (for multi-mcp mcpo usage):
  1. Install mcpo: uv pip install mcpo or pip install mcpo
  2. Create a config.json (see Integration with Open WebUI)
  3. Run mcpo pointing to your config: uvx mcpo --config config.json --port 8001
  4. The MCP server API will be available at: http://localhost:8001/google_workspace (or the name defined in config.json)
  5. OpenAPI documentation (Swagger UI) available at: http://localhost:8001/google_workspace/docs

With startup command (for single-mcp mcpo usage):

  1. Install mcpo: uv pip install mcpo or pip install mcpo
  2. Start with uvx mcpo --port 8001 --api-key "top-secret" --server-type "streamablehttp" -- http://localhost:8000/mcp
  3. The MCP server API will be available at: http://localhost:8001/openapi.json (or the name defined in config.json)
  4. OpenAPI documentation (Swagger UI) available at: http://localhost:8001/docs
HTTP Mode
  1. Start the server in HTTP mode (see Start the Server)
  2. Send MCP JSON requests directly to http://localhost:8000
  3. Useful for testing with tools like curl or custom HTTP clients
  4. Can be used to serve Claude Desktop & other MCP clients yet to integrate the new Streamable HTTP transport via mcp-remote:
  5. You can also serve in SSE fallback mode if preferred.

Integration with Open WebUI

To use this server as a tool provider within Open WebUI:

  1. Create mcpo Configuration: Create a file named config.json with the following structure to have mcpo make the streamable HTTP endpoint available as an OpenAPI spec tool.

      {
       "mcpServers": {
           "google_workspace": {
               "type": "streamablehttp",
               "url": "http://localhost:8000/mcp"
           }
       }
    }
    
  2. Start the mcpo Server:

    mcpo --port 8001 --config config.json --api-key "your-optional-secret-key"
    

    This command starts the mcpo proxy, serving your active (assuming port 8000) Google Workspace MCP on port 8001.

  3. Configure Open WebUI:

    • Navigate to your Open WebUI settings
    • Go to "Connections" -> "Tools"
    • Click "Add Tool"
    • Enter the Server URL: http://localhost:8001/google_workspace (matching the mcpo base URL and server name from config.json)
    • If you used an --api-key with mcpo, enter it as the API Key
    • Save the configuration
    • The Google Workspace tools should now be available when interacting with models in Open WebUI

First-time Authentication

When a tool requiring Google API access is called:

  • If user_google_email is provided to the tool and credentials are missing/invalid: The server automatically initiates the OAuth 2.0 flow. An authorization URL will be returned in the MCP response (or printed to the console).
  • If user_google_email is NOT provided and credentials are missing/invalid: The tool will return an error message guiding the LLM to use the centralized start_google_auth tool. The LLM should then call start_google_auth with the user's email and the appropriate service_name (e.g., "Google Calendar", "Google Docs", "Gmail", "Google Drive"). This will also return an authorization URL.

Steps for the User (once an authorization URL is obtained):

  1. Open the provided authorization URL in a web browser.
  2. Log in to the Google account and grant the requested permissions for the specified service.
  3. After authorization, Google will redirect the browser to http://localhost:8000/oauth2callback (or your configured redirect URI).
  4. The MCP server handles this callback, exchanges the authorization code for tokens, and securely stores the credentials.
  5. The LLM can then retry the original request. Subsequent calls for the same user and service should work without re-authentication until the refresh token expires or is revoked.

🧰 Available Tools

Note: The first use of any tool for a specific Google service may trigger the OAuth authentication flow if valid credentials are not already stored and user_google_email is provided to the tool. If authentication is required and user_google_email is not provided to the tool, the LLM should use the centralized start_google_auth tool (defined in core/server.py) with the user's email and the appropriate service_name.

📅 Google Calendar

Source: gcalendar/calendar_tools.py

ToolDescriptionParameters
start_google_auth(Centralized in core/server.py) Initiates the OAuth 2.0 authentication flow for a specific Google account and service. Use this when no valid credentials are available or if a tool fails due to missing authentication and an email was not provided to it.user_google_email (required): The user's Google email address
service_name (required): The Google service name (e.g., "Google Calendar", "Google Docs", "Gmail", "Google Drive")
list_calendarsLists all calendars accessible to the authenticated user.user_google_email (optional): Used if session is not authenticated
mcp_session_id (injected automatically)
get_eventsRetrieves upcoming events from a specified calendar within a time range.calendar_id (optional): Calendar ID (default: primary)
time_min (optional): Start time (RFC3339 or YYYY-MM-DD)
time_max (optional): End time (RFC3339 or YYYY-MM-DD)
max_results (optional): Max number of events (default: 25)
user_google_email (optional)
mcp_session_id (injected automatically)
create_eventCreates a new calendar event. Supports all-day and timed events.summary (required): Event title
start_time (required): Start time (RFC3339 or YYYY-MM-DD)
end_time (required): End time (RFC3339 or YYYY-MM-DD)
calendar_id (optional): Calendar ID (default: primary)
description, location, attendees, timezone (optional)
user_google_email (optional)
mcp_session_id (injected automatically)
modify_eventUpdates an existing event by ID. Only provided fields will be modified.event_id (required): ID of the event to modify
calendar_id (optional): Calendar ID (default: primary)
summary, start_time, end_time, description, location, attendees, timezone (optional)
user_google_email (optional)
mcp_session_id (injected automatically)
delete_eventDeletes an event by ID.event_id (required): ID of the event to delete
calendar_id (optional): Calendar ID (default: primary)
user_google_email (optional)
mcp_session_id (injected automatically)

ℹ️ All Calendar tools support authentication via the current MCP session (mcp_session_id) or fallback to user_google_email. If neither is available and authentication is required, the tool will return an error prompting the LLM to use the centralized start_google_auth tool with the user's email and service_name="Google Calendar".

🕒 Date/Time Parameters: Tools accept both full RFC3339 timestamps (e.g., 2024-05-12T10:00:00Z) and simple dates (e.g., 2024-05-12). The server automatically formats them as needed.

📁 Google Drive

Source: gdrive/drive_tools.py

ToolDescriptionParameters
search_drive_filesSearches for files and folders across the user's Drivequery (required): Search query string (e.g., name contains 'report')
max_results (optional): Maximum number of files to return
get_drive_file_contentRetrieves the content of a specific filefile_id (required): The ID of the file
mime_type (optional): Specify the desired export format
list_drive_itemsLists files and folders within a specific folder or the rootfolder_id (optional): The ID of the folder to list (defaults to root)
max_results (optional): Maximum number of items to return
create_drive_fileCreates a new file in Google Drivename (required): The desired name for the new file
content (required): The text content to write into the file
folder_id (optional): The ID of the parent folder
mime_type (optional): The MIME type of the file (defaults to text/plain)

Query Syntax: For Google Drive search queries, see Drive Search Query Syntax

📧 Gmail

Source: gmail/gmail_tools.py

ToolDescriptionParameters
search_gmail_messagesSearch email messages using standard Gmail search operators (from, subject, etc).query (required): Search string (e.g., "from:foo subject:bar is:unread")
user_google_email (optional)
page_size (optional, default: 10)
mcp_session_id (injected automatically)
get_gmail_message_contentGet subject, sender, and plain text body of an email by message ID.message_id (required)
user_google_email (optional)
mcp_session_id (injected automatically)
send_gmail_messageSend a plain text email using the user's Gmail account.to (required): Recipient email address
subject (required)
body (required)
user_google_email (optional)
mcp_session_id (injected automatically)
draft_gmail_messageCreate a draft email in the user's Gmail account.subject (required): Email subject
body (required): Email body (plain text)
to (optional): Recipient email address
user_google_email (optional)
mcp_session_id (injected automatically)

Query Syntax: For Gmail search queries, see Gmail Search Query Syntax

📝 Google Docs

Source: gdocs/docs_tools.py

💬 Google Chat

Source: gchat/chat_tools.py

ToolDescriptionParameters
list_spacesLists Google Chat spaces (rooms and DMs) accessible to the user.user_google_email (required)
page_size (optional, default: 100)
space_type (optional, default: "all", can be "room" or "dm")
get_messagesRetrieves messages from a specific Google Chat space.user_google_email (required)
space_id (required)
page_size (optional, default: 50)
order_by (optional, default: "createTime desc")
send_messageSends a message to a Google Chat space.user_google_email (required)
space_id (required)
message_text (required)
thread_key (optional): To reply in a thread
search_messagesSearches for messages across Chat spaces by text content.user_google_email (required)
query (required): Text to search for
space_id (optional): If provided, searches only in this space
page_size (optional, default: 25)

ℹ️ All Chat tools require user_google_email for authentication. If authentication fails or is required, the tool will return an error prompting the LLM to use the centralized start_google_auth tool with the user's email and service_name="Google Chat". | Tool | Description | Parameters | |----------------------|-------------------------------------------------------------------------------------|------------| | search_docs | Search for Google Docs by name (using Drive API). | • query (required): Text to search for in Doc names
user_google_email (optional)
page_size (optional, default: 10)
mcp_session_id (injected automatically) | | get_doc_content | Retrieve the plain text content of a Google Doc by its document ID. | • document_id (required)
user_google_email (optional)
mcp_session_id (injected automatically) | | list_docs_in_folder| List all Google Docs inside a given Drive folder (by folder ID, default = root). | • folder_id (optional, default: 'root')
user_google_email (optional)
page_size (optional, default: 100)
mcp_session_id (injected automatically) | | create_doc | Create a new Google Doc, optionally with initial content. | • title (required): Name for the doc
content (optional, default: empty)
user_google_email (optional)
mcp_session_id (injected automatically) |


🛠️ Development

Project Structure

google_workspace_mcp/
├── .venv/             # Virtual environment (created by uv)
├── auth/              # OAuth handling logic (google_auth.py, oauth_manager.py)
├── core/              # Core MCP server logic (server.py)
├── gcalendar/         # Google Calendar tools (calendar_tools.py)
├── gdocs/             # Google Docs tools (docs_tools.py)
├── gdrive/            # Google Drive tools (drive_tools.py)
├── gmail/             # Gmail tools (gmail_tools.py)
├── .gitignore         # Git ignore file
├── client_secret.json # Google OAuth Credentials (DO NOT COMMIT)
├── config.json        # Example mcpo configuration
├── main.py            # Main server entry point (imports tools)
├── mcp_server_debug.log # Log file for debugging
├── pyproject.toml     # Project metadata and dependencies (for uv/pip)
├── README.md          # This file
├── uv.lock            # uv lock file

Port Handling for OAuth

The server cleverly handles the OAuth 2.0 redirect URI (/oauth2callback) without needing a separate web server framework:

  • It utilizes the built-in HTTP server capabilities of the underlying MCP library when run in HTTP mode or via mcpo
  • A custom MCP route is registered specifically for /oauth2callback on port 8000
  • When Google redirects the user back after authorization, the MCP server intercepts the request on this route
  • The auth module extracts the authorization code and completes the token exchange
  • This requires OAUTHLIB_INSECURE_TRANSPORT=1 to be set when running locally, as the callback uses http://localhost

Debugging

Log File

Check mcp_server_debug.log for detailed logs, including authentication steps and API calls. Enable debug logging if needed.

OAuth Issues
  • Verify client_secret.json is correct and present
  • Ensure the correct redirect URI (http://localhost:8000/oauth2callback) is configured in Google Cloud Console
  • Confirm the necessary APIs (Calendar, Drive, Gmail) are enabled in your Google Cloud project
  • Check that OAUTHLIB_INSECURE_TRANSPORT=1 is set in the environment where the server process runs
  • Look for specific error messages during the browser-based OAuth flow
Tool Errors

Check the server logs for tracebacks or error messages returned from the Google APIs.

Adding New Tools

  1. Choose or create the appropriate module (e.g., gdocs/gdocs_tools.py)
  2. Import necessary libraries (Google API client library, etc.)
  3. Define an async function for your tool logic. Use type hints for parameters
  4. Decorate the function with @server.tool("your_tool_name")
  5. Inside the function, get authenticated credentials:
from auth.google_auth import get_credentials, CONFIG_CLIENT_SECRETS_PATH
# ...
credentials = await asyncio.to_thread(
    get_credentials,
    user_google_email=your_user_email_variable, # Optional, can be None if session_id is primary
    required_scopes=YOUR_SPECIFIC_SCOPES_LIST,  # e.g., [CALENDAR_READONLY_SCOPE]
    client_secrets_path=CONFIG_CLIENT_SECRETS_PATH,
    session_id=your_mcp_session_id_variable    # Usually injected via Header
)
if not credentials or not credentials.valid:
    # Handle missing/invalid credentials, possibly by calling start_auth_flow
    # from auth.google_auth (which is what service-specific start_auth tools do)
    pass
  1. Build the Google API service client: service = build('drive', 'v3', credentials=credentials)
  2. Implement the logic to call the Google API
  3. Handle potential errors gracefully
  4. Return the results as a JSON-serializable dictionary or list
  5. Import the tool function in main.py so it gets registered with the server
  6. Define necessary service-specific scope constants in your tool's module
  7. Update pyproject.toml if new dependencies are required

Scope Management: The global SCOPES list in config/google_config.py is used for the initial OAuth consent screen. Individual tools should request the minimal required_scopes they need when calling get_credentials.


🔒 Security Notes

  • client_secret.json: This file contains sensitive credentials. NEVER commit it to version control. Ensure it's listed in your .gitignore file. Store it securely.

  • User Tokens: Authenticated user credentials (refresh tokens) are stored locally in files like credentials-<user_id_hash>.json. Protect these files as they grant access to the user's Google account data. Ensure they are also in .gitignore.

  • OAuth Callback Security: The use of http://localhost for the OAuth callback is standard for installed applications during development but requires OAUTHLIB_INSECURE_TRANSPORT=1. For production deployments outside of localhost, you MUST use HTTPS for the callback URI and configure it accordingly in Google Cloud Console.

  • mcpo Security: If using mcpo to expose the server over the network, consider:

    • Using the --api-key option for basic authentication
    • Running mcpo behind a reverse proxy (like Nginx or Caddy) to handle HTTPS termination, proper logging, and more robust authentication
    • Binding mcpo only to trusted network interfaces if exposing it beyond localhost
  • Scope Management: The server requests specific OAuth scopes (permissions) for Calendar, Drive, and Gmail. Users grant access based on these scopes during the initial authentication. Do not request broader scopes than necessary for the implemented tools.


Screenshots:

image image

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Recommend Servers
TraeBuild with Free GPT-4.1 & Claude 3.7. Fully MCP-Ready.
MCP AdvisorMCP Advisor & Installation - Use the right MCP server for your needs
CursorThe AI Code Editor
Serper MCP ServerA Serper MCP Server
Amap Maps高德地图官方 MCP Server
WindsurfThe new purpose-built IDE to harness magic
Zhipu Web SearchZhipu Web Search MCP Server is a search engine specifically designed for large models. It integrates four search engines, allowing users to flexibly compare and switch between them. Building upon the web crawling and ranking capabilities of traditional search engines, it enhances intent recognition capabilities, returning results more suitable for large model processing (such as webpage titles, URLs, summaries, site names, site icons, etc.). This helps AI applications achieve "dynamic knowledge acquisition" and "precise scenario adaptation" capabilities.
TimeA Model Context Protocol server that provides time and timezone conversion capabilities. This server enables LLMs to get current time information and perform timezone conversions using IANA timezone names, with automatic system timezone detection.
DeepChatYour AI Partner on Desktop
Visual Studio Code - Open Source ("Code - OSS")Visual Studio Code
Howtocook Mcp基于Anduin2017 / HowToCook (程序员在家做饭指南)的mcp server,帮你推荐菜谱、规划膳食,解决“今天吃什么“的世纪难题; Based on Anduin2017/HowToCook (Programmer's Guide to Cooking at Home), MCP Server helps you recommend recipes, plan meals, and solve the century old problem of "what to eat today"
EdgeOne Pages MCPAn MCP service designed for deploying HTML content to EdgeOne Pages and obtaining an accessible public URL.
AiimagemultistyleA Model Context Protocol (MCP) server for image generation and manipulation using fal.ai's Stable Diffusion model.
Context7Context7 MCP Server -- Up-to-date code documentation for LLMs and AI code editors
MiniMax MCPOfficial MiniMax Model Context Protocol (MCP) server that enables interaction with powerful Text to Speech, image generation and video generation APIs.
Playwright McpPlaywright MCP server
BlenderBlenderMCP connects Blender to Claude AI through the Model Context Protocol (MCP), allowing Claude to directly interact with and control Blender. This integration enables prompt assisted 3D modeling, scene creation, and manipulation.
ChatWiseThe second fastest AI chatbot™
Tavily Mcp
Baidu Map百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Jina AI MCP ToolsA Model Context Protocol (MCP) server that integrates with Jina AI Search Foundation APIs.