Skip to main content
Glama
Daminigit

MCP Google Workspace Server

by Daminigit

MCP Google Workspace Server

A production-ready, generic MCP (Model Context Protocol) server that provides AI agents with secure, reusable tools for interacting with Gmail and Google Docs.

Any MCP-compatible AI agent (Claude Desktop, Cursor, Windsurf, etc.) can connect to this server and use Google Workspace capabilities without needing to implement Google API integrations themselves.


Architecture

AI Agent (Claude, Cursor, etc.)
   │
   │  MCP Protocol (stdio)
   ▼
Generic MCP Server
   ├── gmail_create_draft
   ├── gmail_send_email
   └── google_docs_append_content
   │
   ▼
Google APIs (HTTPS)
   ├── Gmail API
   └── Google Docs API

Design priority: Security → Genericity → Simplicity → Extensibility → Reliability

See docs/architecture.md for full architectural details.


Related MCP server: Gmail & Google Docs MCP Server

Available MCP Tools

Tool

Description

Side Effect

gmail_create_draft

Creates an email draft in Gmail

Saved draft only

gmail_send_email

Sends an email via Gmail

Permanent — irreversible

google_docs_append_content

Appends text to end of a Google Doc

Document edit


Prerequisites

  • Node.js 18 or later

  • A Google Cloud project with the following APIs enabled:

  • OAuth 2.0 credentials (see setup below)


Google Cloud Setup

1. Create a Google Cloud Project

  1. Go to the Google Cloud Console

  2. Create a new project or select an existing one

2. Enable Required APIs

Enable the following APIs in your project:

  • Gmail API — for email draft creation and sending

  • Google Docs API — for document content appending

3. Configure OAuth 2.0

  1. Go to APIs & Services → Credentials

  2. Click Create Credentials → OAuth client ID

  3. Select Desktop application as the application type

  4. Add http://localhost:3000/oauth/callback as an authorized redirect URI

  5. Download the credentials JSON and note your Client ID and Client Secret

4. Required OAuth Scopes

Scope

Purpose

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

Create drafts and send email

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

Read and write Google Docs


Installation

# Clone the repository
git clone https://github.com/Daminigit/MCP-server-for-pulse-detector.git
cd MCP-server-for-pulse-detector

# Install dependencies
npm install

# Copy and configure environment variables
cp .env.example .env

Environment Variables

Edit .env with your credentials:

GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=http://localhost:3000/oauth/callback
GOOGLE_TOKEN_STORAGE=.tokens/google-token.json
MCP_SERVER_PORT=3000
MCP_SERVER_HOST=localhost
LOG_LEVEL=info

⚠️ Never commit .env to Git. It is already listed in .gitignore.


Authentication (One-Time Setup)

Before starting the server, you must complete a one-time OAuth flow to authorize the application:

npm run auth

This will:

  1. Print a Google OAuth consent URL

  2. Open it in your browser and grant the requested permissions

  3. Paste the authorization code back into the terminal

  4. Save the tokens to GOOGLE_TOKEN_STORAGE

After this step, the server can authenticate all subsequent API calls automatically, including token refresh.


Running the Server

Development

npm run dev

Production

npm run build
npm start

Connecting an MCP-Compatible AI Agent

Claude Desktop

Add the following to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "google-workspace": {
      "command": "node",
      "args": ["/absolute/path/to/MCP-server-for-pulse-detector/dist/index.js"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id",
        "GOOGLE_CLIENT_SECRET": "your-client-secret",
        "GOOGLE_REDIRECT_URI": "http://localhost:3000/oauth/callback",
        "GOOGLE_TOKEN_STORAGE": "/absolute/path/to/.tokens/google-token.json"
      }
    }
  }
}

Using tsx (Development)

{
  "mcpServers": {
    "google-workspace": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/MCP-server-for-pulse-detector/src/index.ts"]
    }
  }
}

Example Tool Calls

Create an Email Draft

{
  "tool": "gmail_create_draft",
  "arguments": {
    "to": ["recipient@example.com"],
    "subject": "Project Update",
    "body": "Here is the latest update on the project.",
    "cc": ["manager@example.com"]
  }
}

Response:

{
  "success": true,
  "draft_id": "r1234567890",
  "message": "Email draft created successfully."
}

Send an Email

{
  "tool": "gmail_send_email",
  "arguments": {
    "to": ["recipient@example.com"],
    "subject": "Meeting Confirmed",
    "body": "The meeting is confirmed for tomorrow at 10 AM."
  }
}

Append to a Google Doc

{
  "tool": "google_docs_append_content",
  "arguments": {
    "document_id": "1AbCdEfGhIjKlMnOpQrStUvWxYz",
    "content": "This is additional content generated by the AI agent."
  }
}

Testing

# Run all unit tests
npm test

# Run with coverage report
npm run test:coverage

Tests use mocked Google API clients — no real API calls are made during testing.


Security Considerations

  • OAuth tokens are never logged — pino is configured to redact all token fields automatically.

  • Tokens are never sent to the AI agent — they are managed entirely within the service layer.

  • Client credentials are loaded from environment variables only — never hard-coded.

  • The .tokens/ directory is gitignored — tokens are never committed to source control.

  • Least-privilege OAuth scopes — only gmail.compose and documents are requested.

  • Input validation occurs before any API call is made.

  • Error messages are sanitized — no tokens or secrets appear in error payloads.


Troubleshooting

AUTHENTICATION_REQUIRED error

Run npm run auth to complete the OAuth flow and generate tokens.

DOCUMENT_NOT_FOUND error

Ensure the document ID is correct (from the Google Doc URL) and the authenticated Google account has access to the document.

PERMISSION_DENIED error

Check that the required OAuth scopes were granted during the auth flow. Re-run npm run auth and grant all requested permissions.

Token file exists but auth still fails

Delete .tokens/google-token.json and re-run npm run auth to obtain fresh tokens.

TypeScript build errors

npm run lint  # Check for type errors without building

Project Structure

src/
├── server/          # MCP server bootstrap & tool registration
├── tools/
│   ├── gmail/       # gmail_create_draft, gmail_send_email handlers
│   └── google-docs/ # google_docs_append_content handler
├── services/        # Google API clients (Gmail, Docs, Auth)
├── utils/           # Validation, error handling, logging
├── config/          # Environment variable loader
└── scripts/         # OAuth setup script (auth.ts)

tests/               # Unit tests with mocked Google APIs
docs/                # Architecture and problem statement

Available Tools

3 tools
gmail_create_draftA

Creates an email draft in the authenticated user's Gmail account. Use this tool when you want to prepare an email for review before sending. This tool does NOT send the email — the draft is only saved to Gmail Drafts. To send an email, use the gmail_send_email tool instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNoList of CC email addresses (optional).
toYesList of recipient email addresses (required, at least one).
bccNoList of BCC email addresses (optional).
bodyYesThe plain-text email body (required).
subjectYesThe email subject line (required).
html_bodyNoOptional HTML version of the email body. If provided, overrides plain-text body for HTML-capable email clients.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses the critical behavioral trait: the draft is only saved to Gmail Drafts and is not sent. It also scopes the operation to the authenticated user's Gmail account. It doesn't discuss return values or failure modes, but for a simple draft-creation tool this is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences with no wasted words. The first sentence states the core action, the second gives usage context, the third clarifies what it does not do, and the fourth routes to the correct sibling tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter tool with a fully described schema and no output schema, the description covers everything needed for correct invocation: what it does, when to use it, that it does not send, and which sibling to use instead. No essential context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with every parameter documented, including the html_body override behavior. The tool description itself adds no additional parameter-level meaning, but the schema already handles this fully, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb-resource pair: 'Creates an email draft in the authenticated user's Gmail account.' It further distinguishes itself from gmail_send_email by explicitly stating that it does NOT send the email and only saves the draft to Gmail Drafts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage context: 'Use this tool when you want to prepare an email for review before sending.' It also states a clear exclusion ('This tool does NOT send the email') and names the correct alternative: 'To send an email, use the gmail_send_email tool instead.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gmail_send_emailA

Sends an email immediately via the authenticated Gmail account. Use this tool only when the user has explicitly confirmed they want to send the email. WARNING: This action is PERMANENT — the email will be delivered immediately and cannot be recalled. To create a draft for review instead, use gmail_create_draft.

ParametersJSON Schema
NameRequiredDescriptionDefault
ccNoList of CC email addresses (optional).
toYesList of recipient email addresses (required, at least one).
bccNoList of BCC email addresses (optional).
bodyYesThe plain-text email body (required).
subjectYesThe email subject line (required).
html_bodyNoOptional HTML version of the email body.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description must carry behavioral disclosure. It clearly warns that the action is immediate, irreversible, and cannot be recalled, plus it emphasizes user confirmation. It could go further (e.g., failure handling, rate limits), but for a send action the key permanence trait is clearly disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four concise sentences, each with a distinct purpose (action, precondition, warning, alternative). No fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a side-effecting mutation with no annotations, the description covers the critical context: user confirmation, permanence, and relationship to gmail_create_draft. It doesn't describe return values or error behavior, but those are less critical for a send action and the schema covers parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, all parameters have descriptions. The description does not add additional parameter semantics but relies on the schema, which is acceptable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Sends') with a clear resource ('email via the authenticated Gmail account'). It also distinguishes itself from the sibling tool gmail_create_draft by explicitly directing agents to that alternative for drafts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit guidance: use only after the user has explicitly confirmed sending, and use gmail_create_draft for draft review instead. This clearly states when and when not to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

google_docs_append_contentA

Appends plain text content to the end of an existing Google Document. Use this tool to add new content at the bottom of a Google Doc without modifying existing content. The document ID can be found in the Google Doc URL: docs.google.com/document/d//edit Existing document content is never overwritten or deleted.

ParametersJSON Schema
NameRequiredDescriptionDefault
contentYesThe plain text content to append at the end of the document (required).
document_idYesThe Google Document ID from the document URL (required). Example: "1AbCdEfGhIjKlMnOpQrStUvWxYz"

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden. It prominently states that existing content is never overwritten or deleted and that only plain text is appended, which are the key behavioral guarantees an agent needs. It does not cover failure modes or permissions, but the main non-destructive trait is well disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded with the core action. There is minor redundancy between 'without modifying existing content' and 'never overwritten or deleted,' but overall every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter append operation with no output schema, the description covers the core semantics, the non-destructive behavior, and how to locate the required document ID. It could mention access requirements or behavior on nonexistent documents, but the essential information for correct use is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents both parameters. The description adds a helpful hint about finding the document ID in the URL, but that information is also implied by the schema example, so it provides only marginal added value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action: appending plain text to the end of an existing Google Document. It makes the scope obvious and is easily distinguishable from the unrelated gmail sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use the tool ('add new content at the bottom of a Google Doc') and clarifies that existing content is preserved. It does not name alternatives, but the siblings are unrelated to Docs, so no exclusion is necessary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv1.0.0
    • First observedgmail_create_draft
    • First observedgmail_send_email
    • First observedgoogle_docs_append_content

TDQS

A4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct action and resource: Gmail draft creation, Gmail sending, and Docs appending. The draft/send distinction is explicitly explained in both descriptions, so there is no real ambiguity.

Naming Consistency5/5

All tool names follow a consistent snake_case service_verb_noun pattern: gmail_create_draft, gmail_send_email, google_docs_append_content. The naming makes the target service and action predictable.

Tool Count3/5

Three tools is on the thin side for a server claiming to cover Google Workspace. The scope is limited to outbound Gmail actions and one Docs mutation, which feels under-scoped for the stated domain.

Completeness1/5

The tool surface is severely incomplete for Google Workspace: there is no way to read or search Gmail, create or update Google Docs, or access Calendar, Drive, Sheets, or other core Workspace services. It only supports writing outbound email and appending to existing docs, leaving agents unable to perform basic lifecycle operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers