npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cl0ud95/google-workspace-mcp

v3.1.4

Published

MCP server for Google Workspace (Drive, Sheets, Gmail, Calendar, Tasks) with OAuth and service account auth

Downloads

290

Readme

Google Workspace MCP Server

MCP server providing Google Drive, Sheets, Gmail, Calendar, and Tasks access via googleapis. Supports two auth modes: OAuth (per-user consent via control plane) and Service Account (domain-wide delegation for business clients).

Version

3.1.1 — Service account auth, Google Tasks support, Gmail modify scope, scope-aware error handling.

Architecture

OAuth Mode

flowchart TB
    subgraph CP["Furnace Control Plane"]
        AuthAPI["/internal/google/auth-url<br/>/internal/google/tokens"]
        Onboard["/onboarding/google/callback"]
        DB["client_mcp_configs<br/>(encrypted tokens)"]
        AuthAPI --> DB
        Onboard --> DB
    end

    subgraph Container["Agent Container"]
        MCP["MCP Server (this package)"]
        OAuth2["google-auth-library<br/>OAuth2Client"]
        APIs["googleapis<br/>(Drive/Sheets/Gmail/Calendar/Tasks)"]

        MCP -->|"fetch tokens<br/>request auth URL"| AuthAPI
        MCP --> OAuth2
        MCP --> APIs
        APIs -->|"API calls"| Google["Google Workspace APIs"]
        OAuth2 -->|"refresh token<br/>rotation"| AuthAPI
    end

    User["User Browser"] -->|"consent"| Onboard

    style CP fill:#e1f5fe
    style Container fill:#f3e5f5
    style DB fill:#fff9c4
    style Google fill:#e8f5e9

Service Account Mode

flowchart TB
    subgraph Container["Agent Container"]
        MCP["MCP Server (this package)"]
        JWT["google-auth-library<br/>JWT Client"]
        APIs["googleapis<br/>(Drive/Sheets/Gmail/Calendar/Tasks)"]

        MCP --> JWT
        MCP --> APIs
        APIs -->|"API calls (impersonating user)"| Google["Google Workspace APIs"]
        MCP -->|"scope check (once)"| TokenInfo["Google Tokeninfo API"]
    end

    SA["Service Account JSON<br/>(mounted by hub)"] -->|"key file"| JWT

    style Container fill:#f3e5f5
    style Google fill:#e8f5e9
    style TokenInfo fill:#fff9c4

How It Works — OAuth

  1. Agent calls MCP tool (e.g., drive_list_files)
  2. MCP checks scopes — calls control plane to fetch tokens, verifies the token has the required scopes
  3. Has scopes — refreshes access token if expired, executes API call
  4. Missing scopes — requests auth URL from control plane, returns AUTH_REQUIRED with URL and missing scope info
  5. Agent sends URL to user — user taps, Google shows only new permissions (incremental consent)
  6. Control plane callback — exchanges code, stores tokens encrypted in client_mcp_configs
  7. Agent retries — MCP fetches fresh tokens from control plane, succeeds

How It Works — Service Account

  1. Agent calls MCP tool
  2. First call only — MCP reads service account key, creates JWT client with subject impersonation, authorizes, and verifies granted scopes via Google's tokeninfo endpoint
  3. Subsequent calls — reuses initialized client (no refresh needed, JWT tokens are self-signed)
  4. If scopes are missing — returns clear error naming missing scopes and service account email (admin needs to update delegation)

Environment Variables

Shared

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | GOOGLE_AUTH_MODE | No | oauth | Auth mode: oauth or service_account | | ENCRYPTION_KEY | Yes | — | Shared secret for platform API authentication | | CLIENT_ID | Yes | — | Client identifier (set by hosting platform at runtime) | | AGENT_CONFIG_ID | Yes | — | Agent identifier (set by hosting platform at runtime) | | GOOGLE_ROOT_FOLDER_ID | No | — | Drive folder ID scoping Drive operations | | GOOGLE_SERVICES | No | drive,sheets,gmail,calendar,tasks | Comma-separated enabled services | | GOOGLE_READONLY | No | false | If true, only read tools for Drive/Sheets |

OAuth Mode (required when GOOGLE_AUTH_MODE=oauth)

| Variable | Required | Description | |----------|----------|-------------| | GOOGLE_CLIENT_ID | Yes | OAuth client ID from GCP Console | | GOOGLE_CLIENT_SECRET | Yes | OAuth client secret from GCP Console | | GOOGLE_AUTH_URL | Yes | Platform base URL for token management and auth URL generation |

Service Account Mode (required when GOOGLE_AUTH_MODE=service_account)

| Variable | Required | Description | |----------|----------|-------------| | GOOGLE_SERVICE_ACCOUNT_PATH | Yes | Path to service account JSON key file | | GOOGLE_IMPERSONATE_USER | Yes | Email address to impersonate (domain-wide delegation) |

Scope-Aware Auth

OAuth Mode

Each tool declares required OAuth scopes. Before executing, the MCP verifies the stored token covers those scopes. If not:

{
  "error": "AUTH_REQUIRED",
  "auth_url": "https://accounts.google.com/o/oauth2/v2/auth?...",
  "missing_scopes": ["https://www.googleapis.com/auth/gmail.compose"],
  "current_scopes": ["https://www.googleapis.com/auth/drive"],
  "message": "Google Workspace access required. Missing scopes: ..."
}

Scopes are requested for all configured services upfront (one consent screen). Re-auth is only required if GOOGLE_SERVICES is expanded to include a new service.

Service Account Mode

On first tool call, the MCP verifies granted scopes against requested scopes via Google's tokeninfo endpoint. If the Workspace admin didn't delegate a required scope:

Error: Service account ([email protected]) is missing delegated scopes:
https://www.googleapis.com/auth/gmail.compose. Ask your Workspace admin to grant domain-wide
delegation for these scopes in the Admin Console.

check_google_auth Tool

Proactively check connection status without triggering an error:

Input: { requested_scopes: "drive,sheets" }
Output: {
  "connected": true,
  "current_scopes": ["https://www.googleapis.com/auth/drive", ...],
  "missing_scopes": [],
  "auth_url": null
}

Token Management (OAuth mode only)

  • Fetch: MCP calls GET /internal/google/tokens on first API call
  • Refresh: Uses google-auth-library's OAuth2Client with 60-second proactive buffer
  • Persist: Only persists back to control plane when refresh token rotates (rare)
  • Re-auth: After onboarding, MCP re-fetches from control plane — no container restart needed

Tools (51 total)

Meta

| Tool | Description | |------|-------------| | check_google_auth | Check connection status, missing scopes, get auth URL |

Drive (16 tools)

| Tool | R/W | Description | |------|-----|-------------| | drive_list_files | R | List files in folder (paginated) | | drive_list_folders | R | List only folders in folder | | drive_get_file | R | Get file metadata | | drive_read_file | R | Read text file content (truncates at 1MB) | | drive_download | R | Get download URL for binary files | | drive_search | R | Search files by name in root tree | | drive_tree | R | Get folder tree structure | | drive_create_folder | W | Create folder | | drive_create_file | W | Create text file | | drive_update_file | W | Update file content | | drive_move_file | W | Move file to different folder | | drive_rename_file | W | Rename file/folder | | drive_delete_file | W | Trash file/folder | | drive_share_file | W | Set link sharing (private/anyone/anyone_with_link) | | drive_add_collaborator | W | Add user as collaborator | | drive_remove_collaborator | W | Remove collaborator | | drive_get_permissions | R | Get file permissions and collaborators |

Sheets (12 tools)

| Tool | R/W | Description | |------|-----|-------------| | sheets_list | R | List all spreadsheets in root folder | | sheets_get_info | R | Get spreadsheet metadata and sheets | | sheets_get_sheet | R | Get specific sheet/tab metadata | | sheets_read_cell | R | Read single cell | | sheets_read_range | R | Read range (truncates at 10k rows) | | sheets_read_all | R | Read entire sheet | | sheets_write_cell | W | Write single cell | | sheets_write_range | W | Write 2D array to range | | sheets_append_row | W | Append row to end of sheet | | sheets_clear_range | W | Clear range values | | sheets_create_sheet | W | Create new sheet/tab | | sheets_delete_sheet | W | Delete sheet/tab | | sheets_create_spreadsheet | W | Create new spreadsheet file |

Gmail (7 tools)

| Tool | R/W | Description | |------|-----|-------------| | gmail_search_messages | R | Search messages with query | | gmail_read_message | R | Get full message with decoded body | | gmail_read_thread | R | Get all messages in thread | | gmail_send_message | W | Send email (HTML or plain text) | | gmail_create_draft | W | Create email draft | | gmail_modify_labels | W | Add/remove labels on message | | gmail_list_labels | R | List all labels |

Calendar (8 tools)

| Tool | R/W | Description | |------|-----|-------------| | gcal_list_calendars | R | List all calendars | | gcal_list_events | R | List events in calendar | | gcal_get_event | R | Get single event details | | gcal_create_event | W | Create new event | | gcal_update_event | W | Update existing event | | gcal_delete_event | W | Delete event | | gcal_respond_to_event | W | Accept/decline/tentative response |

Tasks (8 tools)

| Tool | R/W | Description | |------|-----|-------------| | gtasks_list_tasklists | R | List all task lists | | gtasks_get_tasklist | R | Get a specific task list | | gtasks_list_tasks | R | List tasks in a task list (filter by completion/due date) | | gtasks_get_task | R | Get a specific task | | gtasks_create_task | W | Create a new task | | gtasks_update_task | W | Update task (title, notes, status, due date) | | gtasks_delete_task | W | Delete a task | | gtasks_clear_tasks | W | Clear all completed tasks from a list |

Service Filtering

Only register tools the agent needs — saves context tokens:

"GOOGLE_SERVICES": "sheets"               // Only Sheets tools
"GOOGLE_SERVICES": "drive,sheets"         // Drive + Sheets
"GOOGLE_SERVICES": "drive,sheets,gmail"   // Drive + Sheets + Gmail

OAuth Scopes

| Service | Scope URLs | |---------|-----------| | Drive | https://www.googleapis.com/auth/drive | | Sheets | https://www.googleapis.com/auth/spreadsheets | | Gmail | https://www.googleapis.com/auth/gmail.compose, https://www.googleapis.com/auth/gmail.modify | | Calendar | https://www.googleapis.com/auth/calendar | | Tasks | https://www.googleapis.com/auth/tasks |

Installation

npx -y @cl0ud95/google-workspace-mcp

Development

npm install
npm run build      # Compile TypeScript
npm run dev        # Run with tsx
npm run typecheck  # Type check only

License

MIT