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认证, 云存储, 共享驱动器, 办公协作, 在线办公, 文件同步, 文件夹导航, 文件操作, 文档管理, 文档编辑, 日历事件管理, 日历管理, 标准化接口, 演示文稿管理, 自动化攻击, 表格处理, 请求拦截