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: 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
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.
Maintenance
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
- 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