MCP Google Workspace Server
Allows sending emails and creating drafts through Gmail.
Allows appending text to existing Google Docs.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Google Workspace ServerSend an email to john@example.com saying the project is complete."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 an email through Gmail on behalf of the authenticated account. |
| Create a Gmail draft without sending it. |
| 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 layer —
src/server.ts,src/tools/*,src/transports/*(tool registration, validation, structured errors, transports).Google service layer —
src/google/gmailService.ts,src/google/docsService.ts,src/lib/mime.ts.Auth / config —
src/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: Generic MCP Server for Google Workspace
Prerequisites
Node.js 18+ and npm.
A Google account (Gmail and/or Google Workspace).
A Google Cloud project.
1. Google Cloud Console setup
Go to the Google Cloud Console and create (or select) a project.
Enable APIs: APIs & Services → Library → enable Gmail API and Google Docs API.
OAuth consent screen: configure it (External is fine for testing). Add your Google account under Test users.
Add the required scopes (least privilege):
https://www.googleapis.com/auth/gmail.sendhttps://www.googleapis.com/auth/gmail.composehttps://www.googleapis.com/auth/documents
Create credentials: APIs & Services → Credentials → Create Credentials → OAuth client ID → Desktop app.
Add an authorized redirect URI that matches
GOOGLE_OAUTH_REDIRECT(defaulthttp://localhost:3000/oauth2callback).Copy the Client ID and Client secret.
2. Install & configure
npm install
cp .env.example .env # then edit .envFill in at least GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. See .env.example for every variable.
Variable | Required | Purpose |
| yes | OAuth client ID |
| yes | OAuth client secret |
| no (default | Where tokens are stored (git-ignored) |
| no (default | Consent-flow redirect URI |
| no | Default From address |
| no (default |
|
| no | HTTP bind address (defaults |
| required for | Bearer token clients must present |
| no |
|
3. Authorize (one time)
npm run authThis 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 devstdio 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 startThe 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.jsTool 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;
.envandtoken.jsonare 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.1by default.
Testing
npm testUnit 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.
Available Tools
3 toolsappend_to_google_docA
Append text content to the end of an existing Google Doc.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Text to append to the end of the document. | |
| document_id | Yes | The Google Doc ID (the value after /document/d/ in the doc URL). | |
| add_newline_before | No | Insert a newline before the content so it starts on a fresh line. Defaults to true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states the essential behavior but does not disclose permissions, error conditions, or side effects. With no annotations, the burden is moderate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, clear sentence with no extraneous information. Efficiently communicates the core functionality.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description is adequate for a simple append operation but lacks details like permissions or error handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the description adds minimal value beyond restating the action. No additional meaning is provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'append' and resource 'Google Doc' with location 'end'. It clearly distinguishes from siblings which are Gmail-related.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for appending to a doc but provides no explicit when-to-use or when-not-to-use guidance, nor mentions alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
draft_gmailA
Create a Gmail draft without sending it.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | CC recipients. | |
| to | Yes | Recipient email addresses. | |
| bcc | No | BCC recipients. | |
| body | Yes | Email body content. | |
| subject | Yes | Email subject line. | |
| reply_to | No | Reply-To header address. | |
| body_type | No | Body format. Defaults to text. | text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses the key behavioral trait: the draft is not sent. However, it does not mention authentication needs, side effects, or return behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence with 7 words, front-loaded, no waste. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no mention of return values or prerequisites. For a simple draft creation tool, the description is adequate but missing return information. Schema parameters fully described.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description does not need to add parameter details. The description adds no additional meaning beyond the schema, which already describes all parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb 'Create' and the resource 'Gmail draft' with the outcome 'without sending it'. It distinguishes from sibling tool 'send_gmail' which sends, and 'append_to_google_doc' which is unrelated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies usage for creating drafts rather than sending, but lacks explicit guidance on when to use this tool versus alternatives like 'send_gmail'. No exclusions or prerequisites mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_gmailB
Send an email through Gmail on behalf of the authenticated account.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | CC recipients. | |
| to | Yes | Recipient email addresses. | |
| bcc | No | BCC recipients. | |
| body | Yes | Email body content. | |
| subject | Yes | Email subject line. | |
| reply_to | No | Reply-To header address. | |
| body_type | No | Body format. Defaults to text. | text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It only mentions 'on behalf of the authenticated account' but omits side effects (email sent irreversibly), permission requirements, rate limits, or quota implications. A sending action needs more behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence is concise but overly terse. Could benefit from breaking into purpose, usage, and behavior while remaining compact. No wasted words, but structure is flat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, and description fails to explain return value (e.g., message ID, status). Given 7 parameters and sending complexity, the description is insufficient. It omits error conditions, attachment handling, or reply-to behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (all 7 parameters have descriptions). Baseline 3 applies. Description adds no extra meaning beyond the schema; it only provides a high-level purpose. No additional syntax, format details, or cross-parameter relationships are given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it sends an email via Gmail on behalf of the authenticated account. The verb 'send' and resource 'email through Gmail' are specific, and it distinguishes well from siblings like 'draft_gmail' which creates drafts, not sending.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like draft_gmail or other methods. The description does not mention prerequisites (e.g., authenticated Gmail account) or cases where draft_gmail might be preferable.
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. Dates show when Glama detected each change.
3 tool updates
v1.0.0- First observed
append_to_google_doc - First observed
draft_gmail - First observed
send_gmail
TDQS
Each tool has a unique purpose: appending to a Google Doc, drafting a Gmail, and sending a Gmail. Drafting and sending are distinct actions, so no overlap.
All tool names follow a consistent verb_noun pattern in snake_case: append_to_google_doc, draft_gmail, send_gmail.
With only 3 tools, the server is too sparse for a Google Workspace domain. It covers only two features (Docs append and Gmail draft/send) but lacks many essential operations.
The server covers only a tiny fraction of Google Workspace capabilities. Missing tools for creating/reading docs, managing labels, searching emails, etc. Significant gaps.
Maintenance
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
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Permissioned access to Gmail, Drive and Calendar via the user's own Google account
MCP server connecting AI agents to 100+ apps (Gmail, Slack, Notion, GitHub) via one-click OAuth.
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Related MCP Servers
- FlicenseBqualityCmaintenanceA generic MCP server that exposes Gmail and Google Docs capabilities as tools for AI agents. Enables sending emails and appending content to Google Docs.2-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to send emails, create drafts in Gmail, and append content to Google Docs via standardized MCP tools.47ISC
- AlicenseNot gradedqualityCmaintenanceExposes standardized tools for AI agents to interact with Google Workspace (Gmail and Google Docs) via the MCP protocol.47ISC
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to send and draft Gmail emails and append content to Google Docs through standardized MCP tools.19MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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