piotr-agier/google-drive-mcp
GitHub: piotr-agier/google-drive-mcp
这是一个模型上下文协议服务器,提供与Google Drive的标准化集成,让AI客户端能安全管理和操作云文件。
Stars: 154 | Forks: 83
# Google Drive MCP 服务器
一个模型上下文协议(MCP)服务器,为 Google Drive、Docs、Sheets、Slides 和 Calendar 提供安全集成。它允许 Claude Desktop 和其他 MCP 客户端通过标准化接口管理 Google Drive 中的文件和日历事件。
## 功能特性
- **多格式支持**:支持 Google Docs、Sheets、Slides、Calendar 和常规文件
- **文件管理**:创建、更新、删除、重命名、移动、复制、上传和下载文件和文件夹
- **高级搜索**:在整个 Google Drive 中进行搜索
- **共享云端硬盘支持**:除“我的云端硬盘”外,还可完全访问 Google 共享云端硬盘(原 Team Drives)
- **文件夹导航**:列出并浏览文件夹层级结构,支持路径格式(例如 `/Work/Projects`)
- **Google Docs 编辑**:精确的文本插入/删除、表格管理、图片嵌入、批注和丰富的格式设置
- **Google Calendar**:完整的日历管理 — 列出日历、创建/更新/删除事件、Google Meet 集成
- **MCP 资源协议**:文件可作为 MCP 资源访问以读取内容
- **安全认证**:OAuth 2.0,支持自动令牌刷新
## 示例用法
此 MCP 服务器通过自然语言实现强大的文件管理工作流:
### 1. **文档创建与组织**
```
Create a new Google Doc called "Project Plan" in the folder /Work/Projects
with an outline for our Q1 initiatives including milestones and deliverables.
```
### 2. **文件搜索与整理**
```
Search for files containing "budget" and organize them by moving each one
to the appropriate folder in your Drive hierarchy.
```
### 3. **电子表格创建**
```
Create a Google Sheet called "Sales Analysis 2024" with columns for Date, Product,
Quantity, and Revenue to track your sales data.
```
### 4. **演示文稿创建**
```
Create a presentation called "Product Roadmap" with slides outlining
our Q1 milestones, key features, and timeline.
```
### 5. **电子表格更新**
```
Update the "Team Contacts" spreadsheet with new employee information
by modifying specific cells or ranges with the provided data.
```
### 6. **文档搜索**
```
Search for documents in the /Reports folder and create a summary
document listing the files you found.
```
### 7. **文件夹和文档创建**
```
Create a Templates folder and add standard documents like
a Meeting Notes template, Project Proposal template,
and Budget Spreadsheet template.
```
## 要求
- **Node.js**:版本 18 或更高(建议使用 LTS)
- **Google Cloud 项目**:需要启用以下 API:
- Google Drive API
- Google Docs API
- Google Sheets API
- Google Slides API
- Google Calendar API
- **OAuth 2.0 凭据**:桌面应用类型(仅需客户端 ID — 不需要客户端密钥)
## Google Cloud 设置
### 1. 创建 Google Cloud 项目
- 前往 [Google Cloud Console](https://console.cloud.google.com)
- 点击“选择项目” > “新建项目”
- 为项目命名(例如 "Google Drive MCP")
- 记下项目 ID 以备后用
### 2. 启用所需 API
- 在你的项目中,前往“API 和服务” > “程序库”
- 搜索并启用以下每个 API:
- **Google Drive API**
- **Google Docs API**
- **Google Sheets API**
- **Google Slides API**
- **Google Calendar API**
- 等待每个 API 启用后再继续
### 3. 配置 OAuth 同意屏幕
- 前往“API 和服务” > “OAuth 同意屏幕”
- 在“品牌信息”下填写必填字段:
- 应用名称:“My Personal Google Drive MCP”
- 用户支持电子邮件:你的电子邮件
- 开发者联系信息:你的电子邮件
- 在“目标对象”下:
- 选择“外部”(默认选项)或“内部”(适用于 Google Workspace 账户)
- 将你的电子邮件添加为测试用户
- 在“数据访问权限”下添加作用域。为获得最佳用户体验,建议的作用域集如下:
- `./auth/drive.file`
- `.../auth/documents`
- `.../auth/spreadsheets`
- `.../auth/presentations`
- `.../auth/drive`
- `.../auth/drive.readonly`
- `.../auth/calendar`
- `.../auth/calendar.events`
### 4. 创建 OAuth 2.0 凭据
- 前往“API 和服务” > “凭据”
- 点击“+ 创建凭据” > “OAuth 客户端 ID”
- 应用类型:**桌面应用**(重要!)
- 名称:“Google Drive MCP Client”
- 点击“创建”
- 下载 JSON 文件
- 将其重命名为 `gcp-oauth.keys.json`
## 安装
### 选项 1:使用 npx 运行(推荐)
你可以直接运行服务器,无需安装:
```
# 运行服务器(首次运行时会自动进行身份验证)
npx @piotr-agier/google-drive-mcp
# 可选:如需手动进行身份验证
npx @piotr-agier/google-drive-mcp auth
```
### 选项 2:本地安装
1. 克隆并安装:
git clone https://github.com/piotr-agier/google-drive-mcp.git
cd google-drive-mcp
npm install
2. 设置凭据:
# 复制示例文件
cp gcp-oauth.keys.example.json gcp-oauth.keys.json
# 编辑 gcp-oauth.keys.json,填入你的 OAuth 客户端 ID
3. 认证(可选):
npm run auth
注意:如果跳过此步骤,MCP 客户端首次运行时会自动进行认证。
## Docker 使用
### 前提条件
1. **先在本地进行认证** - Docker 容器无法为 OAuth 打开浏览器:
# 使用 npx
npx @piotr-agier/google-drive-mcp auth
# 或使用本地安装
npm run auth
2. **验证令牌位置**:
ls -la ~/.config/google-drive-mcp/tokens.json
### 构建 Docker 镜像
1. **构建项目**(Docker 构建前必须执行):
npm install
npm run build
2. **构建 Docker 镜像**:
docker build -t google-drive-mcp .
### 运行 Docker 容器
`scripts/docker-mcp.sh` 封装脚本管理容器的生命周期 — 它会自动创建、重用和替换容器。MCP 客户端直接调用此脚本(参见下方配置)。
重新构建后,要验证镜像是否正常工作:
```
docker run --rm google-drive-mcp --help
```
### Claude Desktop 的 Docker 配置
#### 选项 A:可重用容器(推荐)
使用封装脚本保持一个命名容器运行,并在客户端重启时重用它 — 启动更快,无容器碎片:
```
{
"mcpServers": {
"google-drive": {
"command": "/path/to/google-drive-mcp/scripts/docker-mcp.sh",
"env": {
"GOOGLE_DRIVE_OAUTH_CREDENTIALS": "$HOME/gcp-oauth.keys.json",
"GOOGLE_DRIVE_MCP_TOKEN_PATH": "$HOME/.config/google-drive-mcp/tokens.json"
}
}
}
}
```
该脚本会:
- 在首次运行时创建容器
- 在后续运行中重用现有容器
- 如果容器已停止则自动重启
- 在镜像重新构建后替换容器
**注意:** 容器会在后台持续运行,直到被显式停止。
要停止它:`docker stop google-drive-mcp`
#### 选项 B:每次启动新容器
在每次客户端重启时创建并移除新容器:
```
{
"mcpServers": {
"google-drive": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-v",
"/path/to/gcp-oauth.keys.json:/config/gcp-oauth.keys.json:ro",
"-v",
"/Users/yourname/.config/google-drive-mcp/tokens.json:/config/tokens.json",
"google-drive-mcp"
]
}
}
}
```
**Docker 特定注意事项:**
- 使用 `-i` 进入交互模式(MCP stdio 通信所需)
- 使用 `--rm` 在退出后自动移除容器
- 无需端口映射(MCP 使用 stdio,而非 HTTP)
- 环境变量在 Dockerfile 中设置
## 配置
### OAuth 凭据配置
服务器支持多种方式提供 OAuth 凭据(按优先级排序):
#### 1. **环境变量**(最高优先级)
```
export GOOGLE_DRIVE_OAUTH_CREDENTIALS="/path/to/your/gcp-oauth.keys.json"
```
#### 2. **配置目录**(推荐)
将 `gcp-oauth.keys.json` 放在 XDG 配置目录下:
```
~/.config/google-drive-mcp/gcp-oauth.keys.json
```
这是推荐的位置 — 在 `npx`、全局安装和本地设置中都能可靠工作。
#### 3. **项目根目录**(旧版备用)
将 `gcp-oauth.keys.json` 放在项目根目录。这在本地开发时仍然有效,但在 `npx` 或全局安装中不可靠。
### OAuth 作用域配置
默认情况下,服务器请求用于 Drive/Docs/Sheets/Slides/Calendar 的宽泛作用域集。
你可以用以下方式覆盖请求的作用域:
```
export GOOGLE_DRIVE_MCP_SCOPES="drive.readonly,documents,spreadsheets"
```
注意:
- 逗号分隔的列表。
- 值可以是完整的作用域 URL 或短别名:
`drive`, `drive.file`, `drive.readonly`, `documents`, `spreadsheets`, `presentations`, `calendar`, `calendar.events`.
- 更改作用域通常需要重新认证。
### 认证服务器端口配置
在 OAuth 认证期间,会启动一个本地 HTTP 服务器来接收回调。默认尝试端口 3000-3004。如果这些端口与其他服务冲突(例如开发服务器),你可以更改起始端口:
```
export GOOGLE_DRIVE_MCP_AUTH_PORT=3100
```
服务器将从配置的值开始尝试 5 个连续端口(例如 3100-3104)。
回调服务器绑定到环回接口,OAuth 重定向 URI 使用环回 IP — `http://127.0.0.1:/oauth2callback`(默认范围 `127.0.0.1:3000`–`127.0.0.1:3004`)。**桌面应用** OAuth 客户端(推荐类型 — 参见[创建 OAuth 2.0 凭据](#4-create-oauth-20-credentials))会自动接受任何环回重定向,无需任何操作。如果你改用 **Web 应用** OAuth 客户端,则必须在 Google Cloud Console 中为范围内的每个端口注册 `http://127.0.0.1:/oauth2callback` 作为授权的重定向 URI,否则认证会因 `redirect_uri_mismatch` 而失败。
### 令牌存储
认证令牌按照 XDG Base Directory 规范安全存储:
| 优先级 | 位置 | 配置 |
|--------|------|------|
| 1 | 自定义路径 | 设置 `GOOGLE_DRIVE_MCP_TOKEN_PATH` 环境变量 |
| 2 | XDG 配置 | `$XDG_CONFIG_HOME/google-drive-mcp/tokens.json` |
| 3 | 默认 | `~/.config/google-drive-mcp/tokens.json` |
**安全注意事项:**
- 令牌创建时具有安全权限(0600)
- 切勿将令牌提交到版本控制
- 令牌在过期前自动刷新
- 处于“测试”状态的 Google OAuth 应用程序的刷新令牌会在 7 天后过期(Google 的策略)
## 运行时配置(CLI 参数或环境变量)
通过 CLI 标志(首选)或环境变量配置超时和重试行为。
CLI 标志优先于环境变量。
### CLI 标志
| 标志 | 默认值 | 描述 |
|------|--------|------|
| `--api-timeout=` | 120000 | 重试封装调用的每次尝试超时;`0` 禁用超时 |
| `--retry-max=` | 3 | 可重试错误(429/503/504、超时、网络)的最大重试次数;`0` 禁用重试 |
| `--retry-base-delay=` | 1000 | 指数退避的基准延迟(上限为 30 秒,带抖动) |
### 环境变量(备用)
- `GOOGLE_DRIVE_MCP_API_TIMEOUT`
- `GOOGLE_DRIVE_MCP_RETRY_MAX`
- `GOOGLE_DRIVE_MCP_RETRY_BASE_DELAY`
### 示例(Claude Desktop 配置)
```
{
"mcpServers": {
"google-drive": {
"command": "npx",
"args": ["@piotr-agier/google-drive-mcp", "--api-timeout=180000", "--retry-max=5"]
}
}
}
```
## 配合 Claude Desktop 使用
将服务器添加到你的 Claude Desktop 配置中:
**macOS**:`~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**:`%APPDATA%\Claude\claude_desktop_config.json`
### 使用 npx(推荐):
```
{
"mcpServers": {
"google-drive": {
"command": "npx",
"args": ["@piotr-agier/google-drive-mcp"],
"env": {
"GOOGLE_DRIVE_OAUTH_CREDENTIALS": "/path/to/your/gcp-oauth.keys.json"
}
}
}
}
```
### 使用本地安装:
```
{
"mcpServers": {
"google-drive": {
"command": "node",
"args": ["/absolute/path/to/google-drive-mcp/dist/index.js"],
"env": {
"GOOGLE_DRIVE_OAUTH_CREDENTIALS": "/path/to/your/gcp-oauth.keys.json"
}
}
}
}
```
**注意**:将 `/path/to/your/gcp-oauth.keys.json` 替换为你的 OAuth 凭据文件的实际路径。
## 可流式传输的 HTTP 传输
默认情况下,服务器使用 stdio 传输(适用于本地 MCP 客户端,如 Claude Desktop)。你也可以使用可流式传输的 HTTP 传输将其作为 HTTP 服务器运行,这可以实现远程/托管部署和共享网关。
### 以 HTTP 模式启动
```
google-drive-mcp start --transport http --port 3100 --host 127.0.0.1
```
或使用环境变量:
```
MCP_TRANSPORT=http MCP_HTTP_PORT=3100 MCP_HTTP_HOST=127.0.0.1 google-drive-mcp start
```
CLI 标志优先于环境变量。
| CLI 标志 | 环境变量 | 默认值 | 描述 |
|----------|----------|--------|------|
| `--transport` | `MCP_TRANSPORT` | `stdio` | `stdio` 或 `http` |
| `--port` | `MCP_HTTP_PORT` | `3100` | HTTP 监听端口 |
| `--host` | `MCP_HTTP_HOST` | `127.0.0.1` | HTTP 绑定地址 |
HTTP 端点为:`POST /mcp` 用于 JSON-RPC 请求,`GET /mcp` 用于 SSE 流,`DELETE /mcp` 用于关闭会话。初始 `initialize` 请求后,所有后续请求都必须包含在 initialize 响应中返回的 `mcp-session-id` 头部。
当绑定到 `127.0.0.1`(默认)时,会自动启用 DNS 重绑定保护。对于远程部署(`0.0.0.0`),请使用服务账号或外部令牌认证,并确保端点位于带有 TLS 的反向代理之后。**没有认证和 TLS,任何能访问该端口的人都能完全访问配置的 Google Drive 账户。**
### MCP 客户端配置(HTTP)
```
{
"mcpServers": {
"google-drive": {
"url": "http://localhost:3100/mcp"
}
}
}
```
## 可用工具
### 搜索和导航
- **search** - 在 Google Drive 中搜索文件
- `query`: 搜索词(或当 `rawQuery=true` 时,原始的 Drive API 查询)
- `pageSize`: 每页结果数(可选,默认 50,最大 100)
- `pageToken`: 下一页的分页令牌(可选)
- `rawQuery`: 将 `query` 直接传递给 Drive API — 支持 `modifiedTime`、`createdTime`、`mimeType`、`name contains` 等运算符(可选)
- **listFolder** - 列出文件夹内容
- `folderId`: 文件夹 ID(可选,默认为根目录)
- `pageSize`: 结果数(可选,最大 100)
- `pageToken`: 分页令牌(可选)
- **listSharedDrives** - 列出可用的 Google 共享云端硬盘
- `pageSize`: 返回的云端硬盘数量(可选,默认 50,最大 100)
- `pageToken`: 分页令牌(可选)
### 文件管理
- **createTextFile** - 创建文本或 Markdown 文件
- `name`: 文件名(必须以 .txt 或 .md 结尾)
- `content`: 文件内容
- `parentFolderId`: 父文件夹 ID(可选)
- **updateTextFile** - 更新现有文本文件
- `fileId`: 要更新的文件 ID
- `content`: 新内容
- `name`: 新名称(可选)
- **deleteItem** - 将文件或文件夹移至回收站(不是永久删除 - 项目可以从 Google Drive 回收站中恢复)
- `itemId`: 要移至回收站的项目 ID
- **renameItem** - 重命名文件或文件夹
- `itemId`: 要重命名的项目 ID
- `newName`: 新名称
- **moveItem** - 移动文件或文件夹
- `itemId`: 要移动的项目 ID
- `destinationFolderId`: 目标文件夹 ID
- **copyFile** - 创建 Google Drive 文件或文档的副本
- `fileId`: 要复制的文件 ID
- `newName`: 副本文件的名称(可选,默认为“[原名称] 的副本”)
- `parentFolderId`: 目标文件夹 ID(可选,默认为同一位置)
#### 共享和权限
- **listPermissions** - 列出文件/文件夹的当前共享权限
- `fileId`: 文件或文件夹 ID
- **addPermission** - 为文件/文件夹添加新权限
- `fileId`: 文件或文件夹 ID
- `type`: 权限目标类型(`user`、`group`、`domain`、`anyone`)
- `role`: 权限角色(`reader`、`commenter`、`writer`、`fileOrganizer`、`organizer`、`owner`)
- `emailAddress`: `user`/`group` 类型时必需
- `domain`: `domain` 类型时必需
- `sendNotificationEmail`: 发送通知邮件(可选)
- **updatePermission** - 更新现有权限的角色
- `fileId`: 文件或文件夹 ID
- `permissionId`: 权限 ID
- `role`: 新角色
- **removePermission** - 移除文件/文件夹的权限
- `fileId`: 文件或文件夹 ID
- `permissionId`: 权限 ID(如果提供了 `emailAddress` 则可选)
- `emailAddress`: 用于查找权限的电子邮件(可选备用)
- **shareFile** - 通过用户电子邮件共享文件(幂等辅助工具)
- `fileId`: 文件或文件夹 ID
- `emailAddress`: 接收者电子邮件
- `role`: 角色(`reader`、`commenter`、`writer`)
- `sendNotificationEmail`: 发送通知邮件(可选)
#### 文件修订版本 (v1.7.0)
- **getRevisions** - 列出文件的修订版本
- `fileId`: 文件 ID
- `pageSize`: 最大返回修订版本数(可选)
- **restoreRevision** - 从选定的修订版本恢复文件(需确认安全)
- `fileId`: 文件 ID
- `revisionId`: 要恢复的修订版本 ID
- `confirm`: 必须为 `true` 才能执行恢复
#### 认证诊断 (v1.7.0)
- **authGetStatus** - 显示令牌/作用域/认证健康状况诊断信息(机器和人类可读)
- **authListScopes** - 显示已配置/请求的作用域、已授予的作用域、缺失的作用域和预设
- **authTestFileAccess** - 测试 Drive 访问(可选地针对特定 `fileId`)
- **uploadFile** - 将本地文件(任何类型:图像、音频、视频、PDF 等)上传到 Google Drive
- `localPath`: 本地文件的绝对路径
- `name`: Drive 中的文件名(可选,默认为本地文件名)
- `parentFolderId`: 父文件夹 ID 或路径(可选,例如 '/Work/Projects')
- `mimeType`: MIME 类型(可选,根据扩展名自动检测)
- `convertToGoogleFormat`: 将上传的文件转换为原生 Google Workspace 格式(可选,默认为 false)。启用时,Office 文件会自动转换:
- `.docx` / `.doc` → Google Doc
- `.xlsx` / `.xls` → Google Sheet
- `.pptx` / `.ppt` → Google Slides
- 文件扩展名会自动从名称中剥离(例如 `report.docx` 变为 `report`)
- **downloadFile** - 将 Google Drive 文件下载到本地路径
- `fileId`: Google Drive 文件 ID
- `localPath`: 保存文件的本地绝对路径(可以是目录或完整文件路径)
- `exportMimeType`: 对于 Google Workspace 文件,导出时的 MIME 类型(可选,例如 'application/pdf'、'text/csv')
- `overwrite`: 是否覆盖现有文件(可选,默认为 false)
#### PDF 导入和转换 (v1.6.0)
- **convertPdfToGoogleDoc** - 将已存储在 Drive 中的 PDF 转换为可编辑的 Google Doc
- `fileId`: 源 PDF 文件 ID
- `newName`: 可选的目标文档名称
- `parentFolderId`: 可选的目标文件夹
- **bulkConvertFolderPdfs** - 转换文件夹中的所有 PDF,并返回每个文件的成功/失败摘要
- `folderId`: 源文件夹 ID
- `maxResults`: 要处理的最大 PDF 数量(可选,默认:100)
- `continueOnError`: 单个失败后继续处理(可选,默认:true)
- **uploadPdfWithSplit** - 上传本地 PDF,可选地在上传前拆分为分块的 PDF 部分
- `localPath`: PDF 的本地绝对路径
- `split`: 启用拆分模式元数据输出(可选,默认为 false)
- `maxPagesPerChunk`: 拆分规划的建议分块大小(可选)
- `parentFolderId`: 可选的目标文件夹
- `namePrefix`: 可选的上传文件名前缀
### 文件夹操作
- **createFolder** - 创建新文件夹
- `name`: 文件夹名称
- `parent`: 父文件夹 ID 或路径(可选)
### Google 文档
#### 创建和更新
- **createGoogleDoc** - 创建 Google Doc
- `name`: 文档名称
- `content`: 文档内容
- `parentFolderId`: 父文件夹 ID(可选)
- **updateGoogleDoc** - 替换 Google Doc 中的所有内容
- `documentId`: 文档 ID
- `content`: 新内容
#### 阅读和发现
- **readGoogleDoc** - 读取 Google Doc 的内容,支持格式选项
- `documentId`: 文档 ID
- `format`: 输出格式 — `text`、`json` 或 `markdown`(可选,默认:text)
- `maxLength`: 返回的最大字符数(可选)
- **readGoogleDocPaginated** - 分页读取大型 Google Doc(避免主机输出大小截断)
- `documentId`: 文档 ID
- `format`: 输出格式 — `text` 或 `markdown`(可选,默认:text)
- `offset`: 输出文本中的字符偏移量(可选,默认:0;传递上一次响应的 `nextOffset`)
- `limit`: 每页最大字符数(可选,默认:50000,最大:80000)
- `tabId`: 按 ID 读取特定标签页(可选)
- **getGoogleDocContent** - 获取文档内容,包含文本索引以进行格式化
- `documentId`: 文档 ID
- `includeFormatting`: 包含每个文本跨度的字体、样式和颜色信息(可选,默认:false)
- **getGoogleDocContentPaginated** - 分页 `getGoogleDocContent`;页面结束处尽可能贴合行边界(单行超过 `limit` 时硬切以确保前进进度)
- `documentId`: 文档 ID
- `includeFormatting`: 包含每个文本跨度的字体、样式和颜色信息(可选,默认:false)
- `offset`: 格式化输出中的字符偏移量(可选,默认:0;传递上一次响应的 `nextOffset`)
- `limit`: 每页最大字符数(可选,默认:50000,最大:80000)
- **listDocumentTabs** - 列出 Google Doc 中的所有标签页及其 ID 和层级结构
- `documentId`: 文档 ID
- `includeContent`: 包含每个标签页的内容摘要(字符数)(可选)
- **addDocumentTab** - 在 Google Doc 中添加新标签页
- `documentId`: 文档 ID
- `title`: 标签页标题
- **renameDocumentTab** - 重命名 Google Doc 中的现有标签页
- `documentId`: 文档 ID
- `tabId`: 标签页 ID
- `title`: 新标签页标题
- **insertSmartChip** - 在文档索引处插入人员智能芯片(提及)。Docs API 仅支持人员芯片;日期和文件芯片为只读。
- `documentId`: 文档 ID
- `index`: 插入索引(从 1 开始)
- `chipType`: `person`(唯一支持的类型)
- `personEmail`: 人员提及的电子邮件地址
- **readSmartChips** - 从文档的默认标签页读取智能芯片类元素(人员提及、富链接、日期芯片)。仅扫描默认标签页;不包含其他标签页。
- `documentId`: 文档 ID
- **createFootnote** - 在 Google Doc 中创建脚注。脚注不能插入到公式、页眉、页脚或其他脚注内部。
- `documentId`: 文档 ID
- `index`: 1-based 字符索引,脚注引用应插入此处(可选 — 提供此参数或 `endOfSegment`)
- `endOfSegment`: 如果为 true,则在文档正文末尾插入脚注(可选 — 提供此参数或 `index`)
- `content`: 脚注正文的可选文本内容
- **listGoogleDocs** - 列出 Google 文档,支持可选过滤
- `query`: 按名称或内容过滤的搜索查询(可选)
- `maxResults`: 最大返回文档数,1-100(可选,默认:20)
- `orderBy`: 排序顺序 — `name`、`modifiedTime` 或 `createdTime`(可选)
- **getDocumentInfo** - 获取特定 Google 文档的详细元数据
- `documentId`: 文档 ID
#### 精确编辑
- **insertText** - 在特定索引处插入文本(不替换整个文档)
- `documentId`: 文档 ID
- `text`: 要插入的文本
- `index`: 插入位置(从 1 开始)
- **deleteRange** - 删除起始和结束索引之间的内容
- `documentId`: 文档 ID
- `startIndex`: 起始索引(从 1 开始,包含)
- `endIndex`: 结束索引(不包含)
#### 文本和段落样式
- **applyTextStyle** - 对范围或找到的文本应用文本格式(粗体、斜体、颜色等)
- `documentId`: 文档 ID
- 目标(使用其一):`startIndex`+`endIndex` 或 `textToFind`+`matchInstance`
- `bold`、`italic`、`underline`、`strikethrough`:文本样式(可选)
- `fontSize`:字号,单位磅(可选)
- `fontFamily`:字体系列名称(可选)
- `foregroundColor`:十六进制颜色,例如 `#FF0000`(可选)
- `backgroundColor`:十六进制背景色(可选)
- `linkUrl`:超链接 URL(可选)
- **applyParagraphStyle** - 应用段落格式
- `documentId`: 文档 ID
- 目标(使用其一):`startIndex`+`endIndex` 或 `textToFind`+`matchInstance` 或 `indexWithinParagraph`
- `namedStyleType`:NORMAL_TEXT, TITLE, SUBTITLE, HEADING_1 至 HEADING_6(可选)
- `alignment`:START, CENTER, END, 或 JUSTIFIED(可选)
- `indentStart`, `indentEnd`:缩进,单位磅(可选)
- `spaceAbove`, `spaceBelow`:间距,单位磅(可选)
- `keepWithNext`:与下一段保持在一起(可选)
- **formatGoogleDocText** - `applyTextStyle` 的别名(兼容性辅助工具)
- 参数与 `applyTextStyle` 相同
- **formatGoogleDocParagraph** - `applyParagraphStyle` 的别名(兼容性辅助工具)
- 参数与 `applyParagraphStyle` 相同
#### 项目符号和列表
- **createParagraphBullets** - 为段落添加或删除项目符号/编号列表
- `documentId`: 文档 ID
- 目标(使用其一):`startIndex`+`endIndex` 或 `textToFind`+`matchInstance`
- `bulletPreset`:项目符号样式预设(可选,默认:`BULLET_DISC_CIRCLE_SQUARE`)。可用预设:
- **项目符号样式**:`BULLET_DISC_CIRCLE_SQUARE`, `BULLET_DIAMONDX_ARROW3D_SQUARE`, `BULLET_CHECKBOX`, `BULLET_ARROW_DIAMOND_DISC`, `BULLET_STAR_CIRCLE_SQUARE`, `BULLET_ARROW3D_CIRCLE_SQUARE`, `BULLET_LEFTTRIANGLE_DIAMOND_DISC`
- **编号样式**:`NUMBERED_DECIMAL_ALPHA_ROMAN`, `NUMBERED_DECIMAL_ALPHA_ROMAN_PARENS`, `NUMBERED_DECIMAL_NESTED`, `NUMBERED_UPPERALPHA_ALPHA_ROMAN`, `NUMBERED_UPPERROMAN_UPPERALPHA_DECIMAL`, `NUMBERED_ZERODECIMAL_ALPHA_ROMAN`
- **删除项目符号**:`NONE` — 从目标段落中移除现有项目符号/编号
- **findAndReplaceInDoc** - 在 Google Doc 中查找和替换文本
- `documentId`: 文档 ID
- `findText`: 要查找的文本
- `replaceText`: 替换文本
- `matchCase`: 区分大小写匹配(可选,默认:false)
- `dryRun`: 仅报告估计匹配数,不修改文档(可选,默认:false)
#### 表格和图像
- **insertTable** - 在给定索引处插入新表格
- `documentId`: 文档 ID
- `rows`: 行数
- `columns`: 列数
- `index`: 插入位置(从 1 开始)
- **editTableCell** - 编辑特定表格单元格的内容和/或样式
- `documentId`: 文档 ID
- `tableStartIndex`: 表格元素的起始索引
- `rowIndex`: 行索引(从 0 开始)
- `columnIndex`: 列索引(从 0 开始)
- `textContent`: 新文本内容(可选)
- `bold`、`italic`、`fontSize`、`alignment`:单元格样式(可选)
- **insertImageFromUrl** - 从可公开访问的 URL 插入内联图像Id`: 文档 ID
- `imageUrl`: 图像的可公开访问 URL
- `index`: 插入位置(从 1 开始)
- `width`、`height`:图像尺寸,单位磅(可选)
- **insertLocalImage** - 将本地图像文件上传到 Drive 并插入到文档中
- `documentId`: 文档 ID
- `localImagePath`: 本地图像文件的绝对路径
- `index`: 插入位置(从 1 开始)
- `width`、`height`:图像尺寸,单位磅(可选)
- `uploadToSameFolder`:上传到与文档相同的文件夹(可选,默认:true)
#### 批注
- **listComments** - 列出 Google 文档中的所有批注,包含位置上下文、字符偏移量和完整的回复链
- `documentId`: 文档 ID
- `includeDeleted`: 包含已删除的批注(可选,默认:false)
- `pageSize`: 最大返回批注数,1-100(可选,默认:100)
- `pageToken`: 下一页结果的令牌(可选)
- 使用分层方法(Docs API 文本匹配,DOCX 导出作为模糊匹配的备用)为每个批注返回周围上下文和 Docs API 字符偏移量
- **getComment** - 获取特定批注及其完整的回复线程
- `documentId`: 文档 ID
- `commentId`: 批注 ID
- **addComment** - 添加锚定到特定文本范围的批注
- `documentId`: 文档 ID
- `startIndex`: 起始索引(从 1 开始)
- `endIndex`: 结束索引(不包含)
- `commentText`: 批注内容
- **replyToComment** - 为现有批注添加回复
- `documentId`: 文档 ID
- `commentId`: 要回复的批注 ID
- `replyText`: 回复内容
- `resolve`: 设为 `true` 以在回复后解决批注线程(可选,默认:false)
- **deleteComment** - 从文档中删除批注
- `documentId`: 文档 ID
- `commentId`: 要删除的批注 ID
### Google 表格
#### 创建和更新
- **createGoogleSheet** - 创建 Google Sheet
- `name`: 电子表格名称
- `data`: 单元格值的二维数组
- `parentFolderId`: 父文件夹 ID(可选)
- `valueInputOption`:`RAW`(默认,安全)或 `USER_ENTERED`(计算公式)(可选)
- **updateGoogleSheet** - 更新 Google Sheet
- `spreadsheetId`: 电子表格 ID
- `range`: 要更新的范围(例如 'Sheet1!A1:C10')
- `data`: 新值的二维数组
- `valueInputOption`:`RAW`(默认,安全)或 `USER_ENTERED`(计算公式)(可选)
- **getGoogleSheetContent** - 获取电子表格内容,包含单元格信息
- `spreadsheetId`: 电子表格 ID
- `range`: 要获取的范围(例如 'Sheet1!A1:C10')
#### 工作表管理
- **getSpreadsheetInfo** - 获取电子表格的详细信息,包括所有工作表/标签页
- `spreadsheetId`: 电子表格 ID
- **appendSpreadsheetRows** - 在工作表末尾追加行
- `spreadsheetId`: 电子表格 ID
- `range`: 指示追加位置的 A1 表示法范围(例如 'A1' 或 'Sheet1!A1')
- `values`: 要追加的值的二维数组
- `valueInputOption`:`RAW` 或 `USER_ENTERED`(可选,默认:USER_ENTERED)
- **addSpreadsheetSheet** - 向现有电子表格添加新工作表/标签页
- **addSheet** - `addSpreadsheetSheet` 的别名
- `spreadsheetId`: 电子表格 ID
- `sheetTitle`: 新工作表的标题
- **listSheets** - 列出电子表格中的标签页/工作表
- `spreadsheetId`: 电子表格 ID
- **renameSheet** - 通过 `sheetId` 重命名工作表/标签页
- `spreadsheetId`: 电子表格 ID
- `sheetId`: 工作表 ID
- `newTitle`: 新标题
- **deleteSheet** - 通过 `sheetId` 删除工作表/标签页
- `spreadsheetId`: 电子表格 ID
- `sheetId`: 工作表 ID
- **addDataValidation** - 为范围添加数据验证规则
- `spreadsheetId`: 电子表格 ID
- `range`: A1 范围(例如 `Sheet1!A1:A10`)
- `conditionType`:`ONE_OF_LIST`、`NUMBER_GREATER`、`NUMBER_LESS` 或 `TEXT_CONTAINS`
- `values`:条件值(例如列表项、阈值)
- `strict`:拒绝无效值(可选,默认:`true`)
- `showCustomUi`:显示下拉菜单/自定义 UI(可选,默认:`true`)
- **protectRange** - 保护电子表格中的范围
- `spreadsheetId`: 电子表格 ID
- `range`: A1 范围
- `description`: 保护描述(可选)
- `warningOnly`: 仅警告而不强制执行(可选,默认:`false`)
- **addNamedRange** - 创建命名范围
- `spreadsheetId`: 电子表格 ID
- `name`: 命名范围名称
- `range`: A1 范围
- **listGoogleSheets** - 列出 Google 电子表格,支持可选过滤
- `query`: 按名称或内容过滤的搜索查询(可选)
- `maxResults`: 最大返回电子表格数,1-100(可选,默认:20)
- `orderBy`: 排序顺序 — `name`、`modifiedTime` 或 `createdTime`(可选)
#### 格式设置
- **formatGoogleSheetCells** - 格式化单元格属性
- `spreadsheetId`: 电子表格 ID
- `range`: 要格式化的范围(例如 'A1:C10')
- `backgroundColor`: 单元格背景色(RGB 0-1)(可选)
- `horizontalAlignment`: LEFT、CENTER 或 RIGHT(可选)
- `verticalAlignment`: TOP、MIDDLE 或 BOTTOM(可选)
- `wrapStrategy`: OVERFLOW_CELL、CLIP 或 WRAP(可选)
- **formatGoogleSheetText** - 为单元格应用文本格式
- `spreadsheetId`: 电子表格 ID
- `range`: 要格式化的范围(例如 'A1:C10')
- `bold`、`italic`、`strikethrough`、`underline`:文本样式(可选)
- `fontSize`:字号,单位磅(可选)
- `fontFamily`:字体名称(可选)
- `foregroundColor`:文本颜色(RGB 0-1)(可选)
- **formatGoogleSheetNumbers** - 应用数字/日期格式
- `spreadsheetId`: 电子表格 ID
- `range`: 要格式化的范围(例如 'A1:C10')
- `pattern`: 格式模式(例如 '#,##0.00', 'yyyy-mm-dd', '$#,##0.00', '0.00%')
- `type`: NUMBER、CURRENCY、PERCENT、DATE、TIME、DATE_TIME 或 SCIENTIFIC(可选)
- **setGoogleSheetBorders** - 配置单元格边框
- `spreadsheetId`: 电子表格 ID
- `range`: 要格式化的范围(例如 'A1:C10')
- `style`: SOLID、DASHED、DOTTED 或 DOUBLE
- `width`: 边框粗细 1-3(可选)
- `color`: 边框颜色(RGB 0-1)(可选)
- `top`、`bottom`、`left`、`right`:应用于特定边框(可选)
- `innerHorizontal`、`innerVertical`:应用于内部边框(可选)
- **mergeGoogleSheetCells** - 合并范围内的单元格
- `spreadsheetId`: 电子表格 ID
- `range`: 要合并的范围(例如 'A1:C3')
- `mergeType`: MERGE_ALL、MERGE_COLUMNS 或 MERGE_ROWS
- **addGoogleSheetConditionalFormat** - 添加条件格式规则
- `spreadsheetId`: 电子表格 ID
- `range`: 应用格式的范围(例如 'A1:C10')
- `condition`: 条件配置
- `type`: NUMBER_GREATER、NUMBER_LESS、TEXT_CONTAINS、TEXT_STARTS_WITH、TEXT_ENDS_WITH 或 CUSTOM_FORMULA
- `value`: 要比较的值或公式
- `format`: 条件为 true 时应用的格式
- `backgroundColor`: 单元格颜色(RGB 0-1)(可选)
- `textFormat`: 包含粗体和前景色的文本格式(可选)
### Google 幻灯片
#### 创建和更新
- **createGoogleSlides** - 创建演示文稿
- `name`: 演示文稿名称
- `slides`: 带有标题和内容的幻灯片数组
- `parentFolderId`: 父文件夹 ID(可选)
- **updateGoogleSlides** - 更新现有演示文稿
- `presentationId`: 演示文稿 ID
- `slides`: 带有标题和内容的幻灯片数组(替换所有现有幻灯片)
#### 内容和格式
- **getGoogleSlidesContent** - 获取演示文稿内容,包含元素 ID
- `presentationId`: 演示文稿 ID
- `slideIndex`: 特定幻灯片索引(可选)
- **formatGoogleSlidesText** - 为幻灯片元素应用文本格式
- `presentationId`: 演示文稿 ID
- `objectId`: 元素 ID
- `startIndex`/`endIndex`: 文本范围(可选,从 0 开始)
- `bold`、`italic`、`underline`、`strikethrough`:文本样式(可选)
- `fontSize`:字号,单位磅(可选)
- `fontFamily`:字体名称(可选)
- `foregroundColor`:文本颜色(RGB 0-1)(可选)
- **formatGoogleSlidesParagraph** - 应用段落格式
- `presentationId`: 演示文稿 ID
- `objectId`: 元素 ID
- `alignment`: START、CENTER、END 或 JUSTIFIED(可选)
- `lineSpacing`: 行距倍数(可选)
- `bulletStyle`: NONE、DISC、ARROW、SQUARE、DIAMOND、STAR 或 NUMBERED(可选)
- **styleGoogleSlidesShape** - 设置形状和元素的样式
- `presentationId`: 演示文稿 ID
- `objectId`: 形状 ID
- `backgroundColor`: 填充颜色(RGBA 0-1)(可选)
- `outlineColor`: 边框颜色(RGB 0-1)(可选)
- `outlineWeight`: 边框粗细,单位磅(可选)
- `outlineDashStyle`: SOLID、DOT、DASH、DASH_DOT、LONG_DASH 或 LONG_DASH_DOT(可选)
- **setGoogleSlidesBackground** - 设置幻灯片背景色
- `presentationId`: 演示文稿 ID
- `pageObjectIds`: 幻灯片 ID 数组
- `backgroundColor`: 背景色(RGBA 0-1)
- **createGoogleSlidesTextBox** - 创建格式化的文本框
- `presentationId`: 演示文稿 ID
- `pageObjectId`: 幻灯片 ID
- `text`: 文本内容
- `x`、`y`、`width`、`height`:位置/尺寸,单位 EMU(1/360000 厘米)
- `fontSize`、`bold`、`italic`:文本格式(可选)
- **createGoogleSlidesShape** - 创建样式化的形状
- `presentationId`: 演示文稿 ID
- `pageObjectId`: 幻灯片 ID
- `shapeType`: RECTANGLE、ELLIPSE、DIAMOND、TRIANGLE、STAR、ROUND_RECTANGLE 或 ARROW
- `x`、`y`、`width`、`height`:位置/尺寸,单位 EMU
- `backgroundColor`: 填充颜色(RGBA 0-1)(可选)
#### 演讲者备注
- **getGoogleSlidesSpeakerNotes** - 获取幻灯片的演讲者备注
- `presentationId`: 演示文稿 ID
- `slideIndex`: 幻灯片索引(从 0 开始)
- **updateGoogleSlidesSpeakerNotes** - 更新或设置幻灯片的演讲者备注
- `presentationId`: 演示文稿 ID
- `slideIndex`: 幻灯片索引(从 0 开始)
- `notes`: 要设置的演讲者备注内容
#### 幻灯片操作和模板
- **deleteGoogleSlide** - 通过对象 ID 删除幻灯片
- `presentationId`: 演示文稿 ID
- `slideObjectId`: 幻灯片对象 ID
- **duplicateSlide** - 通过对象 ID 复制幻灯片
- `presentationId`: 演示文稿 ID
- `slideObjectId`: 幻灯片对象 ID
- **reorderSlides** - 通过对象 ID 和插入索引重新排序幻灯片
- `presentationId`: 演示文稿 ID
- `slideObjectIds`: 要移动的幻灯片对象 ID 数组
- `insertionIndex`: 目标插入索引
- **replaceAllTextInSlides** - 在整个演示文稿中替换文本
- `presentationId`: 演示文稿 ID
- `containsText`: 要查找的文本
- `replaceText`: 替换文本
- `matchCase`: 区分大小写(可选,默认:`false`)
- **exportSlideThumbnail** - 导出幻灯片缩略图 URL(PNG/JPEG, SMALL/MEDIUM/LARGE)
- `presentationId`: 演示文稿 ID
- `slideObjectId`: 幻灯片对象 ID
- `mimeType`:`PNG` 或 `JPEG`(可选,默认:`PNG`)
- `size`:`SMALL`、`MEDIUM` 或 `LARGE`(可选,默认:`LARGE`)
### Google 日历
- **listCalendars** - 列出所有可访问的 Google 日历
- `showHidden`: 包含隐藏日历(可选,默认:false)
- **getCalendarEvents** - 从日历获取事件,支持可选过滤
- `calendarId`: 日历 ID(可选,默认:primary)
- `timeMin`: 时间范围开始,RFC3339(可选,例如 '2024-01-01T00:00:00Z')
- `timeMax`: 时间范围结束,RFC3339(可选)
- `query`: 事件中的自由文本搜索(可选)
- `maxResults`: 最大返回事件数,1-250(可选,默认:50)
- `singleEvents`: 将重复事件展开为实例(可选,默认:true)
- `orderBy`: 排序顺序 — `startTime` 或 `updated`(可选,默认:startTime)
- **getCalendarEvent** - 通过 ID 获取单个日历事件
- `eventId`: 事件 ID
- `calendarId`: 日历 ID(可选,默认:primary)
- 响应包含事件的文件 `attachments`(标题和 URL),如果存在的话
- **createCalendarEvent** - 创建新的日历事件,支持 Google Meet
- `summary`: 事件标题
- `start`: 开始时间(带时间的事件用 `dateTime`,全天事件用 `date`,可选 `timeZone`)
- `end`: 结束时间(格式同 start)
- `calendarId`: 日历 ID(可选,默认:primary)
- `description`: 事件描述(可选)
- `location`: 事件地点(可选)
- `attendees`: 电子邮件地址数组(可选)
- `sendUpdates`:`all`、`externalOnly` 或 `none`(可选,默认:none)
- `conferenceType`:`hangoutsMeet` 以添加 Google Meet 链接(可选)
- `recurrence`: 重复事件的 RRULE 字符串数组(可选)
- `visibility`:`default`、`public`、`private` 或 `confidential`(可选)
- `attachments`: `{ fileUrl, title?, mimeType? }` 数组(可选,最多 25 个;对于 Drive 文件,使用文件的共享 URL 作为 `fileUrl`)
- **updateCalendarEvent** - 更新现有日历事件
- `eventId`: 事件 ID
- `calendarId`: 日历 ID(可选,默认:primary)
- `summary`、`description`、`location`:更新的字段(可选)
- `start`、`end`:更新的时间(可选)
- `attendees`: 更新的参与者电子邮件,替换现有(可选)
- `attachments`:`{ fileUrl, title?, mimeType? }` 数组,替换现有(可选,最多 25 个);省略以保留当前附件,或传递 `[]` 以删除所有
- `sendUpdates`:`all`、`externalOnly` 或 `none`(可选,默认:none)
- **deleteCalendarEvent** - 删除日历事件
- `eventId`: 事件 ID
- `calendarId`: 日历 ID(可选,默认:primary)
- `sendUpdates`: 发送取消通知(可选,默认:none)
## 外部认证
对于托管、容器化或 CI/CD 部署(无法进行基于浏览器的 OAuth 流程),服务器支持两种替代认证模式。它们在回退到默认本地 OAuth 流程之前按优先级顺序检查。
### 1. 服务账号模式
设置标准的 `GOOGLE_APPLICATION_CREDENTIALS` 环境变量,指向服务账号 JSON 密钥文件。最适合服务器到服务器、CI/CD 和容器部署。
```
{
"mcpServers": {
"google-drive": {
"command": "npx",
"args": ["@piotr-agier/google-drive-mcp"],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/service-account-key.json"
}
}
}
}
```
**注意:** 服务账号必须有权访问你要使用的 Google Drive 文件/文件夹。对于共享云端硬盘,授予服务账号的电子邮件地址适当的权限。
#### 域范围委托(模拟用户)
默认情况下,服务账号代表其自身。某些 Google API(例如限定到用户“我的云端硬盘”的 Drive 读取,或针对个人日历的日历 ACL 写入)需要代表真实的 Workspace 用户。设置 `GOOGLE_DRIVE_MCP_SUBJECT` 为要模拟的用户电子邮件:
```
{
"mcpServers": {
"google-drive": {
"command": "npx",
"args": ["@piotr-agier/google-drive-mcp"],
"env": {
"GOOGLE_APPLICATION_CREDENTIALS": "/path/to/service-account-key.json",
"GOOGLE_DRIVE_MCP_SUBJECT": "user@your-domain.com"
}
}
}
}
```
**前提条件:** Workspace 管理员必须在 **管理控制台 > 安全性 > API 控件 > 管理域范围委托** 下授权服务账号的客户端 ID 用于请求的作用域。那里授予的作用域必须覆盖服务器请求的作用域(参见 [OAuth 作用域配置](#oauth-scope-configuration))。
`GOOGLE_DRIVE_MCP_SCOPES` 在服务账号模式下也适用,因此你可以将 JWT 限制为已委托作用域的子集。
### 2. 外部 OAuth 令牌模式
通过 `GOOGLE_DRIVE_MCP_ACCESS_TOKEN` 提供预先获取的 OAuth 访问令牌。当外部服务处理 OAuth 流程时,这很有用(例如,代表用户获取令牌的 Web 应用)。
**仅访问令牌**(无自动刷新 — 令牌最终会过期):
```
{
"mcpServers": {
"google-drive": {
"command": "npx",
"args": ["@piotr-agier/google-drive-mcp"],
"env": {
"GOOGLE_DRIVE_MCP_ACCESS_TOKEN": "ya29.a0AfH6SM..."
}
}
}
}
```
**带刷新令牌**(推荐 — 启用自动令牌刷新):
```
{
"mcpServers": {
"google-drive": {
"command": "npx",
"args": ["@piotr-agier/google-drive-mcp"],
"env": {
"GOOGLE_DRIVE_MCP_ACCESS_TOKEN": "ya29.a0AfH6SM...",
"GOOGLE_DRIVE_MCP_REFRESH_TOKEN": "1//0dx...",
"GOOGLE_DRIVE_MCP_CLIENT_ID": "123456789.apps.googleusercontent.com",
"GOOGLE_DRIVE_MCP_CLIENT_SECRET": "GOCSPX-..."
}
}
}
}
```
| 变量 | 必需 | 描述 |
|---|---|---|
| `GOOGLE_DRIVE_MCP_ACCESS_TOKEN` | 是(激活模式) | Google OAuth 访问令牌 |
| `GOOGLE_DRIVE_MCP_REFRESH_TOKEN` | 否 | 用于自动刷新的刷新令牌 |
| `GOOGLE_DRIVE_MCP_CLIENT_ID` | 与刷新令牌一起时必需 | OAuth 客户端 ID |
| `GOOGLE_DRIVE_MCP_CLIENT_SECRET` | 与刷新令牌一起时必需 | OAuth 客户端密钥 |
### 3. 本地 OAuth 流程(默认)
如果上述两种模式均未配置,服务器使用现有的基于浏览器的 OAuth 流程。详情见下文。
## 认证流程
服务器使用 OAuth 2.0 进行安全认证:
### 自动认证(首次运行)
1. 服务器检测到缺少令牌并启动本地认证服务器
2. 你的浏览器打开 Google 的同意页面
3. 授予请求的权限
4. 令牌安全保存到 `~/.config/google-drive-mcp/tokens.json`
5. 服务器继续启动
### 令牌管理
- **自动刷新**:令牌在过期前自动刷新
- **安全存储**:令牌以 0600 权限存储
- **迁移**:旧版令牌自动迁移到安全位置
### 手动重新认证
在以下情况下运行认证命令:
- 切换 Google 账户
- 刷新过期令牌(处于“测试”状态的应用,Google 会在 7 天后使刷新令牌过期)
- 从被撤销的访问中恢复
```
# 使用 npx
npx @piotr-agier/google-drive-mcp auth
# 使用本地安装
npm run auth
```
## 安全性
### 安全特性
- **无客户端密钥**:桌面 OAuth 流程仅需客户端 ID 即可工作
- **安全令牌存储**:令牌以 0600 权限存储在符合 XDG 规范的位置
- **范围访问**:请求最小权限(drive.file、documents、spreadsheets、presentations、calendar)
- **本地执行**:所有处理都在你的机器上进行
- **自动令牌刷新**:减少重新认证的需求
- **令牌迁移**:旧版令牌自动移动到安全位置
### 最佳实践
1. **切勿提交凭据**:添加到 `.gitignore`:
gcp-oauth.keys.json
client_secret*.json
.config/
2. **使用环境变量**进行生产部署:
export GOOGLE_DRIVE_OAUTH_CREDENTIALS="/secure/path/credentials.json"
export GOOGLE_DRIVE_MCP_TOKEN_PATH="/secure/path/tokens.json"
3. **监控访问**:
- 检查 Google Drive 中的近期活动
- 定期审查 OAuth 应用权限
### 撤销 OAuth 访问
如果你需要撤销 Google Drive MCP 对你 Google 账户的访问权限:
1. 访问 [Google 账户权限](https://myaccount.google.com/permissions)
2. 在列表中找到“Google Drive MCP”或你的自定义应用名称
3. 点击它并选择“移除访问权限”
4. 清除本地令牌以完成撤销:
rm ~/.config/google-drive-mcp/tokens.json
撤销访问权限后,下次使用服务器时需要重新认证。
## 故障排除
### 常见问题及解决方案
#### “未找到 OAuth 凭据”
```
OAuth credentials not found. Please provide credentials using one of these methods:
1. Config directory (recommended):
Place your gcp-oauth.keys.json file in: ~/.config/google-drive-mcp/
2. Environment variable:
export GOOGLE_DRIVE_OAUTH_CREDENTIALS="/path/to/gcp-oauth.keys.json"
```
**解决方案:**
- 从 Google Cloud Console 下载凭据
- 将文件放在 `~/.config/google-drive-mcp/gcp-oauth.keys.json`(推荐),或设置环境变量
- 确保文件具有适当的读取权限
#### “认证失败”或浏览器未打开
**可能原因:**
1. **凭据类型错误**:必须是“桌面应用”,而不是“Web 应用”
2. **端口被阻止**:端口 3000-3004 必须可用(如果设置了 `GOOGLE_DRIVE_MCP_AUTH_PORT`,则为自定义范围)
3. **未添加测试用户**:在 OAuth 同意屏幕中添加你的电子邮件
4. **`redirect_uri_mismatch`(仅限 Web 应用客户端)**:回调重定向 URI 使用环回 IP `http://127.0.0.1:/oauth2callback`。切换到“桌面应用”客户端(推荐),或将 `http://127.0.0.1:3000/oauth2callback` … `http://127.0.0.1:3004/oauth2callback`(加上任何自定义的 `GOOGLE_DRIVE_MCP_AUTH_PORT` 范围)添加为授权的重定向 URI
**解决方案:**
```
# 检查端口是否被占用
lsof -i :3000-3004
# 方案一:如需终止进程
kill -9
# 方案二:使用不同的端口范围
export GOOGLE_DRIVE_MCP_AUTH_PORT=3100
# 重新运行身份验证
npx @piotr-agier/google-drive-mcp auth
```
#### “令牌已过期”或“授权无效”
**对于处于“测试”状态的 Google OAuth 应用:**
- Google 会在 7 天后自动使刷新令牌过期
- 在发布应用之前,你需要每周重新认证一次
**解决方案:**
```
# 清除旧令牌并重新验证身份
rm ~/.config/google-drive-mcp/tokens.json
npx @piotr-agier/google-drive-mcp auth
```
**对于生产环境:**
- 在 Google Cloud Console 中将应用移至“已发布”状态
- 完成 OAuth 验证流程
#### 即使令牌有效也出现“需要登录”错误
**如果你更新了 OAuth 作用域但仍然收到错误:**
- 即使移除了本地令牌,Google 也会缓存应用授权
- 应用可能使用的是旧的/有限的作用域
**解决方案:**
1. 前往 [Google 账户权限](https://myaccount.google.com/permissions)
2. 找到并移除“Google Drive MCP”的访问权限
3. 清除本地令牌:`rm ~/.config/google-drive-mcp/tokens.json`
4. 重新认证以授予所有必需的作用域
5. 验证同意屏幕显示所有作用域,包括完全 Drive 访问权限
#### “API 未启用”错误
```
Error: Google Sheets API has not been used in project...
```
**解决方案:**
1. 前往 [Google Cloud Console](https://console.cloud.google.com)
2. 选择你的项目
3. 导航到“API 和服务” > “程序库”
4. 搜索并启用缺失的 API
5. 等待 1-2 分钟以传播
#### “权限不足”
**检查凭据中的作用域:**
- 需要 drive.file 或 drive 作用域
- 需要 docs、sheets、slides 作用域用于相应的服务
**解决方案:**
- 使用正确的作用域重新创建 OAuth 凭据
- 更新凭据后重新认证
#### 速率限制(429 错误)
**Google API 配额:**
- Drive API:每分钟 12,000 个请求
- Docs/Sheets/Slides:每分钟 300 个请求
**解决方案:**
- 实施指数退避
- 尽可能批量操作
- 在 Google Cloud Console 中检查配额使用情况
### Docker 特定问题
#### Docker 中的“需要认证”
**问题:** Docker 中的 MCP 服务器显示认证错误,即使你拥有有效的令牌。
**原因:** OAuth 流程需要浏览器访问,这在 Docker 容器中不可用。
**解决方案:**
```
# 1. 先在 Docker 外进行身份验证
npx @piotr-agier/google-drive-mcp auth
# 2. 验证令牌是否存在
ls -la ~/.config/google-drive-mcp/tokens.json
# 3. 重新构建镜像并重启客户端
docker build -t google-drive-mcp .
# 客户端将调用 scripts/docker-mcp.sh 脚本,该脚本会自动替换过期的容器
```
#### Docker 构建期间“npm ci 失败”
**问题:** Docker 构建失败,出现 `tsc: not found` 或类似错误。
**解决方案:**
```
# 首先在本地构建项目
npm install
npm run build
# 然后构建 Docker 镜像
docker build -t google-drive-mcp .
```
Dockerfile 预期本地构建生成的 `dist/` 目录存在。
#### Docker 中的“令牌刷新失败”
**问题:** 令牌无法在容器内刷新。
**解决方案:** 确保以写权限挂载令牌文件:
```
# 正确:可以更新令牌
-v "$HOME/.config/google-drive-mcp/tokens.json":/config/tokens.json
# 错误:只读挂载阻止了令牌刷新
-v "$HOME/.config/google-drive-mcp/tokens.json":/config/tokens.json:ro
```
### 调试模式
启用详细日志记录:
```
# 设置调试环境变量
export DEBUG=google-drive-mcp:*
npx @piotr-agier/google-drive-mcp
```
### 获取帮助
1. **检查日志**:服务器将错误记录到 stderr
2. **验证设置**:运行 `npx @piotr-agier/google-drive-mcp help`
3. **测试认证**:运行 `npx @piotr-agier/google-drive-mcp auth`
4. **报告问题**:[GitHub Issues](https://github.com/piotr-agier/google-drive-mcp/issues)
## 开发
### 项目结构
```
google-drive-mcp/
├── src/ # Source code
│ ├── index.ts # Main server implementation
│ ├── auth.ts # Main authentication module
│ ├── auth/ # Authentication components
│ │ ├── client.ts # OAuth2 client setup
│ │ ├── externalAuth.ts # Service account & external token auth
│ │ ├── server.ts # Local auth server
│ │ ├── tokenManager.ts # Token storage and validation
│ │ └── utils.ts # Auth utilities
│ ├── tools/ # Tool implementations by service
│ │ ├── drive.ts # File management tools
│ │ ├── docs.ts # Google Docs tools
│ │ ├── sheets.ts # Google Sheets tools
│ │ ├── slides.ts # Google Slides tools
│ │ └── calendar.ts # Google Calendar tools
│ ├── utils.ts # Shared utility functions
│ ├── types.ts # TypeScript type definitions
│ └── download-file.ts # File download helper
├── dist/ # Compiled JavaScript (generated)
├── scripts/ # Build scripts
│ └── build.js # Custom build script
├── gcp-oauth.keys.json # OAuth credentials (create from example)
├── gcp-oauth.keys.example.json # Example credentials file
├── package.json # NPM package configuration
├── tsconfig.json # TypeScript configuration
├── LICENSE # MIT license
└── README.md # This file
```
### 构建
```
npm run build # Compile TypeScript
npm run watch # Compile and watch for changes
npm run typecheck # Type checking without compilation
```
### 脚本
- `npm start` - 启动编译后的服务器
- `npm run auth` - 运行认证流程
- `npm run build` - 构建项目(运行类型检查 + 自定义构建脚本)
- `npm run watch` - 构建并监视更改
- `npm run typecheck` - 仅运行 TypeScript 类型检查
- `npm run lint` - 运行 TypeScript 类型检查(typecheck 的别名)
- `npm run prepare` - 在 npm 发布前自动运行 build
- `npm test` - 运行单元测试
## 高级配置
### 环境变量
#### 用户配置变量
**凭据**(必需 - 使用以下方法之一):
| 变量 | 描述 | 示例 |
|------|------|------|
| `GOOGLE_DRIVE_OAUTH_CREDENTIALS` | OAuth 凭据 JSON 文件的路径 | `/home/user/secrets/oauth.json` |
| *(或将文件放在)* | 配置目录(推荐):`~/.config/google-drive-mcp/gcp-oauth.keys.json` | `~/.config/google-drive-mcp/gcp-oauth.keys.json` |
| *(或将文件放在)* | 项目根目录(旧版备用):`gcp-oauth.keys.json` | `./gcp-oauth.keys.json` |
**可选**(用于自定义):
| 变量 | 描述 | 默认值 | 示例 |
|------|------|--------|------|
| `GOOGLE_DRIVE_MCP_TOKEN_PATH` | 覆盖令牌存储位置 | `~/.config/google-drive-mcp/tokens.json` | `/custom/path/tokens.json` |
| `GOOGLE_DRIVE_MCP_AUTH_PORT` | OAuth 回调服务器的起始端口(使用 5 个连续端口) | `3000` | `3100` |
| `GOOGLE_DRIVE_MCP_DISABLE_RESOURCES` | 禁用 MCP 资源协议(`gdrive:///` 列出/读取);工具仍可用。适用于仅工具客户端或挂起枚举大型 Drive 的客户端(例如 Gemini CLI)。接受 `1/0`、`true/false`、`yes/no`、`on/off`。也可作为 `--no-resources[=]` 标志使用(`--no-resources=false` 重新启用,覆盖真值环境变量) | (已启用) | `1` |
| `DEBUG` | 启用调试日志记录 | (已禁用) | `google-drive-mcp:*` |
**外部认证**(本地 OAuth 流程的替代方案):
| 变量 | 描述 | 示例 |
|------|------|------|
| `GOOGLE_APPLICATION_CREDENTIALS` | 服务账号 JSON 密钥文件的路径 | `/path/to/service-account.json` |
| `GOOGLE_DRIVE_MCP_SUBJECT` | 通过域范围委托模拟的 Workspace 用户(可选,服务账号模式) | `user@your-domain.com` |
| `GOOGLE_DRIVE_MCP_ACCESS_TOKEN` | 预先获取的 OAuth 访问令牌 | `ya29.a0AfH6SM...` |
| `GOOGLE_DRIVE_MCP_REFRESH_TOKEN` | 用于自动刷新的刷新令牌(可选) | `1//0dx...` |
| `GOOGLE_DRIVE_MCP_CLIENT_ID` | OAuth 客户端 ID(与刷新令牌一起时必需) | `123456789.apps.googleusercontent.com` |
| `GOOGLE_DRIVE_MCP_CLIENT_SECRET` | OAuth 客户端密钥(与刷新令牌一起时必需) | `GOCSPX-...` |
#### 系统变量(如果存在则由代码库使用)
这些是应用程序读取的标准系统环境变量,但通常不需要设置:
| 变量 | 描述 | 用途 |
|------|------|------|
| `XDG_CONFIG_HOME` | Linux/Unix 配置目录标准 | 确定默认令牌存储位置 |
| `NODE_ENV` | Node.js 环境模式 | 可能影响错误处理和日志记录 |
#### 已弃用变量(请勿使用)
| 变量 | 描述 |
|------|------|
| `GOOGLE_TOKEN_PATH` | 旧版令牌路径 - 请改用 `GOOGLE_DRIVE_MCP_TOKEN_PATH` |
| `GOOGLE_CLIENT_SECRET_PATH` | 旧版凭据路径 - 请改用 `GOOGLE_DRIVE_OAUTH_CREDENTIALS` |
## 许可证
MIT - 详情见 LICENSE 文件
## 贡献
欢迎贡献!请:
1. Fork 仓库
2. 创建特性分支 (`git checkout -b feature/amazing-feature`)
3. 提交你的更改 (`git commit -m 'Add amazing feature'`)
4. 推送到分支 (`git push origin feature/amazing-feature`)
5. 开启拉取请求
## 支持
- 📚 [文档](https://github.com/piotr-agier/google-drive-mcp)
- 🐛 [问题跟踪器](
标签:Claude Desktop集成, Google Drive API, MCP协议, MITM代理, OAuth 2.0认证, 云存储, 共享驱动器, 办公协作, 在线办公, 文件同步, 文件夹导航, 文件操作, 文档管理, 文档编辑, 日历事件管理, 日历管理, 标准化接口, 演示文稿管理, 自动化攻击, 表格处理, 请求拦截