Gmail + Google Docs MCP Server

Gmail + Google Docs MCP Server

An MCP server that provides tools for drafting and sending Gmail emails, as well as creating and appending to Google Docs, using OAuth 2.0 authentication.

Category
访问服务器

README

Gmail + Google Docs MCP Server

An MCP server that gives an AI agent tools to:

  • Draft and send Gmail emails
  • Create Google Docs and append content to them

Built with the official @modelcontextprotocol/sdk and Google's googleapis client, using a one-time OAuth 2.0 browser login (no Google Workspace admin setup required — works with a normal personal or Workspace Gmail account).

Tools exposed

Tool Description
gmail_create_draft Creates a draft email (not sent)
gmail_send_email Sends an email immediately
gmail_send_draft Sends a previously created draft by ID
gmail_list_drafts Lists existing drafts
docs_create Creates a new Google Doc, optionally with initial text
docs_append_text Appends text to the end of an existing Google Doc (safe under concurrent edits — see below)
server_metrics Returns per-tool call counts, error rates, and latency for this running server

gmail_create_draft and gmail_send_email also accept an optional attachments array (up to 10 files, 20MB each): { filename, contentBase64, mimeType }.

1. Set up Google Cloud credentials

  1. Go to the Google Cloud Console and create (or select) a project.
  2. Enable these two APIs (APIs & Services > Library):
    • Gmail API
    • Google Docs API
  3. Configure the OAuth consent screen (APIs & Services > OAuth consent screen):
    • User type: "External" is fine for personal use (add yourself as a test user), or "Internal" if using a Workspace account.
  4. Create credentials (APIs & Services > Credentials > Create Credentials > OAuth client ID):
    • Application type: Desktop app (accepts any loopback redirect URI, so GOOGLE_REDIRECT_URI below doesn't need to be pre-registered).
  5. Copy .env.example to .env and fill in GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET from that OAuth client (adjust GOOGLE_REDIRECT_URI too if you want a different local port/path).

2. Install dependencies and build

npm install
npm run build

3. Authorize (one-time)

npm run authorize

This opens your browser to sign in to Google and grant access to Gmail (compose/send) and Docs. After you approve, tokens are saved to the path in GOOGLE_TOKEN_STORAGE_PATH (default tokens.json in the project root). Re-run this if you ever revoke access or delete that file.

.env and the token storage file contain secrets — they're already excluded via .gitignore and should never be committed.

4. Run the server

npm start

By default (MCP_TRANSPORT=stdio) the server communicates over stdio, so normally you won't run it directly — instead point your MCP client (e.g. Cursor) at it. To host it remotely instead (e.g. on Render), see deployment-plan.md and the "Remote (HTTP) hosting" section below.

5. Connect it to Cursor

Add this to your mcp.json (Cursor Settings > MCP, or .cursor/mcp.json in a project):

{
  "mcpServers": {
    "gmail-docs": {
      "command": "node",
      "args": ["C:\\Users\\thriv\\OneDrive\\Documents\\BuildMCP\\dist\\index.js"]
    }
  }
}

Restart Cursor (or reload MCP servers) and the tools above will become available to the agent.

Configuration

Required (see .env.example):

Variable Default Purpose
GOOGLE_CLIENT_ID (required) OAuth client ID from Google Cloud Console
GOOGLE_CLIENT_SECRET (required) OAuth client secret from Google Cloud Console
GOOGLE_REDIRECT_URI http://localhost:3000/oauth2callback Redirect URI used for the one-time npm run authorize flow; npm run authorize listens on whatever host/port/path this specifies
GOOGLE_TOKEN_STORAGE_PATH ./tokens.json Where the access/refresh token is stored (encrypted at rest); relative paths resolve from the project root
MCP_SERVER_NAME google-workspace-mcp-server Name this server reports over MCP
LOG_LEVEL info Structured (JSON) log verbosity written to stderr: trace|debug|info|warn|error|fatal

Remote (HTTP) transport — only relevant when hosting this server remotely instead of running it locally via stdio (see deployment-plan.md):

Variable Default Purpose
MCP_TRANSPORT stdio "stdio" for local Cursor usage, or "http" to bind an HTTP server instead (for remote hosting)
PORT 8080 Port the HTTP transport binds to (0.0.0.0). Render (default 10000) or Railway injects this automatically — don't set it yourself there.
MCP_AUTH_TOKEN (required if MCP_TRANSPORT=http) Shared secret remote clients must send as Authorization: Bearer <token> to /mcp, and ?token=<token> to /authorize. The server refuses to start in http mode without it.

Optional:

Variable Default Purpose
GOOGLE_APPLICATION_CREDENTIALS (unset) Path to a service-account key file. Not yet used — reserved for a future service-account auth mode; see the NOTE comment in src/auth.ts.
ALLOWED_GOOGLE_ACCOUNTS (unset, i.e. any account) Comma-separated email allowlist. Not yet enforced — see the NOTE comment in src/auth.ts for what's needed to wire it up (requires the openid/userinfo.email scopes).
ENABLE_HTML_EMAIL true If false, gmail_create_draft/gmail_send_email reject isHtml: true with an INVALID_INPUT error
ENABLE_DOCS_APPEND true If false, the docs_append_text tool is not registered at all

Additional hardening (kept from the previous .env layout — see .env.example):

Variable Default Purpose
RATE_LIMIT_PER_MINUTE 60 Max calls allowed per tool per rolling 60s window before returning a RATE_LIMITED error
MAX_CONFLICT_RETRIES 3 Retry attempts for docs_append_text when a concurrent edit is detected
MAX_ATTACHMENT_BYTES 20971520 (20MB) Max size per email attachment
TOKEN_ENCRYPTION_KEY (auto-generated) Base64, 32-byte key used to encrypt the token storage file at rest; if unset, a random key is generated once into .token.key

Notes & safety

  • gmail_send_email sends immediately with no human review — if you want a safety net, have the agent use gmail_create_draft and then a human sends it from Gmail (or call gmail_send_draft explicitly).
  • The Gmail scope used is gmail.compose, which allows creating/sending drafts and sending messages, but does not grant read access to the mailbox.
  • The Docs scope used is documents, which allows creating and editing docs but does not touch other Drive files.
  • Access tokens refresh automatically and are persisted back to the token storage file, which is encrypted at rest (AES-256-GCM). Existing plaintext token files are migrated transparently on first read.

Reliability & observability (Phase 5 hardening)

  • Structured errors: every tool failure is normalized to Error [CODE]: message, where CODE is one of INVALID_INPUT, REAUTH_REQUIRED, RATE_LIMITED, UPSTREAM_ERROR, CONFLICT, or INTERNAL_ERROR, plus a retryable hint and a requestId for correlating with logs.
  • Rate limiting: each tool is capped at RATE_LIMIT_PER_MINUTE calls/minute (in-process, sliding window) to protect your Google API quota from a runaway agent loop.
  • Conflict-safe Docs writes: docs_append_text reads the document's current revision and writes with writeControl.requiredRevisionId; if another edit races it, the request is retried with exponential backoff (MAX_CONFLICT_RETRIES attempts) instead of silently overwriting.
  • Structured logs: JSON logs go to stderr (never stdout, which is reserved for the MCP protocol channel) with a requestId per tool call. Only non-sensitive metadata is logged (e.g. recipient counts, string lengths) — email bodies, document text, attachment bytes, and tokens are never written to logs.
  • Metrics: call the server_metrics tool at any time to see call counts, error rates, and average latency per tool for the running process.

Remote (HTTP) hosting

Setting MCP_TRANSPORT=http switches the entrypoint to bind an HTTP server (instead of stdio) exposing:

  • GET /health — unauthenticated; returns 200 { status: "ok" } for platform health checks.
  • POST/GET/DELETE /mcp — the actual MCP endpoint (Streamable HTTP transport), gated by Authorization: Bearer <MCP_AUTH_TOKEN>.
  • GET /authorize — starts the Google consent flow remotely (gated by ?token=<MCP_AUTH_TOKEN> since it's opened in a browser). Needed because a headless remote server has no browser for npm run authorize to open.
  • GET <path from GOOGLE_REDIRECT_URI> — Google's OAuth callback; exchanges the code and persists the token, no restart required.

This mode is stateless: each /mcp request gets its own short-lived MCP server + transport pair (per the SDK's guidance for stateless HTTP hosting), so a single process can serve concurrent requests without cross-talk. The in-memory rate limiter and metrics are still per-process, so run a single instance (see deployment-plan.md, Phase 11).

Full step-by-step Render deployment instructions (persistent Disk for token storage, environment variables, redirect URI updates, CI, etc.) are in deployment-plan.md. render.yaml at the repo root declares the service, disk, and env vars for a one-click Render Blueprint deploy (a railway.json is also kept in the repo if you'd rather deploy to Railway instead).

Project structure

src/
  config.ts       - env-driven settings: OAuth client, token path, server name, scopes, transport, feature toggles, hardening limits
  errors.ts        - AppError type + Google API error -> standardized error code mapping
  logging.ts       - structured pino logger (stderr-only) + per-request correlation IDs
  metrics.ts       - in-memory per-tool call/error/latency counters
  rateLimiter.ts   - per-tool sliding-window rate limiting
  tokenCrypto.ts   - AES-256-GCM encryption at rest for token.json
  auth.ts          - OAuth2 client creation + encrypted token load/save (stdio: eager/fail-fast; HTTP: lazy/non-throwing)
  authorize.ts     - one-time interactive `npm run authorize` script (local/stdio setup)
  gmail.ts         - GmailClient: createDraft, sendEmail (with attachments), sendDraft, listDrafts
  docs.ts          - DocsClient: createDocument, appendText (conflict-safe with retries)
  mcpServer.ts     - createMcpServer(): tool registry + shared logging/rate-limit/error middleware (used by both transports)
  httpServer.ts    - Streamable HTTP transport: /health, /mcp (bearer-token gated), /authorize, OAuth callback
  index.ts         - entrypoint; picks stdio or HTTP transport based on MCP_TRANSPORT

render.yaml        - Render Blueprint (web service, persistent disk, env vars) — see deployment-plan.md
railway.json       - equivalent config for Railway, kept for reference

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选