内容
# mcp-gmail-docs-server
通用**模型上下文协议(MCP)**服务器,为任何MCP兼容的客户端(Cursor、Claude Desktop、自定义代理)提供三个工具:
| 工具 | 描述 |
|---|---|
| `send_email` | 通过Gmail发送电子邮件(文本/HTML、抄送/密送、附件、可选线程) |
| `draft_email` | 创建Gmail草稿(与发送相同输入) |
| `append_to_google_doc` | 将纯文本或基本Markdown追加到现有的Google Doc |
认证和配置存在于**服务器环境**,而非调用代理。
---
## 前提条件
- Node.js **18+**
- 具有**桌面**OAuth客户端的Google Cloud项目
- 已启用Gmail API + Google Docs API
---
## 1. Google Cloud设置
1. 打开[Google Cloud Console](https://console.cloud.google.com/)并创建(或选择)一个项目。
2. 启用API:
- [Gmail API](https://console.cloud.google.com/apis/library/gmail.googleapis.com)
- [Google Docs API](https://console.cloud.google.com/apis/library/docs.googleapis.com)
3. 配置**OAuth同意屏幕**(外部对于个人/测试足够)。
- 添加自己作为**测试用户**,在应用处于测试阶段时。
- 服务器使用的范围:
- `https://www.googleapis.com/auth/gmail.compose`
- `https://www.googleapis.com/auth/documents`
4. 创建凭证 → **OAuth客户端ID** → 应用程序类型 **桌面应用程序**。
5. 下载客户端JSON(或将客户端ID/客户端密钥复制到 `.env`)。
---
## 2. 本地安装和环境变量
```bash
npm install
cp .env.example .env
```
编辑 `.env`:
```env
GOOGLE_CLIENT_ID=...你的客户端ID...
GOOGLE_CLIENT_SECRET=...你的客户端密钥...
GOOGLE_TOKEN_STORAGE_PATH=./tokens.json
GOOGLE_REDIRECT_URI=http://localhost:3000/
```
`GOOGLE_REFRESH_TOKEN` 为可选,如果令牌存储在 `tokens.json` 中(推荐)。
---
## 3. 一次性OAuth(创建 `tokens.json`)
```bash
npm run get-refresh-token
```
1. 确保重定向URI(`http://localhost:3000/`)已允许用于您的桌面OAuth客户端(环回是桌面应用程序的标准)。
2. 打开打印的URL,登录并授予访问权限。
3. 令牌写入到 `GOOGLE_TOKEN_STORAGE_PATH`(默认为 `./tokens.json`)。
`tokens.json` 被git忽略 - 永远不要提交它。
---
## 4. 运行服务器
```bash
npm run build
npm start
# 或在开发过程中:
npm run dev
```
服务器通过 **stdio** (stdout是协议;日志输出到stderr)与MCP通信。
### 验证发现(无实时Google调用)
```bash
npm run smoke
```
### 实时集成测试(可选)
```bash
# PowerShell
$env:RUN_INTEGRATION="1"
$env:TEST_EMAIL_TO="you@example.com"
$env:TEST_DOCUMENT_ID="your-doc-id-from-url"
npm run smoke
```
---
## 5. Cursor / Claude Desktop 配置
### Cursor (`mcp.json`)
添加类似的内容:
```json
{
"mcpServers": {
"gmail-docs": {
"command": "node",
"args": ["C:/Users/YOU/path/to/M3- MCP Server/dist/server.js"],
"env": {
"GOOGLE_CLIENT_ID": "your-client-id",
"GOOGLE_CLIENT_SECRET": "your-client-secret",
"GOOGLE_TOKEN_STORAGE_PATH": "C:/Users/YOU/path/to/M3- MCP Server/tokens.json"
}
}
}
}
```
或将 `command` 指向 `npx` + `tsx`,将 `args` 指向 `src/server.ts`,以实现无需构建的工作流。
### Claude Desktop
在Claude的配置文件中,`mcpServers`下采用相同的格式(stdio `command` / `args` / `env`)。
---
## 6. 工具参考
### `send_email`
| 字段 | 类型 | 必需 | 备注 |
|---|---|---|---|
| `to` | 字符串 | 是 | 收件人 |
| `subject` | 字符串 | 是 | 主题 |
| `body` | 字符串 | 是 | 正文 |
| `body_type` | `"text"` \| `"html"` | 否 | 默认 `"text"` |
| `cc` / `bcc` | 字符串 | 否 | 抄送/密送 |
| `attachments` | `{ filename, content_base64, mime_type }[]` | 否 | 最大约20MB |
| `thread_id` | 字符串 | 否 | 回复线程 |
**成功:** `{ status: "sent", message_id, thread_id }`
### `draft_email`
输入与 `send_email` 相同。
**成功:** `{ status: "draft_created", draft_id, message_id }`
### `append_to_google_doc`
| 字段 | 类型 | 必需 | 备注 |
|---|---|---|---|
| `document_id` | 字符串 | 是 | 从文档URL |
| `content` | 字符串 | 是 | 正文 |
| `format` | `"plain"` \| `"markdown"` | 否 | 默认 `"plain"` |
| `add_page_break_before` | 布尔值 | 否 | 默认 `false` |
| `newline_before` | 布尔值 | 否 | 默认 `true` |
Markdown子集:`#`–`###`标题,`**bold**`,`-` / `*` 项目符号(其他标记的最佳努力)。
**成功:** `{ status: "appended", document_id, inserted_at_index, revision_id? }`
### 错误
所有工具失败均返回MCP `isError: true`,包含:
```json
{
"status": "error",
"error_code": "AUTH_FAILED | INVALID_INPUT | NOT_FOUND | RATE_LIMITED | UPSTREAM_ERROR",
"message": "人类可读的描述",
"details": {}
}
```
---
## 7. 安全注意事项
- 永远不要提交 `.env`、`tokens.json` 或 `client_secret_*.json`。
- 信息日志仅包含元数据(收件人数量、主题长度、文档ID) - 不包含电子邮件/文档正文。
- 权限故意限制(`gmail.compose` + `documents`)。
- 优先使用磁盘上的 `tokens.json` 而不是将刷新令牌放在聊天记录或截图中。
- 在完成Google验证之前(如果您超出个人使用范围),请将OAuth应用程序保持在**测试**状态并限制测试用户。
---
## 8. 脚本
| 命令 | 目的 |
|---|---|
| `npm run dev` | 通过 `tsx` 运行服务器(stdio) |
| `npm run build` / `npm start` | 编译并运行 |
| `npm test` | 单元测试(无实时Google调用) |
| `npm run get-refresh-token` | 一次性OAuth → `tokens.json` |
| `npm run smoke` | MCP客户端:`tools/list`(+ 实时工具,如果 `RUN_INTEGRATION=1`) |
---
## 9. 部署
**v1(当前):** 通过Cursor / Claude Desktop(stdio)**本地**运行。这是主要的部署模型。
**远程平台(锁定):** **[Railway](https://railway.app/)** - 在v1.1中Streamable HTTP上线后部署。 将`GOOGLE_*`秘密设置为Railway变量;优先使用`GOOGLE_REFRESH_TOKEN`而不是`tokens.json`,因为Railway的文件系统是短暂的。
**逐步指南:** 见 [`DEPLOYMENT_PLAN.md`](./DEPLOYMENT_PLAN.md)(第A部分本地 · 第B部分Railway)。
---
## 项目文档
- [`problemStatement.md`](./problemStatement.md) - 需求
- [`IMPLEMENTATION_PLAN.md`](./IMPLEMENTATION_PLAN.md) - 阶段、待办事项、部署理由
- [`DEPLOYMENT_PLAN.md`](./DEPLOYMENT_PLAN.md) - 逐步本地 + Railway部署
- [`ACCEPTANCE.md`](./ACCEPTANCE.md) - 实时验收检查清单