Skip to main content
Glama
sunreddy1593-tech

MCP Google Workspace Server

MCP Google Workspace Server

A Model Context Protocol (MCP) server that exposes Gmail and Google Docs capabilities as tools any MCP-compliant agent (Claude Desktop, Cursor, custom agents, etc.) can call.

It provides three tools:

Tool

Description

send_gmail

Send an email through Gmail on behalf of the authenticated account.

draft_gmail

Create a Gmail draft without sending it.

append_to_google_doc

Append text to the end of an existing Google Doc (never overwrites).

Both stdio and streamable HTTP transports are supported.


Architecture

The codebase is modular so each layer is independently testable:

  • MCP layersrc/server.ts, src/tools/*, src/transports/* (tool registration, validation, structured errors, transports).

  • Google service layersrc/google/gmailService.ts, src/google/docsService.ts, src/lib/mime.ts.

  • Auth / configsrc/auth/*, src/config.ts.

send_gmail / draft_gmail / append_to_google_doc
        │  (zod-validated input, JSON-Schema advertised)
        ▼
   MCP server (stdio | streamable HTTP)
        ▼
 Gmail / Docs services  ──►  Google APIs
        ▲
   OAuth2 client (auto-refresh)

Related MCP server: Google Docs + Gmail MCP Server

Prerequisites

  • Node.js 18+ and npm.

  • A Google account (Gmail and/or Google Workspace).

  • A Google Cloud project.


1. Google Cloud Console setup

  1. Go to the Google Cloud Console and create (or select) a project.

  2. Enable APIs: APIs & Services → Library → enable Gmail API and Google Docs API.

  3. OAuth consent screen: configure it (External is fine for testing). Add your Google account under Test users.

  4. Add the required scopes (least privilege):

    • https://www.googleapis.com/auth/gmail.send

    • https://www.googleapis.com/auth/gmail.compose

    • https://www.googleapis.com/auth/documents

  5. Create credentials: APIs & Services → Credentials → Create Credentials → OAuth client ID → Desktop app.

  6. Add an authorized redirect URI that matches GOOGLE_OAUTH_REDIRECT (default http://localhost:3000/oauth2callback).

  7. Copy the Client ID and Client secret.


2. Install & configure

npm install
cp .env.example .env   # then edit .env

Fill in at least GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. See .env.example for every variable.

Variable

Required

Purpose

GOOGLE_CLIENT_ID

yes

OAuth client ID

GOOGLE_CLIENT_SECRET

yes

OAuth client secret

GOOGLE_TOKEN_PATH

no (default ./token.json)

Where tokens are stored (git-ignored)

GOOGLE_OAUTH_REDIRECT

no (default http://localhost:3000/oauth2callback)

Consent-flow redirect URI

DEFAULT_SEND_AS

no

Default From address

MCP_TRANSPORT

no (default stdio)

stdio or http

MCP_HTTP_HOST / MCP_HTTP_PORT

no

HTTP bind address (defaults 127.0.0.1:3333)

MCP_HTTP_AUTH_TOKEN

required for http

Bearer token clients must present

LOG_LEVEL

no

debug/info/warn/error


3. Authorize (one time)

npm run auth

This opens the Google consent screen, captures the redirect, and stores a refresh token at GOOGLE_TOKEN_PATH. Tokens are refreshed transparently afterward. Re-run it if you change scopes or revoke access.


4. Build & run

npm run build      # compile TypeScript to dist/
npm start          # run the compiled server (uses MCP_TRANSPORT)
# or during development:
npm run dev

stdio transport (local/desktop agents)

Set MCP_TRANSPORT=stdio (default). The server communicates over stdin/stdout; all logs go to stderr.

streamable HTTP transport (remote agents)

MCP_TRANSPORT=http MCP_HTTP_AUTH_TOKEN=$(openssl rand -hex 32) npm start

The endpoint is http://<host>:<port>/mcp. Every request must include Authorization: Bearer <MCP_HTTP_AUTH_TOKEN>.


5. Connect an MCP client

See mcp-client-config.example.json. Example for a stdio client:

{
  "mcpServers": {
    "google-workspace": {
      "command": "node",
      "args": ["/absolute/path/to/dist/index.js"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id.apps.googleusercontent.com",
        "GOOGLE_CLIENT_SECRET": "your-client-secret",
        "GOOGLE_TOKEN_PATH": "/absolute/path/to/token.json",
        "MCP_TRANSPORT": "stdio"
      }
    }
  }
}

You can also inspect the server with the MCP Inspector:

npx @modelcontextprotocol/inspector node dist/index.js

Tool reference

send_gmail

Input: to: string[] (req), subject: string (req), body: string (req), body_type: "text"|"html" (default text), cc?: string[], bcc?: string[], reply_to?: string. Output: { "message_id": string, "thread_id": string, "status": "sent" }

draft_gmail

Input: same as send_gmail. Output: { "draft_id": string, "message_id": string, "status": "drafted" }

append_to_google_doc

Input: document_id: string (req; a raw ID or a full docs URL), content: string (req), add_newline_before: boolean (default true). Output: { "document_id": string, "status": "appended" }


Authentication model & tradeoffs

This server uses OAuth2 user-delegated auth (Approach 1 in the problem statement):

  • Each user authorizes once via the standard consent flow; the server stores and auto-refreshes the refresh token.

  • Works for any Gmail/Workspace account with no admin setup — the best fit for an agent-agnostic server that may act for arbitrary users.

Alternative — service account with domain-wide delegation (not used here):

  • Suited to a single Workspace domain.

  • A plain service account cannot send Gmail as arbitrary users; it needs domain-wide delegation configured by a Workspace admin. For Docs, the target document must be shared with the service account's email.

To switch to a service account, replace getAuthorizedClient in src/auth/googleAuth.ts with a JWT client using domain-wide delegation (subject = impersonated user); the rest of the code is unchanged.


Error handling

Tools never crash the connection; they return structured MCP tool errors (isError: true with a machine-readable error.code). Codes include: INVALID_INPUT, DOCUMENT_NOT_FOUND, INSUFFICIENT_SCOPE, CREDENTIALS_MISSING, RATE_LIMITED, NETWORK_ERROR, GOOGLE_API_ERROR. Inputs are validated against the schema before any Google API call.


Security

  • Least-privilege scopes only.

  • Secrets loaded from env; .env and token.json are git-ignored. Never hard-coded.

  • The logger redacts recipients and never logs email bodies or document contents.

  • Email addresses and document IDs are validated/sanitized; MIME header injection is prevented.

  • The HTTP transport requires a bearer token and binds to 127.0.0.1 by default.


Testing

npm test

Unit tests mock the Google layer and cover each tool's success and error branches, MIME construction, and the Google→MCP error mapping.


Future extensions

Rich-text Docs formatting, email attachments/inline images, Gmail read/reply, and new tools (create Doc, insert at index, Sheets/Calendar) can be added as new modules under src/tools/ and src/google/ without changing existing tool contracts.

Install Server
A
license - permissive license
B
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sunreddy1593-tech/MCP-1'

If you have feedback or need assistance with the MCP directory API, please join our Discord server